I have a knockout app and within it I have a function which shows/hides elements on the page depending on the selected option. The button that has been selected to activate a particular toggle will have an 'active' class so that it 'stands out' from the others and is clearly visible that that's the selected option. My problem is that I've created a knockout function to toggle the active class but it's triggering the active state on all of the buttons rather than the selected button and I'm not sure why?
var viewModel = function(){
var self = this;
self.isActive = ko.observable(false);
self.toggleActive = function(data, event){
self.isActive(!self.isActive()); //toggle the isActive value between true/false
}
}
<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
Fiddle: http://jsfiddle.net/amMup/5/
You only have one viewmodel for all three buttons. That means you only have a single "isActive" flag that all buttons are bound to.
Instead, use an array of items and a foreach loop to render each one. Here's a tweaked version of your view model:
var viewModel = function(){
var self = this;
self.items = [
{ isActive: ko.observable(false) },
{ isActive: ko.observable(false) },
{ isActive: ko.observable(false) }
];
self.toggleActive = function(data, event){
data.isActive(!data.isActive());//toggle the isActive value between true/false
}
}
var myModel = new viewModel();
ko.applyBindings(myModel);
And the HTML is simplified:
<div data-bind="foreach: items">
<button data-bind="click: $parent.toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
</div>
Note the use of $parent
to access the parent's binding context . When you're inside a foreach loop, the binding context is the individual item pulled from the foreach loop. By accessing $parent
you "reach up" to the object that contains the items
property -- which, in your case, is the viewmodel where the toggleActive
exists.
Here's an updated fiddle: http://jsfiddle.net/psteele/amMup/6/
This is because you have them all bound to the same observable.
http://jsfiddle.net/Kohan/fdzqJ/
var viewModel = function(){
var self = this;
self.isActive1 = ko.observable(false);
self.isActive2 = ko.observable(false);
self.isActive3 = ko.observable(false);
self.toggleActive = function(data){
data(!data());
}
}
var myModel = new viewModel();
ko.applyBindings(myModel);
<button data-bind="click: function(){toggleActive(isActive1)}, css : {'activeStyle' : isActive1}">Toggle Active</button>
<button data-bind="click: function(){toggleActive(isActive2)}, css : {'activeStyle' : isActive2}">Toggle Active</button>
<button data-bind="click: function(){toggleActive(isActive3)}, css : {'activeStyle' : isActive3}">Toggle Active</button>
Another way:
<button data-bind="click: function(){setActive('1')}, css: buttonActive() == '1' ? 'active' : '' ">Toggle Active</button>
var viewModel = function(){
var self = this;
self.buttonActive = ko.observable(false);
self.buttonActive = function(index){
self.buttonActive(index);
}
}
var myModel = new viewModel();
ko.applyBindings(myModel);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.