]> source.dussan.org Git - archiva.git/commitdiff
[MRM-1576] rewrite proxies connector page
authorOlivier Lamy <olamy@apache.org>
Mon, 13 Feb 2012 13:55:09 +0000 (13:55 +0000)
committerOlivier Lamy <olamy@apache.org>
Mon, 13 Feb 2012 13:55:09 +0000 (13:55 +0000)
add sortable knockout binding.

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1243512 13f79535-47bb-0310-9956-ffa450edef68

archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/knockout-sortable.js [new file with mode: 0644]

diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/knockout-sortable.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/knockout-sortable.js
new file mode 100644 (file)
index 0000000..ec928b1
--- /dev/null
@@ -0,0 +1,137 @@
+//knockout-sortable | (c) 2012 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license
+(function(ko, $, undefined) {
+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();
+    }
+
+    //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;
+};
+
+//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);
+        }
+
+        //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 (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 (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
+        }));
+
+        //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: {}
+};
+})(ko, jQuery);
\ No newline at end of file