KO Subscription

by _anil

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.0/knockout-min.js"></script>
<script src="http://cloud.github.com/downloads/rniemeyer/knockout-postbox/knockout-postbox.min.js"></script>
<h2>Master List</h2>
<ul data-bind="foreach: AllStates">
    <li>
        <label><input type="checkbox" data-bind="value: abbrev, checked: $root.BusinessStates"/> <span data-bind="text: name"></span></label></li>
</ul>

<h2>Services</h2>
<div class="service" data-bind="foreach: Services">
    <h3 data-bind="text: Name"></h3>
    <ul data-bind="foreach: Locations">
        <li><label><input type="checkbox" data-bind="value: State().abbrev, checked: IsSelected" /> <span data-bind="text: State().name"></span></label> <input type="text" placeholder="Cert. Number" data-bind="value: CertNum" /></li>
    </ul>
</div>

<hr/>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

CSS

h2 {
    font-weight: bold;
}
h3 {
    font-style: italic;
}
ul {
    margin-left: 1em;
    margin-bottom: 1em;
}
div.service {
    margin-left: 1em;
}

JavaScript

function Service(sName) {
    var self = this;

    self.Name = ko.observable(sName);
    self.SelectedStates = ko.observableArray().subscribeTo("MasterStates");
    self.Locations = ko.computed(function() {
        var arr = [];

        ko.utils.arrayForEach(self.SelectedStates(), function(item) {
            arr.push(new StateAndCert(item));
        });
        return arr;
    });
}

function StateAndCert(state) {
    var self = this;

    self.IsSelected = ko.observable(false);
    self.State = ko.observable(state);
    self.CertNum = ko.observable();
}

function viewModel() {
    var self = this;

    self.AllStates = [
        {
        name: "Alabama",
        abbrev: "AL"},
    {
        name: "Alaska",
        abbrev: "AK"},
    {
        name: "Arizona",
        abbrev: "AZ"},
    {
        name: "Arkansas",
        abbrev: "AR"}
    ];

    self.BusinessStates = ko.observableArray();

    self.AllSelectedStates = ko.computed(function() {
        return ko.utils.arrayFilter(self.AllStates, function(item) {
            return self.BusinessStates.indexOf(item.abbrev) >= 0;
        });
    });

    self.AllSelectedStatesAndCerts = ko.computed(function() {
        var arr = [];

        ko.utils.arrayForEach(self.AllSelectedStates(), function(item) {
            arr.push(new StateAndCert(item));
        });
        return arr;
    });

    self.Services = ko.observableArray([
        new Service("Sales"),
        new Service("Service"),
        new Service("Consulting")
        ]);

    self.AllSelectedStates.publishOn("MasterStates");
};

var vm = new viewModel();

vm.AllSelectedStates.subscribe(function(newValue) {
    //console.log(newValue);
});

ko.applyBindings(vm);