define("knockout.sortable",["jquery","order!utils","order!knockout"], function() {
(function(ko, $, undefined) {
-var prepareTemplateOptions = function(valueAccessor) {
- var result = {},
- options = ko.utils.unwrapObservable(valueAccessor());
+ var prepareTemplateOptions = function(valueAccessor) {
+ var result = {},
+ options = ko.utils.unwrapObservable(valueAccessor());
- //build our options to pass to the template engine
- if (options.data) {
- result.foreach = options.data;
- result.name = options.template;
- result.afterAdd = options.afterAdd;
- result.beforeRemove = options.beforeRemove;
- result.afterRender = options.afterRender;
- result.includeDestroyed = options.includeDestroyed;
- result.templateEngine = options.templateEngine;
- } else {
- result.foreach = valueAccessor();
- }
+ //build our options to pass to the template engine
+ if (options.data) {
+ result.foreach = options.data;
+ result.name = options.template;
+ result.afterAdd = options.afterAdd;
+ result.beforeRemove = options.beforeRemove;
+ result.afterRender = options.afterRender;
+ result.includeDestroyed = options.includeDestroyed;
+ result.templateEngine = options.templateEngine;
+ } else {
+ result.foreach = valueAccessor();
+ }
- //use an afterRender function to add meta-data
- if (options.afterRender) {
- //wrap the existing function, if it was passed
- result.afterRender = function(element, data) {
- ko.bindingHandlers.sortable.afterRender.call(data, element, data);
- options.afterRender.call(data, element, data);
- };
- } else {
- result.afterRender = ko.bindingHandlers.sortable.afterRender;
- }
+ //use an afterRender function to add meta-data
+ if (options.afterRender) {
+ //wrap the existing function, if it was passed
+ result.afterRender = function(element, data) {
+ ko.bindingHandlers.sortable.afterRender.call(data, element, data);
+ options.afterRender.call(data, element, data);
+ };
+ } else {
+ result.afterRender = ko.bindingHandlers.sortable.afterRender;
+ }
- //return options to pass to the template binding
- return result;
-};
+ //return options to pass to the template binding
+ return result;
+ };
-//connect items with observableArrays
-ko.bindingHandlers.sortable = {
- init: function(element, valueAccessor, allBindingsAccessor, data, context) {
- var value = ko.utils.unwrapObservable(valueAccessor()),
- templateOptions = prepareTemplateOptions(valueAccessor),
- sortable = ko.bindingHandlers.sortable,
- connectClass = value.connectClass || sortable.connectClass,
- allowDrop = value.allowDrop === undefined ? sortable.allowDrop : value.allowDrop,
- beforeMove = value.beforeMove || sortable.beforeMove,
- afterMove = value.afterMove || sortable.afterMove,
- options = value.options || sortable.options;
+ //connect items with observableArrays
+ ko.bindingHandlers.sortable = {
+ init: function(element, valueAccessor, allBindingsAccessor, data, context) {
+ var value = ko.utils.unwrapObservable(valueAccessor()),
+ templateOptions = prepareTemplateOptions(valueAccessor),
+ sortable = ko.bindingHandlers.sortable,
+ connectClass = value.connectClass || sortable.connectClass,
+ allowDrop = value.allowDrop === undefined ? sortable.allowDrop : value.allowDrop,
+ beforeMove = value.beforeMove || sortable.beforeMove,
+ afterMove = value.afterMove || sortable.afterMove,
+ options = value.options || sortable.options;
- //if allowDrop is an observable or a function, then execute it in a computed observable
- if (ko.isObservable(allowDrop) || typeof allowDrop == "function") {
- ko.computed({
- read: function() {
- var value = ko.utils.unwrapObservable(allowDrop),
- shouldAdd = typeof value == "function" ? value.call(this, templateOptions.foreach) : value;
- ko.utils.toggleDomNodeCssClass(element, connectClass, shouldAdd);
- },
- disposeWhenNodeIsRemoved: element
- }, this);
- } else {
- ko.utils.toggleDomNodeCssClass(element, connectClass, allowDrop);
- }
+ //if allowDrop is an observable or a function, then execute it in a computed observable
+ if (ko.isObservable(allowDrop) || typeof allowDrop == "function") {
+ ko.computed({
+ read: function() {
+ var value = ko.utils.unwrapObservable(allowDrop),
+ shouldAdd = typeof value == "function" ? value.call(this, templateOptions.foreach) : value;
+ ko.utils.toggleDomNodeCssClass(element, connectClass, shouldAdd);
+ },
+ disposeWhenNodeIsRemoved: element
+ }, this);
+ } else {
+ ko.utils.toggleDomNodeCssClass(element, connectClass, allowDrop);
+ }
- //attach meta-data
- $(element).data("ko_sortList", templateOptions.foreach);
- $(element).sortable(ko.utils.extend(options, {
- update: function(event, ui) {
- var sourceParent, targetParent, targetIndex, arg,
- item = ui.item.data("ko_sortItem");
+ //attach meta-data
+ $(element).data("ko_sortList", templateOptions.foreach);
+ $(element).sortable(ko.utils.extend(options, {
+ update: function(event, ui) {
+ var sourceParent, targetParent, targetIndex, arg,
+ item = ui.item.data("ko_sortItem");
- if (item) {
- //identify parents
- sourceParent = ui.item.data("ko_parentList");
- targetParent = ui.item.parent().data("ko_sortList");
- targetIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
+ if (item) {
+ //identify parents
+ sourceParent = ui.item.data("ko_parentList");
+ targetParent = ui.item.parent().data("ko_sortList");
+ targetIndex = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
- if (beforeMove || afterMove) {
- arg = {
- item: item,
- sourceParent: sourceParent,
- sourceIndex: sourceParent.indexOf(item),
- targetParent: targetParent,
- targetIndex: targetIndex,
- cancelDrop: false
- };
- }
+ if (beforeMove || afterMove) {
+ arg = {
+ item: item,
+ sourceParent: sourceParent,
+ sourceIndex: sourceParent.indexOf(item),
+ targetParent: targetParent,
+ targetIndex: targetIndex,
+ cancelDrop: false
+ };
+ }
- if (beforeMove) {
- beforeMove.call(this, arg, event, ui);
- if (arg.cancelDrop) {
- $(ui.sender).sortable('cancel');
- return;
- }
- }
+ if (beforeMove) {
+ beforeMove.call(this, arg, event, ui);
+ if (arg.cancelDrop) {
+ $(ui.sender).sortable('cancel');
+ return;
+ }
+ }
- if (targetIndex >= 0) {
- sourceParent.remove(item);
- targetParent.splice(targetIndex, 0, item);
- }
- //rendering is handled by manipulating the observableArray; ignore dropped element
- ui.item.remove();
+ if (targetIndex >= 0) {
+ sourceParent.remove(item);
+ targetParent.splice(targetIndex, 0, item);
+ }
+ //rendering is handled by manipulating the observableArray; ignore dropped element
+ ui.item.remove();
- //allow binding to accept a function to execute after moving the item
- if (afterMove) {
- afterMove.call(this, arg, event, ui);
- }
- }
- },
- connectWith: "." + connectClass
- }));
+ //allow binding to accept a function to execute after moving the item
+ if (afterMove) {
+ afterMove.call(this, arg, event, ui);
+ }
+ }
+ },
+ connectWith: "." + connectClass
+ }));
- //handle disposal
- ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
- $(element).sortable("destroy");
- });
- //we are wrapping the template binding
- return ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
- },
- update: function(element, valueAccessor, allBindingsAccessor, data, context) {
- var templateOptions = prepareTemplateOptions(valueAccessor);
+ //handle disposal
+ ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
+ $(element).sortable("destroy");
+ });
+ //we are wrapping the template binding
+ return ko.bindingHandlers.template.init(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
+ },
+ update: function(element, valueAccessor, allBindingsAccessor, data, context) {
+ var templateOptions = prepareTemplateOptions(valueAccessor);
- //call the actual template binding
- ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
- },
- afterRender: function(elements, data) {
- ko.utils.arrayForEach(elements, function(element) {
- if (element.nodeType === 1) {
- $(element).data("ko_sortItem", data);
- $(element).data("ko_parentList", $(element).parent().data("ko_sortList"));
- }
- });
- },
- connectClass: 'ko_container',
- allowDrop: true,
- afterMove: null,
- beforeMove: null,
- options: {}
-};
+ //call the actual template binding
+ ko.bindingHandlers.template.update(element, function() { return templateOptions; }, allBindingsAccessor, data, context);
+ },
+ afterRender: function(elements, data) {
+ ko.utils.arrayForEach(elements, function(element) {
+ if (element.nodeType === 1) {
+ $(element).data("ko_sortItem", data);
+ $(element).data("ko_parentList", $(element).parent().data("ko_sortList"));
+ }
+ });
+ },
+ connectClass: 'ko_container',
+ allowDrop: true,
+ afterMove: null,
+ beforeMove: null,
+ options: {}
+ };
})(ko, jQuery);
})
\ No newline at end of file