knockout multiselect with checkbox
by Pranav Kulkarni
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<div class="rounded-box" id="locationsSelect-container" data-bind="with: students">
<span>There are </span><span data-bind="text: FlattenedOptions().length"></span><span> students in our class.</span>
<br/>
<span>There are </span><span data-bind="text: Options().length"></span><span> student groups in our class.</span>
<!-- ko template: { name: 'dropdown-template' } -->
<!-- /ko -->
</div>
<script type="text/html" id="dropdown-template">
<div id="busyContainer" class="loading-div-mask" data-bind="css: { 'visible': OptionsBusy() }">
<img class="loading-image" src="https://i0.wp.com/cdnjs.cloudflare.com/ajax/libs/galleriffic/2.0.1/css/loader.gif" alt="Loading..." />
</div>
<div class="multiselect-native-select">
<div class="btn-group">
<button type="button" class="multiselect dropdown-toggle btn btn-default" data-toggle="dropdown" title="All" aria-expanded="true"><span class="multiselect-selected-text" data-bind="text: SelectedText()"></span> <b class="caret"></b></button>
<ul class="multiselect-container dropdown-menu">
<li class="multiselect-item multiselect-all"><a tabindex="0" class="multiselect-all"><label class="checkbox"><input type="checkbox" data-bind="checked: IsAllOptionsSelected"> Select all</label></a></li>
<!-- ko foreach: Options -->
<!-- ko if: typeof Options == 'undefined' -->
<li>
<a tabindex="0"><label class="checkbox">
...
CSS
.loading-div-mask {
display: none;
}
JavaScript
var FilterOptionModel = function (text, value) {
var self = this;
value = value ? value : "";
self.Value = ko.observable(value);
text = text ? text : "";
self.Text = ko.observable(text);
self.IsSelected = ko.observable(false);
};
var FilterGroupModel = function (label, options) {
var self = this;
label = label ? label : "";
self.Label = ko.observable(label);
options = options ? options : [];
self.Options = ko.observableArray(options);
self.IsSelected = ko.pureComputed({
read: function () {
var nonSelected = false;
for (var i = 0; i < self.Options().length; i++) {
if (!self.Options()[i].IsSelected())
nonSelected = true;
}
return !nonSelected;
},
write: function (selected) {
for (var i = 0; i < self.Options().length; i++) {
!self.Options()[i].IsSelected(selected);
}
}
});
};
var FilterDropDownModel = function () {
var self = this;
self.Title = ko.observable('');
self.Options = ko.observableArray([]);
self.FlattenedOptions = ko.pureComputed(function () {
var allOptions = self.Options();
if (self.IsGroupedOptions()) {
allOptions = Array.prototype.concat.apply([], self.Options().map(function (category) { return category['Options'](); }));
}
return allOptions;
}, self);
self.IsGroupedOptions = ko.pureComputed({
read: function () {
var result = false;
var allOptions = self.Options();
if (allOptions && allOptions.length && allOptions.length...