1) implemented working replace mode 2) autocreate new tree on launch if needed
authorsenator <lebbeous@esilibrary.com>
Fri, 15 Apr 2011 16:02:07 +0000 (12:02 -0400)
committerBill Erickson <berick@esilibrary.com>
Wed, 6 Jul 2011 18:50:49 +0000 (14:50 -0400)
Open-ILS/web/js/dojo/openils/vandelay/TreeDndSource.js
Open-ILS/web/js/dojo/openils/vandelay/TreeStoreModel.js
Open-ILS/web/js/dojo/openils/vandelay/nls/match_set.js
Open-ILS/web/js/ui/default/vandelay/match_set.js
Open-ILS/web/templates/default/vandelay/match_set_tree.tt2

index 8ccd836..832ef6f 100644 (file)
@@ -7,12 +7,15 @@ dojo.require("dijit._tree.dndSource");
  */
 dojo.declare(
     "openils.vandelay.TreeDndSource", dijit._tree.dndSource, {
-        "_is_replaceable": function(src_item, target_item) {
+        "_is_replaceable": function(spoint, dpoint) {
             /* An OP can replace anything, but non-OPs can only replace other
              * non-OPs
              */
-            console.log("src item: " + src_item + " target item: " + target_item);
-            return true;    /* XXX TODO FINISHME */
+            if (spoint.bool_op())
+                return true;
+            else if (!dpoint.bool_op())
+                return true;
+            return false;
         },
         "constructor": function() {
             /* Given a tree object, there seems to be no way to access its
@@ -28,11 +31,14 @@ dojo.declare(
         "checkItemAcceptance": function(target, source, position) {
             if (!source._ready || source == this) return;
 
-            if (this.tree.model._replace_mode) {
+            if (this.tree.model.replace_mode) {
                 return (
                     position == "over" && this._is_replaceable(
                         source.getAllNodes()[0].match_point,
-                        dijit.getEnclosingWidget(target).item.match_point
+                        this.tree.model.store.getValue(
+                            dijit.getEnclosingWidget(target).item,
+                            "match_point"
+                        )
                     )
                 );
             } else {
@@ -47,12 +53,45 @@ dojo.declare(
              * only when we want the item to be draggable */
         },
         "itemCreator": function(nodes, somethingelse) {
-            console.log("gew: " + dijit.getEnclosingWidget(somethingelse).item.name);
-            console.log("dojo.dnd.manager.copy: " + dojo.dnd.manager.copy);
             var default_items = this.inherited(arguments);
             for (var i = 0; i < default_items.length; i++)
                 default_items[i].match_point = nodes[i].match_point;
             return default_items;
+        },
+        "onDndDrop": function(source, nodes, copy) {
+            if (
+                !this.tree.model.replace_mode ||
+                this.containerState != "Over" ||
+                this.dropPosition == "Before" ||
+                this.dropPosition == "After" ||
+                source == this
+            ) {
+                return this.inherited(arguments);
+            }
+
+            /* This method only comes into play for our "replace mode" */
+
+            var target_widget = dijit.getEnclosingWidget(this.targetAnchor);
+            var new_params = this.itemCreator(nodes, this.targetAnchor)[0];
+
+            /* Here, we morph target_widget.item into the new item */
+
+            var store = this.tree.model.store;
+            var item = target_widget.item;
+            for (var k in new_params) {
+                if (k == "id") continue;    /* can't use this / don't need it */
+                store.setValue(item, k, new_params[k]);
+            }
+            if (typeof(window.render_vmsp_label) == "function") {
+                store.setValue(
+                    item,
+                    "name",
+                    window.render_vmsp_label(new_params.match_point)
+                );
+            }
+
+            /* just because this is at the end of the default implementation: */
+            this.onDndCancel();
         }
     }
 );
index 2a35b70..af26d09 100644 (file)
@@ -19,7 +19,7 @@ function _simple_item(model, item) {
 
 dojo.declare(
     "openils.vandelay.TreeStoreModel", dijit.tree.TreeStoreModel, {
-        "_replace_mode": 0,
+        "replace_mode": 0,
         "getSimpleTree": function(item, oncomplete, result) {
             var self = this;
             if (!result) result = {};
index ceb72bb..30132e3 100644 (file)
@@ -3,5 +3,6 @@
     "LEAVE_ROOT_ALONE": "You cannot delete the root node of a tree (but you can replace it).",
     "EXACTLY_ONE": "First select exactly one node from the tree on the right side of the screen.",
     "EXIT_REPLACE_MODE": "Exit Replace Mode",
-    "ENTER_REPLACE_MODE": "Enter Replace Mode"
+    "ENTER_REPLACE_MODE": "Enter Replace Mode",
+    "NO_CAN_DO": "An error has occurred. Close this interface and try again."
 }
index f9fa8ec..20fb624 100644 (file)
@@ -208,14 +208,21 @@ function render_vmsp_label(point) {
     }
 }
 
-function replace_mode() {
-    tree.model._replace_mode ^= 1;
+function replace_mode(explicit) {
+    if (typeof explicit == "undefined")
+        tree.model.replace_mode ^= 1;
+    else
+        tree.model.replace_mode = explicit;
+
     dojo.attr(
         "replacer", "innerHTML",
         localeStrings[
-            (tree.model._replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
+            (tree.model.replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
         ]
     );
+    dojo[tree.model.replace_mode ? "addClass" : "removeClass"](
+        "replacer", "replace-mode"
+    );
 }
 
 function delete_selected_in_tree() {
@@ -231,6 +238,19 @@ function delete_selected_in_tree() {
     );
 }
 
+function new_match_set_tree() {
+    var point = new vmsp();
+    point.bool_op("AND");
+    return [
+        {
+            "id": "root",
+            "children": [],
+            "name": render_vmsp_label(point),
+            "match_point": point
+        }
+    ];
+}
+
 /* dojoize_match_set_tree() takes an argument, "point", that is actually a
  * vmsp fieldmapper object with descendants fleshed hierarchically. It turns
  * that into a syntactically flat array but preserving the hierarchy
@@ -247,6 +267,9 @@ function dojoize_match_set_tree(point, refgen) {
     /* XXX TODO test with deeper trees! */
     var root = false;
     if (!refgen) {
+        if (!point) {
+            return new_match_set_tree();
+        }
         refgen = 0;
         root = true;
     }
@@ -292,6 +315,12 @@ function my_init() {
     pcrud = new openils.PermaCrud();
     CGI = new openils.CGI();
 
+    if (!CGI.param("match_set")) {
+        alert(localeStrings.NO_CAN_DO);
+        progress_dialog.hide();
+        return;
+    }
+
     var match_set = pcrud.retrieve("vms", CGI.param("match_set"));
     render_match_set_description(match_set);
 
@@ -331,6 +360,8 @@ function my_init() {
 
     node_editor = new NodeEditor(src, "node-editor-container");
 
+    replace_mode(0);
+
     dojo.connect(
         src, "onDndDrop", null,
         function(source, nodes, copy, target) {
index 06f1679..f8572e9 100644 (file)
@@ -15,6 +15,7 @@
     .node-editor { margin-bottom: 1.5ex; }
     .node-editor td { padding: 0.5ex; }
     li { background-color: #ddd; }
+    .replace-mode { background-color: #990; color: #fff; }
 </style>
 <h1>[% ctx.page_title %]</h1>
 <table id="vms-table">
@@ -85,9 +86,7 @@
             <button id="deleter" onclick="delete_selected_in_tree()">
                 Delete Selected Node
             </button>
-            <button id="replacer" onclick="replace_mode()">
-                Enter Replace Mode
-            </button>
+            <button id="replacer" onclick="replace_mode()"></button>
         </div>
     </div>
 </div>