Search code examples
knockout.jsknockout-binding-handlers

How can I disable/enable a drop down embedded in a table mapped to a knockout observable array


I'd like to disable/enable a drop down embedded in a table in a form until a particular value is selected in the predecessor drop down.

Here's what I tried that doesn't seem to work:

<tbody data-bind="foreach:studentData">
    <tr>
        <td><span data-bind="text:rollNo"></span></td>
        <td><select class="form-control" data-bind="options:$parent.sexDropDown,optionsText:'name',optionValue:'id',value:sex,optionsCaption:'-Select-'"></select></td>
        <td><select class="form-control" data-bind="options:$parent.uniformTypeDropDown,optionsText:'name',optionValue:'id',value:uniform,enable:sex? (sex.id == 2):false,optionsCaption:'-Select-'"></select></td>
    </tr>
</tbody>

Please find the associated fiddle here

To give a brief I want the "Uniform Type" drop down in each of the rows to be enabled in case the option "Female" is selected in the "Sex" drop down and it needs to be disabled in all other scenarios.


Solution

  • First, your sex and uniform properties have to be observable to allow for two way binding:

    self.studentData  = ko.observableArray([
      { rollNo: 1, sex: ko.observable(null), uniform: ko.observable(null) }
      //                ^^^^^^^^^^^^^^    ^           ^^^^^^^^^^^^^^    ^
      // This allows the `value` binding to write to the property
    ]);
    

    Then, in your enable binding, you can use the live-updating value:

    enable: sex() ? (sex().id === 2) : false
    //         ^^       ^^
    // Because this property is now observable, you need to call it to extract
    // its value
    

    In an updated fiddle: https://jsfiddle.net/ocd5qvr8/