Commit bfa88e43 authored by David Stutz's avatar David Stutz

Merge pull request #447 from Aaron-P/master

Improved knockout binding.
parents 614bd4b5 3f1b6be7
......@@ -11,71 +11,82 @@
if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
ko.bindingHandlers.multiselect = {
after: ['options', 'value', 'selectedOptions'],
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var listOfSelectedItems = allBindingsAccessor().selectedOptions;
var config = ko.utils.unwrapObservable(valueAccessor());
$(element).multiselect(config);
if (isObservableArray(listOfSelectedItems)) {
// Set the initial selection state on the multiselect list.
$(element).multiselect('select', ko.utils.unwrapObservable(listOfSelectedItems));
// Subscribe to the selectedOptions: ko.observableArray
listOfSelectedItems.subscribe(function (changes) {
var addedArray = [], deletedArray = [];
forEach(changes, function (change) {
switch (change.status) {
case 'added':
addedArray.push(change.value);
break;
case 'deleted':
deletedArray.push(change.value);
break;
}
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $element = $(element);
var config = ko.toJS(valueAccessor());
$element.multiselect(config);
if (allBindings.has('options')) {
var options = allBindings.get('options');
if (ko.isObservable(options)) {
ko.computed({
read: function() {
options();
setTimeout(function() {
var ms = $element.data('multiselect');
if (ms)
ms.updateOriginalOptions();//Not sure how beneficial this is.
$element.multiselect('rebuild');
}, 1);
},
disposeWhenNodeIsRemoved: element
});
if (addedArray.length > 0) {
$(element).multiselect('select', addedArray);
}
if (deletedArray.length > 0) {
$(element).multiselect('deselect', deletedArray);
}
}, null, "arrayChange");
}
}
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var listOfItems = allBindingsAccessor().options,
ms = $(element).data('multiselect'),
config = ko.utils.unwrapObservable(valueAccessor());
if (isObservableArray(listOfItems)) {
// Subscribe to the options: ko.observableArray incase it changes later
listOfItems.subscribe(function (theArray) {
$(element).multiselect('rebuild');
});
//value and selectedOptions are two-way, so these will be triggered even by our own actions.
//It needs some way to tell if they are triggered because of us or because of outside change.
//It doesn't loop but it's a waste of processing.
if (allBindings.has('value')) {
var value = allBindings.get('value');
if (ko.isObservable(value)) {
ko.computed({
read: function() {
value();
setTimeout(function() {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
}
}
if (!ms) {
$(element).multiselect(config);
}
else {
ms.updateOriginalOptions();
//Switched from arrayChange subscription to general subscription using 'refresh'.
//Not sure performance is any better using 'select' and 'deselect'.
if (allBindings.has('selectedOptions')) {
var selectedOptions = allBindings.get('selectedOptions');
if (ko.isObservable(selectedOptions)) {
ko.computed({
read: function() {
selectedOptions();
setTimeout(function() {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
}
}
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$element.multiselect('destroy');
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $element = $(element);
var config = ko.toJS(valueAccessor());
$element.multiselect('setOptions', config);
$element.multiselect('rebuild');
}
};
}
function isObservableArray(obj) {
return ko.isObservable(obj) && !(obj.destroyAll === undefined);
}
function forEach(array, callback) {
for (var index = 0; index < array.length; ++index) {
callback(array[index]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment