Reputation: 9342
I develop a project with knockout. I found a way to have my select with knockout binding and optgroup. Here is the solution: http://jsfiddle.net/HPhmB/3/
Unfortunately this solution use a static model for populating 'option' & 'optgroup' in the select.
For my personal need, I would like something more dynamic. I would like to start with an observableArray provided from a database. This observableArray looks something like this:
var vehicles = ko.observableArray([
{
Id: 1,
Brand: "Volkswagen",
Type: "Golf"
},
{
Id: 2,
Brand: "Volkswagen",
Type: "Sharan"
},
{
Id: 3,
Brand: "BMW",
Type: "118i"
}
{
Id: 4,
Brand: "BMW",
Type: "525D"
}
]);
My question: is it possible to have a solution based on this single observableArray to construct the select. Maybe with the help of computed properties to retrieve the optgroup/options?
Thanks.
Upvotes: 3
Views: 4005
Reputation: 16465
Here is one of the ways to do this. It is not optimal but works well:
var ViewModel = function () {
var self = this;
self.vehicles = ko.observableArray([{
Id: 1,
Brand: "Volkswagen",
Type: "Golf"
}, {
Id: 2,
Brand: "Volkswagen",
Type: "Sharan"
}, {
Id: 3,
Brand: "BMW",
Type: "118i"
}, {
Id: 2,
Brand: "BMW",
Type: "525D"
}]);
self.brands = ko.computed(function(){
var list = ko.utils.arrayMap(self.vehicles(), function(item){
return item.Brand;
});
return ko.utils.arrayGetDistinctValues(list);
});
};
ko.applyBindings(new ViewModel());
<select data-bind="foreach: brands">
<optgroup data-bind="attr: {label: $data}, foreach: $parent.vehicles">
<!-- ko if: Brand == $parent -->
<option data-bind="text: Type"></option>
<!-- /ko -->
</optgroup>
</select>
Fiddle: http://jsfiddle.net/HPhmB/55/
Upvotes: 9