I found an example here to create a select list with optgroups using KnockoutJS. This works fine, but I want to bind the value of the dropdown to my own javascript object, then access a particular property of that object:
<select data-bind="foreach: groups, value:selectedOption"> <optgroup data-bind="attr: {label: label}, foreach: children"> <option data-bind="text: label"></option> </optgroup> </select>
function Group(label, children) { this.label = ko.observable(label); this.children = ko.observableArray(children); } function Option(label, property) { this.label = ko.observable(label); this.someOtherProperty = ko.observable(property); } var viewModel = { groups: ko.observableArray([ new Group("Group 1", [ new Option("Option 1", "A"), new Option("Option 2", "B"), new Option("Option 3", "C") ]), new Group("Group 2", [ new Option("Option 4", "D"), new Option("Option 5", "E"), new Option("Option 6", "F") ]) ]), selectedOption: ko.observable(), specialProperty: ko.computed(function(){ this.selectedOption().someOtherProperty(); }) }; ko.applyBindings(viewModel);
KO is able to create a two-way binding if you use value to link a form element to an Observable property, so that the changes between them are exchanged among them. If you refer a simple property on ViewModel, KO will set the form element's initial state to property value.
KnockoutJS is basically a library written in JavaScript, based on MVVM pattern that helps developers build rich and responsive websites.
To activate Knockout, add the following line to a <script> block: ko. applyBindings(myViewModel); You can either put the script block at the bottom of your HTML document, or you can put it at the top and wrap the contents in a DOM-ready handler such as jQuery's $ function.
A good choice for this situation is to create a quick custom binding that let's your "hand-made" options behave in the same way as options created by the options
binding (attaches the object as meta-data). The binding could simply look like:
ko.bindingHandlers.option = { update: function(element, valueAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()); ko.selectExtensions.writeValue(element, value); } };
You would use it like:
<select data-bind="foreach: groups, value: selectedOption"> <optgroup data-bind="attr: {label: label}, foreach: children"> <option data-bind="text: label, option: $data"></option> </optgroup> </select>
Sample here: http://jsfiddle.net/rniemeyer/aCS7D/
This version with caption and if you want to have parent item selected:
<select data-bind="value: selectedOption "> <option data-bind="value:'', text:'Select'"></option> <!-- ko foreach: groups --> <optgroup data-bind="attr:{label: label}"> <option data-bind="value: $data, text:label"></option> <!-- ko foreach: children --> <option data-bind="value: $data, text:label"></option> <!-- /ko --> </optgroup> <!-- /ko --> </select>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With