Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KnockoutJS - Binding value of select with optgroup and javascript objects

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); 

like image 255
user888734 Avatar asked Jun 25 '12 12:06

user888734


People also ask

What is two-way binding in KnockoutJS?

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.

What is KnockoutJS used for?

KnockoutJS is basically a library written in JavaScript, based on MVVM pattern that helps developers build rich and responsive websites.

How do you activate a KnockoutJS model?

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.


2 Answers

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/

like image 145
RP Niemeyer Avatar answered Sep 21 '22 15:09

RP Niemeyer


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> 
like image 35
Berezh Avatar answered Sep 20 '22 15:09

Berezh