Knockout and jQuery Mobile: Checkboxes
Demonstrates a custom KnockoutJS binding that can be used in place of the standard 'checked' binding when using jQuery Mobile with KnockoutJS.
by mcannon
HTML
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css">
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css">
<div data-bind="foreach: people">
<!--<div>
<input type="checkbox" data-bind="koChecked: $root.selectedPeople.indexOf(id), attr: {id: 'chk' + ko.unwrap($index) }"/>
<label data-bind="text: name, attr: {for: 'chk' + ko.unwrap($index) }"></label>
</div>-->
<!---->
<span class="button-checkbox">
<button type="button" class="btn" data-color="primary"><span data-bind="text: name"></span></button>
<input type="checkbox" class="hidden" value="" data-bind="value2: id, checkedValue: id, checked: $root.selectedPeople, attr: {id: 'chk' + id }">
</span>
<!--
<li>
<input type="checkbox" value="" data-bind="value2: id, checkedValue: id, checked: $root.selectedPeople"><span data-bind="text: name"></span>
</li>-->
</div>
<div>
<!-- TODO: change data-bind="koChecked: inlist(val1)"
http://bootsnipp.com/snippets/featured/jquery-checkbox-buttons
-->
<!-- <input class="info" type="checkbox" data-bind="koChecked: val1" id="checkbox1"/>
<label for="checkbox1">checkbox1</label>
</div>
<div>
<input type="checkbox" data-bind="koChecked: val2" id="checkbox2"/>
<label for="checkbox2">checkbox2</label>
</div>
<div>
<input type="checkbox" data-bind="koChecked: val3" id="checkbox3"/>
<label for="checkbox3">checkbox3</label>
</div>-->
<hr/>
ViewModel
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
JavaScript
/*ko.bindingHandlers.koChecked = {
init: ko.bindingHandlers.checked.init,
update: function (element, valueAccessor) {
//KO v3 and previous versions of KO handle this differently
//KO v3 does not use 'update' for 'checked' binding
if (ko.bindingHandlers.checked.update)
ko.bindingHandlers.checked.update.apply(this, arguments); //for KO < v3, delegate the call
else
ko.utils.unwrapObservable(valueAccessor()); //for KO v3, force a subscription to get further updates
if ($(element).data("mobile-checkboxradio")) //calling 'refresh' only if already enhanced by JQM
$(element).checkboxradio('refresh');
}
};*/
function Person(id,name,age) {
this.id = id;
this.name = name;
this.age = age;
}
var listOfPeople = [
new Person(1, 'Fred', 25),
new Person(2, 'Joe', 60),
new Person(3, 'Sally', 43),
new Person(4, 'Steve', 43),
new Person(5, 'Bob', 43),
new Person(6, 'Roger', 43),
new Person(7, 'Mary', 43)
];
var viewModel = {
selectedPeople: ko.observableArray([]),
people: ko.observableArray(listOfPeople),
checkedList : ko.observableArray([])
};
$(function () {
ko.applyBindings(viewModel);
});
$(function () {
$('.button-checkbox').each(function () {
// Settings
var $widget = $(this),
$button = $widget.find('button'),
$checkbox = $widget.find('input:checkbox'),
color = $button.data('color'),
settings = {
on: {
icon: 'glyphicon glyphicon-check'
},
off: {
icon: 'glyphicon glyphicon-unchecked'
}
};
// Event Handlers
$button.on('click', function () {
$checkbox.prop('checked', !$checkbox.is(':checked'));
$checkbox.triggerHandler('change');
updateDisplay();
});
$checkbox.on('change',...