Cascading Dropdowns Select

cascading dropdowns with Select2 and Knockout

by Doug Hill

HTML

<link rel="stylesheet" href="https://rawgithub.com/ivaynberg/select2/master/select2.css">
<script src="https://rawgithub.com/ivaynberg/select2/master/select2.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script>
<div>
    <select id="make" data-bind="select2:{} , options: carMakers, value: selectedMake,optionsValue:'text', optionsText : 'text', optionsCaption : 'Select your make'"></select><br/>
    
    Selected Make:<span data-bind="text: selectedMake"></span><br/>
    <select id="type" data-bind="select2:{} ,options: carTypes, value: selectedType, optionsValue:'text', optionsText : 'text', optionsCaption : 'Select your type', enable : carTypes"></select><br/>
   
    Selected Type: <span data-bind="text: selectedType"></span><br/>
    <select id="model" data-bind="select2:{} ,options: carModels, value: selectedModel,optionsValue:'text', optionsText : 'text', optionsCaption : 'Select your Model', enable: carModels"></select><br/>
   
    Selected Model: <span data-bind="text: selectedModel"></span><br/>
</div>

CSS

.select2-container
{
    width:150px;
}

select
{
    width:150px;
}

JavaScript

//ko binding handler
ko.bindingHandlers.select2 = {
    init: function(element, valueAccessor) {
        
         var options = ko.toJS(valueAccessor()) || {};
          setTimeout(function() { 
              $(element).select2(options);
          }, 0);
       //$(element).select2(valueAccessor());

        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).select2('destroy');
        });
    },
    update: function(element) {
        $(element).trigger('change');
    }
};

//Define our options model
var cascadingOption = function(data){
    var self = this;
    //self.data=self;
    self.text = data.text;
    self.childOptions = data.childOptions;
    //console.log(self);
}

//fill our models with example data
function buildData(){
    var fordTrucks = new cascadingOption({
        text: 'Trucks',
        childOptions : [
            new cascadingOption({
                text: 'F150'
            }),
            new cascadingOption({
                text: 'SuperDuty'
            })
        ]
    });

    var fordCars = new cascadingOption({
        text: 'Cars',
        childOptions : [
            new cascadingOption({
                text: 'Focus'
            }),
            new cascadingOption({
                text: 'Mustang'
            })
        ]
    });

    var fords = new cascadingOption({
        text: 'Ford',
        childOptions : [fordTrucks, fordCars]
    });

    var audis = new cascadingOption({
        text: 'Audi',
        childOptions : [
            new cascadingOption({
                text:'Crossovers',
                childOptions : [
                    {text: 'Q5'},
                    {text: 'Q7'}
                ]
            }),
            new cascadingOption({
                text:'Cars',
                childOptions : [
                    {text: 'A3'},
                    {text: 'A4'},
                    {text: 'A6'}
                ]
            })
        ]
    });

    return [fords,...