Knockout - Linked Dropdown Lists

by smichelotti

HTML

<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.debug.js"></script>
<select data-bind="options: makes, value: selectedMake, optionsText: 'name', optionsCaption: 'Choose a make'"></select>
<select data-bind="options: models, value: selectedModel, optionsText: 'name', optionsCaption: 'Choose a model'"></select>
<div>
    selectedMake:
    <!-- ko if: selectedMake-->
    <span data-bind="text:selectedMake().name"></span>
    <!-- /ko -->
</div>
<div>
    selectedModel:
    <!-- ko if: selectedModel-->
    <span data-bind="text:selectedModel().name"></span>
    <!-- /ko -->
</div>

JavaScript

// One namespace to rule them all
var my = {};

// The "Models"
my.data = {
    allMakes: ko.observableArray([
    {
    name: "Lexus",
    key: "L"},
{
    name: "BMW",
    key: "B"}]),
    allModels: ko.observableArray([
{
    name: "ISF",
    makeKey: "L",
    key: 1},
{
    name: "IS350",
    makeKey: "L",
    key: 2},
{
    name: "ES350",
    makeKey: "L",
    key: 3},
{
    name: "Z3",
    makeKey: "B",
    key: 4},
{
    name: "i335",
    makeKey: "B",
    key: 5},
{
    name: "i735",
    makeKey: "B",
    key: 6}])};

// The ViewModel
function VehViewModel() {
    var 
        makes = my.data.allMakes, 
        selectedMake = ko.observable(""), 
        selectedModel = ko.observable(""), 
        models = ko.computed(function() {
            if (!selectedMake()) {
                return null;
            }
            var filter = selectedMake().key.toLowerCase();
            return ko.utils.arrayFilter(my.data.allModels(), function(item) {
                //return ko.utils.stringStartsWith(item.makeKey.toLowerCase(), filter);
                return item.makeKey.toLowerCase().substring(0, filter.length) === filter;
            });
        }, this);        
    return {
        makes: makes,
        selectedMake: selectedMake,
        selectedModel: selectedModel,
        models: models
    };
}
//})();

// Whenever the selectedMake changes, reset the selectedModel 
//my.viewmodel.selectedMake.subscribe(function() { 
//    my.viewmodel.selectedModel(undefined); 
//}, my.viewmodel); 

//ko.applyBindings(my.viewmodel);
ko.applyBindings(new VehViewModel());