Knockout Checkbox Binding

by robhortn

HTML

<script src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<script src="https://rawgithub.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.debug.js"></script>
<div>
    <p>Items in the Available Books list should display in the Selected Books listed when checked and disappear from the Selected Books list when unchecked.</p>
    <p>In the expensive books section, the list of books should be filtere by prices over a specified amount.</p>
</div>
<br />Available Books:
<div data-bind="foreach: $root.availableItems">
    <input type="checkbox" data-bind="value: id(), click: $root.itemSelection" /> <span data-bind="text: '&nbsp;' + Name() + '&nbsp;' + Price()"></span>

    <br/>
</div>
<br/>Selected Books:
<div data-bind="foreach: $root.selectedItems"> <span data-bind="text: id() + '|' + Name() + '|' + Price()"></span>

    <br/>
</div>
<br/>Expensive Books:
<div data-bind="foreach: $root.expensiveItems()"> <span data-bind="text: id() + '|' + Name() + '|' + Price()"></span>

    <br/>
</div>
<br />
<div>Number of expensive items <span data-bind="text: $root.expensiveItems().length"></span>

</div>
<p>Check count of expensive books via js function</p>
<div>
    <input id="btnClickMe" type="button" value="How many?" />
</div>
<p>Check contents of Expensive Book array</p>
<div>
    <input id="btnShowItems" type="button" value="Show Me Values" />
</div>

JavaScript 1.7

$("#btnClickMe").click(function () {
    alert('There are ' + viewModel.expensiveItems().length + ' books in this array');
});

$("#btnShowItems").click(function () {

    var myarray = [];
    var myJSON = "";

    for (var i = 0; i < viewModel.expensiveItems().length; i++) {
        var book = {
            "id": viewModel.expensiveItems()[i].id(),
                "name": viewModel.expensiveItems()[i].Name()
        };
        myarray.push(book);
    }

    myJSON = JSON.stringify(myarray);
    alert(myJSON);
});

function BookItem(id, name, price) {
    var self = this;

    self.id = ko.observable(id);
    self.Name = ko.observable(name);
    self.Price = ko.observable(price);
    self.Selected = ko.observable(false);
}

function ViewModel() {
    var self = this;

    self.availableItems = ko.observableArray();

    self.selectedItems = ko.computed(function () {
        return self.availableItems().filter(function (item) {
            return item.Selected() == true;
        });
    });

    self.expensiveItems = ko.computed(function () {
        return self.availableItems().filter(function (item) {
            return item.Price() > 30;
        });
    });

    self.init = function () {
        self.availableItems.push(new BookItem(1, 'Knockout.js For Dummies, Newbs or just Rob', 30.99));
        self.availableItems.push(new BookItem(2, 'Application Security - Exploring Your Inner Rage', 40.99));
        self.availableItems.push(new BookItem(3, 'iOS Development for Windows Developers', 41.99));
        self.availableItems.push(new BookItem(4, 'Stand Up Meeting Timers You Can Build at Home', 10.99));
        self.availableItems.push(new BookItem(5, 'Coffee, Red Bull, and Other Ways to Speed Up Time', 21.99));
    };

    self.itemSelection = function (item) {
        item.Selected(!(item.Selected()));
        return true;
    };
}

var viewModel = new ViewModel();
ko.applyBindings(viewModel);
viewModel.init();