KO Hierarchical Select List Binding

by Jimmy Chandra

HTML

<h2>Fire Someone</h2>

<p>Pick someone to fire...</p>

<div id='staffPicker'>
    <select data-bind="value:selectedOffice, options:availableOffice, optionsText:'name', optionsCaption:'Pick an office...'"></select><br/>
    
    <select data-bind="value:selectedDepartment, options:availableDepartments, optionsText:'name', optionsCaption:'Pick a department...',visible:typeof(selectedOffice()) !== 'undefined'"></select><br/>
    
    <select data-bind="value:selectedStaff, options:availableStaffs, optionsText:'name', optionsCaption: 'Pick a staff...',visible:typeof(selectedDepartment()) !== 'undefined'"></select>
    
    <p data-bind="visible:typeof(selectedStaff()) !== 'undefined'"><span data-bind="text:firedStaffName"></span> has been fired.</p>
</div>

CSS

select {
    width: 200px;
    margin-bottom:10px;
}

JavaScript

(function() {
    'use strict';
    
    var VM = function(data) {
        var self = this;
        
        self.selectedOffice = ko.observable();
        self.selectedDepartment = ko.observable();
        self.selectedStaff = ko.observable();
        self.availableOffice = ko.observableArray(data);
        self.availableDepartments = ko.observableArray();
        self.availableStaffs = ko.observableArray();
        
        self.selectedOffice.subscribe(function(n) {
            self.availableDepartments(n.departments);
        });        
        
        self.selectedDepartment.subscribe(function(n) {
            self.availableStaffs(n.staffs);
        });
        
        self.firedStaffName = ko.computed(function() {
            if (self.selectedStaff()) {
                return self.selectedStaff().name;
            }
            
            return "Nobody";
        });
    };
    
    var vm = new VM([
        { 
            id: 1, 
            name: 'Jakarta',
            departments : [
                {
                    id: 1,
                    name: 'Corporate',
                    staffs: [
                        { id: 1, name: 'Badung' },
                        { id: 2, name: 'Lala' }
                    ]
                },
                {
                    id: 2,
                    name: 'Finance',
                    staffs: [
                        { id: 3, name: 'Unyil' },
                        { id: 4, name: 'Cuplis' },
                        { id: 15, name: 'Usro' }
                    ]
                }
            ]
        },
        {
            id: 2,
            name: 'Bandung',
            departments: [
                {
                    id: 3,
                    name: 'Manufacturing',
                    staffs: [
                        { id: 5, name: 'Murni' },
                        { id: 6, name: 'Paijo' }
                    ]
                },
                {
                    id: 4,
               ...