knockout.jsjquery-ui-selectmenu

KnockoutJS select option value


I'm trying to disable one select HTML element based on value from another select HTML element using KnockoutJS

HTML code for that part looks like:

<label for="searchBy">Search by:</label>
<select id="searchBy" name="searchBy" tabindex="1" data-bind="options: searchBy, value: selectedSearchBy, optionsText: 'searchBy', optionsValue: 'searchBy'"></select>

<label for="searchMethod">Search method:</label>
<select id="searchMethod" name="searchMethod" tabindex="2" data-bind="options: searchMethod, value: selectedSearchMethod, optionsText: 'searchMethod', optionsValue: 'searchMethod', disable: searchByDOB"></select>

and related KonckutJS code:

this.searchByDOB = ko.observable(false);

this.searchBy = ko.observableArray([{searchBy: 'Name', value: 'name'},{searchBy: 'Date of Birth', value: 'dob'},{searchBy: 'User ID', value: 'id'}]);

this.selectedSearchBy = ko.observable();
this.searchMethod = ko.observableArray([{searchMethod: 'beginning with', value: 's%'},{searchMethod: 'containing', value: '%s%'},{searchMethod: 'ending with', value: '%s'}]);
this.selectedSearchMethod = ko.observable();

this.selectedSearchBy.subscribe(function(latest) {
  console.log("Search by: " + this.selectedSearchBy().value);
    if(this.selectedSearchBy().value == 'dob')
    {
      this.searchByDOB = ko.observable(true);
    }

}, this);

but what I'm getting is that this.selectedSearchBy().value is undefinied

What i have missing? Should I change logic to on change event?


Solution

  • There is no .value property; it is this one that gives the undefined error.

    Just read the value via this.selectedSearchBy().

    Also write to a property via this.searchByDOB(true) instead of a value assignment.

    EDIT

    The subscribe method must include both the enable this.searchByDOB(true) and disable this.searchByDOB(false) statements, otherwise the dropdown list stays disabled once disabled.

    Also, only checking via (this.selectedSearchBy() === 'dob') suffices.
    (Prefere === over ==, although it makes no difference here.)

    function ViewModel()
    {
    
        this.searchByDOB = ko.observable(false);
    
        this.searchBy = ko.observableArray([
            {searchBy: 'Name', value: 'name'},
            {searchBy: 'Date of Birth', value: 'dob'},
            {searchBy: 'User ID', value: 'id'}
          ]);
    
        this.selectedSearchBy = ko.observable();
        
        this.searchMethod = ko.observableArray([
            {searchMethod: 'beginning with', value: 's%'},
            {searchMethod: 'containing', value: '%s%'},
            {searchMethod: 'ending with', value: '%s'}
            ]);
            
        this.selectedSearchMethod = ko.observable();
    
        this.selectedSearchBy.subscribe(function(latest) {
            var isSearchByDob = (this.selectedSearchBy() === 'dob');        
            this.searchByDOB(isSearchByDob);
            }, this
            );
    }
    
    var vm = new ViewModel();
    ko.applyBindings(vm);
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    
    <label for="searchBy">Search by:</label>
    <select id="searchBy" name="searchBy" tabindex="1" data-bind="options: searchBy, value: selectedSearchBy, optionsText: 'searchBy', optionsValue: 'value'"></select>
    
    <label for="searchMethod">Search method:</label>
    <select id="searchMethod" name="searchMethod" tabindex="2" data-bind="options: searchMethod, value: selectedSearchMethod, optionsText: 'searchMethod', optionsValue: 'value', disable: searchByDOB"></select>