I have a computed
observableArray
called selectedToppings
which returns filtered data from another observableArray
called toppings
. selectedToppings
should return all toppings that have their observable
property of selected
set to true
. In some situations, only one topping can be selected, such as if a customer is ordering the child-sized ice cream. Here is my code.
<label>Multiple Toppings:
<input type="checkbox" data-bind="checked: multiselectable" />
<em data-bind="if: !multiselectable()">pick only one topping</em>
</label>
<h2>Available</h2>
<ul data-bind="foreach: toppings">
<li data-bind="text: label, click: selected.bind($data, true)"></li>
</ul>
<h2>Selected</h2>
<ul data-bind="foreach: selectedToppings">
<li data-bind="text: label, click: selected.bind($data, false)">
</li>
</ul>
<script>
function Topping(options) {
this.label = ko.observable(options.label);
this.selected = ko.observable(false);
}
var iceCream = {
toppings: ko.observableArray([
new Topping({label: 'Sprinkles'}),
new Topping({label: 'Marshmallows'}),
new Topping({label: 'Nuts'})
]),
multiselectable: ko.observable(false)
};
iceCream.selectedToppings = ko.computed(function () {
return ko.utils.arrayFilter(iceCream.toppings(), function(item){
return item.selected();
});
});
var selectedSub = iceCream.selectedToppings.subscribe(function (toppings) {
if (!this.multiselectable()) {
if (toppings.length > 1) {
var item = toppings.shift();
item.selected(false);
}
}
}, iceCream);
ko.applyBindings(iceCream);
</script>
Also on jsfiddle.
I am using a subscription on availableToppings
to enforce the one-topping rule if it is supposed to be followed. This implementation is not working, and I am not sure how to fix it.
What is not working:
- Ensure multiselectable is not checked.
- Click on Available Sprinkles.
- Click on Available Marshmallows.
- Click on Available Nuts.
- Click on Available Sprinkles.
- Notice how the selection does not change.