Search code examples
knockout.jsknockout-mapping-plugin

Populating dropdown based on radiobutton knockout


I am trying to populate lists based on the selection of the radio button in knockout.

Based on the radio button selection, appropriate list gets data-binded to the dropdown. http://jsfiddle.net/varunfiddle/5r9gjbdp/ <--- this works just fine.

However when I add the value field in the data-bind attribute the second drop down list does not populate itself.

http://jsfiddle.net/varunfiddle/h77mgmx8/1/

<p>

<input type="radio" value="groupUsers" data-bind="checked: Select" />sel users
<input type="radio" value="allUsers" data-bind="checked: Select" />all users
</p>
<p data-bind="text: Select"></p>
<p data-bind="with: Select">
     <select data-bind="value:selU,options: $root.users[$data], optionsText:'name',optionsCaption: 'Choose'"></select><br/>
    Something else? <select data-bind="value:allU, options: $root.users[$data], optionsText:'place'  ,optionsCaption: 'Choose'"></select>
</p>


function ViewModel() {
    this.Select = ko.observable();
    this.selU= ko.observable();
    this.allU=ko.observable();
    this.users = {
        groupUsers:[{name:"Varun",place:"bangalore"},{name:"Harsha",place:"SanJose"}],
        allUsers:[{name:"Robb",place:"houstonn"},{name:"Stark",place:"London"}]
    }}

ko.applyBindings(new ViewModel());

What is the mistake that I am making ?

When I try to access the value field, I see a null. Why is the value field not getting updated ? http://jsfiddle.net/varunfiddle/h77mgmx8/3/


Solution

  • The problem is not with your second select, it's with the first.

    Modify your data-bind for both:

    <select data-bind="value:$root.selU,options: $root.users[$data], optionsText:'name',optionsCaption: 'Choose'"></select><br/>
    Something else? <select data-bind="value:$root.allU, options: $root.users[$data], optionsText:'place'  ,optionsCaption: 'Choose'"></select>
    

    JSFiddle here: http://jsfiddle.net/h77mgmx8/5/

    Edit in response to new Fiddle

    When you created the data-binding to reference the .name, you caused the bindings to bomb out. When you first load your models the value will be null; and .name does not exist on the null object returned from selU or allU. Add the following to your model:

    // Null reference exceptions kill bindings, so let's fix null to
    // be an empty object.
    var self = this;
    ko.computed(function () {
        if (!self.selU()) {
            self.selU({});
        }
        if (!self.allU()) {
            self.allU({});
        }
    });
    

    JSFiddle here: http://jsfiddle.net/h77mgmx8/13/