JSFiddle - React, Tailwind, and code Playground

by Doug Hill

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-debug.js"></script>
<select data-bind="options: manufacturers, optionsCaption:'Manufacturer', optionsText: 'text', optionsValue: 'value', value: selectedManufacturer"></select>
<select data-bind="options: models, optionsCaption:'Model', optionsText: 'text', optionsValue: 'value', value: selectedModel, enable: models().length"></select>
<select data-bind="options: engines, optionsCaption:'Engine', optionsText: 'text', optionsValue: 'value', value: selectedEngine, enable: engines().length"></select>

JavaScript

function ViewModel(items) {
    this.manufacturers = ko.observableArray(items);
    this.selectedManufacturer = ko.observable();
    this.selectedModel = ko.observable();
    this.selectedEngine = ko.observable();
    
    function getById(items, value) {
        if(!value) {
            return [];
        }
        
        var result = ko.utils.arrayFirst(items, function(item) {
            return item.value === value;
        });
        
        return result && result.childItems || [];
    }
    
    this.models = ko.computed(function(){
        var items = this.manufacturers();
        var id = this.selectedManufacturer()
        return getById(items, id);
    }, this);
    
    this.engines = ko.computed(function(){
        var items = this.models();
        var id = this.selectedModel()
        return getById(items, id);
    }, this);
}

var items = [
    { text: 'Ford', value: 1, childItems:
     [
         { text: 'F-150', value: 1, childItems:
          [
              { text: 'Gasoline', value: 1, childItems: [] },
              { text: 'Diesel', value: 2, childItems: [] }
          ]
         },
         { text: 'F-250', value: 2, childItems:
          [
              { text: 'Gasoline', value: 3, childItems: [] },
              { text: 'Diesel', value: 4, childItems: [] }
          ]
         }
     ]
    },
    { text: 'Honda', value: 2, childItems:
     [
         { text: 'Civic', value: 5, childItems:
          [
              { text: 'Gasoline', value: 5, childItems: [] },
              { text: 'Electric', value: 6, childItems: [] }
          ]
         },
         { text: 'Accord', id: 6, childItems:
          [
              { text: 'Gasoline', value: 7, childItems: [] },
              { text: 'Electric', value: 8, childItems: [] }
          ]
         }
     ]
    }
];

var module = {};

module.viewModel = new ViewModel(items);

ko.applyBindings(module.viewModel);