mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5282 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
309 lines
6.9 KiB
JavaScript
309 lines
6.9 KiB
JavaScript
/*
|
|
Copyright (c) 2004-2006, The Dojo Foundation
|
|
All Rights Reserved.
|
|
|
|
Licensed under the Academic Free License version 2.1 or above OR the
|
|
modified BSD license. For more information on Dojo licensing, see:
|
|
|
|
http://dojotoolkit.org/community/licensing.shtml
|
|
*/
|
|
|
|
|
|
dojo.provide("dojo.widget.TreeSelectorV3");
|
|
|
|
dojo.require("dojo.widget.HtmlWidget");
|
|
dojo.require("dojo.widget.TreeCommon");
|
|
|
|
dojo.widget.defineWidget(
|
|
"dojo.widget.TreeSelectorV3",
|
|
[dojo.widget.HtmlWidget, dojo.widget.TreeCommon],
|
|
function() {
|
|
this.eventNames = {};
|
|
this.listenedTrees = {};
|
|
this.selectedNodes = [];
|
|
this.lastClicked = {}
|
|
},
|
|
{
|
|
// TODO: add multiselect
|
|
|
|
listenTreeEvents: ["afterTreeCreate","afterCollapse","afterChangeTree", "afterDetach", "beforeTreeDestroy"],
|
|
listenNodeFilter: function(elem) { return elem instanceof dojo.widget.Widget},
|
|
|
|
allowedMulti: true,
|
|
|
|
/**
|
|
* if time between clicks < dblselectTimeout => its dblselect
|
|
*/
|
|
dblselectTimeout: 300,
|
|
|
|
eventNamesDefault: {
|
|
select : "select",
|
|
deselect : "deselect",
|
|
dblselect: "dblselect" // select already selected node.. Edit or whatever
|
|
},
|
|
|
|
onAfterTreeCreate: function(message) {
|
|
var tree = message.source;
|
|
dojo.event.browser.addListener(tree.domNode, "onclick", dojo.lang.hitch(this, this.onTreeClick));
|
|
if (dojo.render.html.ie) {
|
|
dojo.event.browser.addListener(tree.domNode, "ondblclick", dojo.lang.hitch(this, this.onTreeDblClick));
|
|
}
|
|
dojo.event.browser.addListener(tree.domNode, "onKey", dojo.lang.hitch(this, this.onKey));
|
|
|
|
},
|
|
|
|
|
|
onKey: function(e) {
|
|
if (!e.key || e.ctrkKey || e.altKey) { return; }
|
|
|
|
switch(e.key) {
|
|
case e.KEY_ENTER:
|
|
var node = this.domElement2TreeNode(e.target);
|
|
if (node) {
|
|
this.processNode(node, e);
|
|
}
|
|
|
|
}
|
|
},
|
|
|
|
|
|
|
|
onAfterChangeTree: function(message) {
|
|
|
|
if (!message.oldTree && message.node.selected) {
|
|
this.select(message.node);
|
|
}
|
|
|
|
if (!message.newTree || !this.listenedTrees[message.newTree.widgetId]) {
|
|
// moving from our trfee to new one that we don't listen
|
|
|
|
if (this.selectedNode && message.node.children) {
|
|
this.deselectIfAncestorMatch(message.node);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
initialize: function(args) {
|
|
|
|
for(name in this.eventNamesDefault) {
|
|
if (dojo.lang.isUndefined(this.eventNames[name])) {
|
|
this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name];
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
onBeforeTreeDestroy: function(message) {
|
|
this.unlistenTree(message.source);
|
|
},
|
|
|
|
// deselect node if ancestor is collapsed
|
|
onAfterCollapse: function(message) {
|
|
this.deselectIfAncestorMatch(message.source);
|
|
},
|
|
|
|
// IE will throw select -> dblselect. Need to transform to select->select
|
|
onTreeDblClick: function(event) {
|
|
this.onTreeClick(event);
|
|
},
|
|
|
|
checkSpecialEvent: function(event) {
|
|
return event.shiftKey || event.ctrlKey;
|
|
},
|
|
|
|
|
|
onTreeClick: function(event) {
|
|
|
|
var node = this.domElement2TreeNode(event.target);
|
|
|
|
if (!node) {
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
var checkLabelClick = function(domElement) {
|
|
return domElement === node.labelNode;
|
|
}
|
|
|
|
if (this.checkPathCondition(event.target, checkLabelClick)) {
|
|
this.processNode(node, event);
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
/**
|
|
* press on selected with ctrl => deselect it
|
|
* press on selected w/o ctrl => dblselect it and deselect all other
|
|
*
|
|
* press on unselected with ctrl => add it to selection
|
|
*
|
|
* event may be both mouse & keyboard enter
|
|
*/
|
|
processNode: function(node, event) {
|
|
|
|
if (node.actionIsDisabled(node.actions.SELECT)) {
|
|
return;
|
|
}
|
|
|
|
//dojo.debug("click "+node+ "special "+this.checkSpecialEvent(event));
|
|
|
|
if (dojo.lang.inArray(this.selectedNodes, node)) {
|
|
|
|
if(this.checkSpecialEvent(event)){
|
|
// If the node is currently selected, and they select it again while holding
|
|
// down a meta key, it deselects it
|
|
this.deselect(node);
|
|
return;
|
|
}
|
|
|
|
var _this = this;
|
|
var i=0;
|
|
var selectedNode;
|
|
|
|
/* remove all nodes from selection excepts this one */
|
|
while(this.selectedNodes.length > i) {
|
|
selectedNode = this.selectedNodes[i];
|
|
if (selectedNode !== node) {
|
|
//dojo.debug("Deselect "+selectedNode);
|
|
this.deselect(selectedNode);
|
|
continue;
|
|
}
|
|
|
|
i++; // skip the doubleclicked node
|
|
}
|
|
|
|
/* lastClicked.node may be undefined if node was selected(before) programmatically */
|
|
var wasJustClicked = this.checkRecentClick(node)
|
|
|
|
eventName = wasJustClicked ? this.eventNames.dblselect : this.eventNames.select;
|
|
if (wasJustClicked) {
|
|
eventName = this.eventNames.dblselect;
|
|
/* after dblselect, next select is usual select */
|
|
this.forgetLastClicked();
|
|
} else {
|
|
eventName = this.eventNames.select;
|
|
this.setLastClicked(node)
|
|
}
|
|
|
|
dojo.event.topic.publish(eventName, { node: node });
|
|
|
|
return;
|
|
}
|
|
|
|
/* if unselected node.. */
|
|
|
|
this.deselectIfNoMulti(event);
|
|
|
|
//dojo.debug("select");
|
|
|
|
this.setLastClicked(node);
|
|
|
|
this.select(node);
|
|
|
|
},
|
|
|
|
forgetLastClicked: function() {
|
|
this.lastClicked = {}
|
|
},
|
|
|
|
setLastClicked: function(node) {
|
|
this.lastClicked.date = new Date();
|
|
this.lastClicked.node = node;
|
|
},
|
|
|
|
checkRecentClick: function(node) {
|
|
var diff = new Date() - this.lastClicked.date;
|
|
//dojo.debug(new Date())
|
|
//dojo.debug("check old "+this.lastClicked.node+" now "+(new Date())+" diff "+diff)
|
|
if (this.lastClicked.node && diff < this.dblselectTimeout) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
// deselect all if no meta key or disallowed
|
|
deselectIfNoMulti: function(event) {
|
|
if (!this.checkSpecialEvent(event) || !this.allowedMulti) {
|
|
//dojo.debug("deselect All");
|
|
this.deselectAll();
|
|
}
|
|
},
|
|
|
|
deselectIfAncestorMatch: function(ancestor) {
|
|
/* deselect all nodes with this ancestor */
|
|
var _this = this;
|
|
dojo.lang.forEach(this.selectedNodes, function(node) {
|
|
var selectedNode = node;
|
|
node = node.parent
|
|
while (node && node.isTreeNode) {
|
|
//dojo.debug("ancestor try "+node);
|
|
|
|
if (node === ancestor) {
|
|
_this.deselect(selectedNode);
|
|
return;
|
|
}
|
|
node = node.parent;
|
|
}
|
|
});
|
|
},
|
|
|
|
|
|
|
|
|
|
onAfterDetach: function(message) {
|
|
this.deselectIfAncestorMatch(message.child);
|
|
},
|
|
|
|
|
|
select: function(node) {
|
|
|
|
var index = dojo.lang.find(this.selectedNodes, node, true);
|
|
|
|
if (index >=0 ) {
|
|
return; // already selected
|
|
}
|
|
|
|
//dojo.debug("select "+node);
|
|
this.selectedNodes.push(node);
|
|
|
|
dojo.event.topic.publish(this.eventNames.select, {node: node} );
|
|
},
|
|
|
|
|
|
deselect: function(node){
|
|
var index = dojo.lang.find(this.selectedNodes, node, true);
|
|
if (index < 0) {
|
|
//dojo.debug("not selected");
|
|
return; // not selected
|
|
}
|
|
|
|
//dojo.debug("deselect "+node);
|
|
//dojo.debug((new Error()).stack);
|
|
|
|
this.selectedNodes.splice(index, 1);
|
|
dojo.event.topic.publish(this.eventNames.deselect, {node: node} );
|
|
//dojo.debug("deselect");
|
|
|
|
},
|
|
|
|
deselectAll: function() {
|
|
//dojo.debug("deselect all "+this.selectedNodes);
|
|
while (this.selectedNodes.length) {
|
|
this.deselect(this.selectedNodes[0]);
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|