Index: dojo-release-1.3.2-src/dijit/Tree.js =================================================================== --- dojo-release-1.3.2-src.orig/dijit/Tree.js 2009-11-11 14:53:30.000000000 -0800 +++ dojo-release-1.3.2-src/dijit/Tree.js 2009-11-16 10:19:58.000000000 -0800 @@ -7,6 +7,7 @@ dojo.require("dijit._Container"); dojo.require("dijit._Contained"); dojo.require("dojo.cookie"); +dojo.require("dijit.InlineEditBox"); dojo.declare( "dijit._TreeNode", @@ -44,6 +45,11 @@ // will not fire. isSelectable: true, + // isEditable: Boolean + // If false, node will not be editable + // will not fire. + isEditable: false, + // state: [private] String // Dynamic loading-related stuff. // When an empty folder node appears, it is "UNCHECKED" first, @@ -273,6 +279,7 @@ tree: tree, isExpandable: model.mayHaveChildren(item), isSelectable: tree.getSelectable(item), + isEditable: tree.getEditable(item), label: tree.getLabel(item), indent: this.indent + 1 }); @@ -394,6 +401,53 @@ // private dojo.removeClass(this.rowNode, "dijitTreeNodeHover"); this.tree._onNodeMouseLeave(this, evt); + }, + + edit: function(kwArgs){ + if(!this.isEditable){ + //console.debug(this.id+"::edit node is not editable"); + return; + } + kwArgs = dojo.mixin({ + onChange: function(){}, + onCancel: function(){}, + width: "12em", + scope: dojo.global + }, kwArgs || {}); + var labelNode = this.labelNode; + var editSpan = document.createElement('span'); + editSpan.innerHTML = labelNode.innerHTML; + labelNode.innerHTML = ""; + labelNode.appendChild(editSpan); + var editor = null; + + var destroyEditor = dojo.hitch(this, function(){ + this.labelNode.innerHTML = editor.displayNode.innerHTML; + editor.destroy(); + this.tree.isEditing = false; + setTimeout(dojo.hitch(this, function(){ + this.tree.focusNode(this); + }), 0); + }); + + editor = new dijit.InlineEditBox({ + autoSave: true, + onChange: dojo.hitch(this, function(val){ + //console.debug("InlineEditBox::onChange"); + this.tree.setLabel(this.item, val); + destroyEditor(); + kwArgs.onChange.call(kwArgs.scope, this.item, val); + }), + onCancel: dojo.hitch(this, function(){ + //console.debug("InlineEditBox::onCancel"); + destroyEditor(); + kwArgs.onCancel.call(kwArgs.scope, this.item); + }), + width: kwArgs.width + }, editSpan); + editor.startup(); + editor.edit(); + this.tree.isEditing = true; } }); @@ -457,6 +511,10 @@ // TODO: this appears to be vestigal. Remove. isTree: true, + // isEditing: [protected] + // Used to flag internal state when a node is being edited. + isEditing: false, + // persist: Boolean // Enables/disables use of cookies for state saving. persist: true, @@ -630,6 +688,7 @@ tree: this, isExpandable: true, isSelectable: this.getSelectable(item), + isEditable: this.getEditable(item), label: this.label || this.getLabel(item), indent: this.showRoot ? 0 : -1 }); @@ -685,6 +744,14 @@ return this.model.getLabel(item); // String }, + setLabel: function(/*dojo.data.Item*/ item, label){ + // summary: + // Overridable function to set the label for a tree node (given the item) + // tags: + // extension + return this.model.setLabel(item, label); + }, + getIconClass: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){ // summary: // Overridable function to return CSS class name to display icon @@ -728,6 +795,17 @@ return this.model.getSelectable(item); }, + getEditable: function(/*dojo.data.Item*/ item){ + // summary: + // Overridable function to determine if the item's node is editable. + // By default all the nodes are non-editable + // returns: + // Boolean + // tags: + // extension + return this.model.getEditable(item); + }, + _itemsEqual: function(/*dojo.data.Item[]*/){ // summary: // Compares all argument's model identity against each other @@ -804,6 +882,7 @@ _onKeyPress: function(/*Event*/ e){ // summary: // Translates keypress events into commands for the controller + if(this.isEditing){ return; } if(e.altKey){ return; } var dk = dojo.keys; var treeNode = dijit.getEnclosingWidget(e.target); Index: dojo-release-1.3.2-src/dijit/tree/model.js =================================================================== --- dojo-release-1.3.2-src.orig/dijit/tree/model.js 2009-11-11 14:53:30.000000000 -0800 +++ dojo-release-1.3.2-src/dijit/tree/model.js 2009-11-11 15:07:23.000000000 -0800 @@ -71,6 +71,13 @@ // tags: // extension }, + + getEditable: function(/*dojo.data.Item*/ item){ + // summary: + // Get the editability of an item + // tags: + // extension + }, // ======================================================================= // Write interface @@ -91,6 +98,13 @@ // tags: // extension }, + + setLabel: function(/*dojo.data.Item*/ item, /* String */ val){ + // summary: + // Set what represents the label after it has been edited. + // tags: + // extension + }, // ======================================================================= // Callbacks Index: dojo-release-1.3.2-src/dijit/tree/TreeStoreModel.js =================================================================== --- dojo-release-1.3.2-src.orig/dijit/tree/TreeStoreModel.js 2009-11-11 14:53:30.000000000 -0800 +++ dojo-release-1.3.2-src/dijit/tree/TreeStoreModel.js 2009-11-11 15:07:23.000000000 -0800 @@ -25,6 +25,11 @@ // selectableAttr: String // Default attribute used to determine if items are selectable selectableAttr: "selectable", + + // editableAttr: String + // Default attribute used to determine if items are editable + editableAttr: "editable", + // root: [readonly] dojo.data.Item // Pointer to the root item (read only, not a parameter) @@ -168,6 +173,13 @@ return selectable === undefined ? true : selectable; // Boolean }, + getEditable: function(/*dojo.data.Item*/ item){ + // summary: + // Get the editability of an item + var editable = this.store.getValue(item,this.editableAttr); + return editable === undefined ? false : editable; // Boolean + }, + // ======================================================================= // Write interface