You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							333 lines
						
					
					
						
							9.5 KiB
						
					
					
				
			
		
		
	
	
							333 lines
						
					
					
						
							9.5 KiB
						
					
					
				<html> | 
						|
<head> | 
						|
<title>Dojo Tree Widget Test (ajax, drag'n'drop and more)</title> | 
						|
 | 
						|
<script type="text/javascript"> | 
						|
	var djConfig = {isDebug: true }; | 
						|
</script> | 
						|
<script type="text/javascript" src="../../../dojo.js"></script> | 
						|
 | 
						|
<script type="text/javascript"> | 
						|
	dojo.require("dojo.lang.*"); | 
						|
	dojo.require("dojo.widget.Tree"); | 
						|
	dojo.require("dojo.widget.TreeRPCController"); | 
						|
	dojo.require("dojo.widget.TreeSelector"); | 
						|
	dojo.require("dojo.widget.TreeNode"); | 
						|
	dojo.require("dojo.widget.TreeContextMenu"); | 
						|
 | 
						|
	function restoreIconSrc() { | 
						|
		// icon was changed during the action => no need to move it back | 
						|
		//alert("Restore "+this.icon.src.substr(-18)) | 
						|
		if (this.icon.src.substr(-18) != 'static/loading.jpg') { // check if icon.src is loading icon | 
						|
			return; | 
						|
		} | 
						|
		this.icon.src = this.oldIconSrc; | 
						|
	} | 
						|
 | 
						|
 | 
						|
	/* process up or down operation */ | 
						|
	function moveClicked(selectedNode, controllerId, icon, direction) { | 
						|
		if (selectedNode.actionIsDisabled(selectedNode.actions.MOVE)) { | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		this.icon = icon; | 
						|
		this.oldIconSrc = icon.src; | 
						|
 | 
						|
		this.controller = dojo.widget.manager.getWidgetById(controllerId); | 
						|
 | 
						|
		if (!selectedNode) { | 
						|
			alert('No node selected'); | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		if (direction == 'up') { | 
						|
			if (!selectedNode.getPreviousSibling()) return; | 
						|
			var res = controller.move(selectedNode, selectedNode.parent, selectedNode.getParentIndex()-1); | 
						|
		} else if (direction == 'down') { | 
						|
			if (!selectedNode.getNextSibling()) return; | 
						|
			var res = controller.move(selectedNode, selectedNode.parent, selectedNode.getParentIndex()+1); | 
						|
		} | 
						|
 | 
						|
 | 
						|
	} | 
						|
 | 
						|
	/* process create operation */ | 
						|
	function createClicked(selectedNode, controllerId, icon) { | 
						|
		if (!selectedNode || selectedNode.actionIsDisabled(selectedNode.actions.ADDCHILD)) { | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		this.icon = icon; | 
						|
		this.oldIconSrc = icon.src; | 
						|
 | 
						|
		this.controller = dojo.widget.manager.getWidgetById(controllerId); | 
						|
 | 
						|
		if (!selectedNode || !selectedNode.isFolder) { | 
						|
			alert('Select folder please'); | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		this.icon.src = 'static/loading.jpg'; | 
						|
 | 
						|
		// I send some data to server and recieve feedback with right node | 
						|
		var res = controller.createChild(selectedNode, 0, { suggestedTitle: "New node" }, dojo.lang.hitch(this, restoreIconSrc)); | 
						|
 | 
						|
		// local checks failed | 
						|
		if (res == false) { | 
						|
			restoreIconSrc.apply(this); | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	function removeClicked(selectedNode, controllerId, icon) { | 
						|
 | 
						|
		if (!selectedNode) { | 
						|
			alert('No node selected'); | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		if (selectedNode.actionIsDisabled(selectedNode.actions.REMOVE)) { | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		this.icon = icon; | 
						|
		this.oldIconSrc = icon.src; | 
						|
 | 
						|
		this.controller = dojo.widget.manager.getWidgetById(controllerId); | 
						|
 | 
						|
 | 
						|
		this.icon.src = 'static/loading.jpg'; | 
						|
 | 
						|
		var res = controller.removeNode(selectedNode, dojo.lang.hitch(this, restoreIconSrc)); | 
						|
 | 
						|
		// local checks failed | 
						|
		if (res == false) { | 
						|
			restoreIconSrc.apply(this); | 
						|
		} | 
						|
 | 
						|
 | 
						|
	} | 
						|
 | 
						|
	var reporter = function(reporter) { | 
						|
		this.name = eventName; | 
						|
		this.go = function(message) { | 
						|
			var rep = [ reporter + " -- event: "+this.name ]; | 
						|
			for(i in message) rep.push(i+": "+message[i]); | 
						|
			dojo.debug(rep.join(', ')); | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	dojo.addOnLoad(function(){ | 
						|
 | 
						|
 | 
						|
		/* Add debug print for all controller events */ | 
						|
		var controller = dojo.widget.manager.getWidgetById('treeController'); | 
						|
		for(eventName in controller.eventNames) { | 
						|
			dojo.event.topic.subscribe( | 
						|
				controller.eventNames[eventName], | 
						|
				new reporter('controller'), | 
						|
				'go' | 
						|
			); | 
						|
		} | 
						|
 | 
						|
		/* Add debug print for all firstTree events */ | 
						|
		var firstTree = dojo.widget.manager.getWidgetById('firstTree'); | 
						|
 | 
						|
 | 
						|
		for(eventName in firstTree.eventNames) { | 
						|
			dojo.event.topic.subscribe( | 
						|
				firstTree.eventNames[eventName], | 
						|
				new reporter('firstTree'), | 
						|
				'go' | 
						|
			); | 
						|
		} | 
						|
 | 
						|
		/* Add debug print for all secondTree events */ | 
						|
		var secondTree = dojo.widget.manager.getWidgetById('secondTree'); | 
						|
		for(eventName in secondTree.eventNames) { | 
						|
			dojo.event.topic.subscribe( | 
						|
				secondTree.eventNames[eventName], | 
						|
				new reporter('secondTree'), | 
						|
				'go' | 
						|
			); | 
						|
		} | 
						|
 | 
						|
		//dojo.widget.manager.getWidgetById('1.1').edit({title: '123'}); | 
						|
 | 
						|
 | 
						|
	}); | 
						|
 | 
						|
 | 
						|
</script> | 
						|
 | 
						|
</head> | 
						|
<body> | 
						|
 | 
						|
 | 
						|
<div dojoType="TreeRPCController" RPCUrl="local" widgetId="treeController" DNDController="create"></div> | 
						|
 | 
						|
<div dojoType="TreeSelector" widgetId="treeSelector"></div> | 
						|
 | 
						|
 | 
						|
<div dojoType="TreeContextMenu" toggle="explode" contextMenuForWindow="false" widgetId="treeContextMenu"> | 
						|
	<div dojoType="TreeMenuItem" treeActions="addChild" iconSrc="static/createsmall.gif" widgetId="treeContextMenuCreate" caption="Create"></div> | 
						|
	<div dojoType="TreeMenuItem" treeActions="remove" iconSrc="static/removesmall.gif" caption="Remove" widgetId="treeContextMenuRemove"></div> | 
						|
	<div dojoType="TreeMenuItem" treeActions="move" iconSrc="static/downsmall.png" caption="Up" widgetId="treeContextMenuUp"></div> | 
						|
	<div dojoType="TreeMenuItem" treeActions="move" iconSrc="static/upsmall.png" caption="Down" widgetId="treeContextMenuDown"></div> | 
						|
</div> | 
						|
<script> | 
						|
 | 
						|
/* setup menu actrions */ | 
						|
dojo.addOnLoad(function() { | 
						|
 | 
						|
	dojo.event.topic.subscribe('treeContextMenuCreate/engage', | 
						|
		function (menuItem) { createClicked( menuItem.getTreeNode(), 'treeController',  menuItem.getTreeNode().expandIcon); } | 
						|
	); | 
						|
 | 
						|
	dojo.event.topic.subscribe('treeContextMenuRemove/engage', | 
						|
		function (menuItem) { removeClicked( menuItem.getTreeNode(), 'treeController',  menuItem.getTreeNode().expandIcon); } | 
						|
	); | 
						|
 | 
						|
	dojo.event.topic.subscribe('treeContextMenuUp/engage', | 
						|
		function (menuItem) { moveClicked( menuItem.getTreeNode(), 'treeController',  menuItem.getTreeNode().expandIcon, 'up'); } | 
						|
	); | 
						|
 | 
						|
	dojo.event.topic.subscribe('treeContextMenuDown/engage', | 
						|
		function (menuItem) { moveClicked( menuItem.getTreeNode(), 'treeController',  menuItem.getTreeNode().expandIcon, 'down'); } | 
						|
	); | 
						|
 | 
						|
 | 
						|
}); | 
						|
 | 
						|
 | 
						|
</script> | 
						|
 | 
						|
 | 
						|
 | 
						|
<style> | 
						|
#toolsDiv img { | 
						|
	vertical-align: middle; | 
						|
} | 
						|
.treeTable tr { | 
						|
	vertical-align: top; | 
						|
} | 
						|
</style> | 
						|
<!-- | 
						|
	A sample toolbar | 
						|
--> | 
						|
<div id="toolsDiv"> | 
						|
<img src="static/create.gif" onclick="createClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode,'treeController', this);"/> | 
						|
<img src="static/up.gif" onclick="moveClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode,'treeController', this, 'up');"/> | 
						|
<img src="static/down.gif" onclick="moveClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode,'treeController', this, 'down');"/> | 
						|
<img src="static/recyclebin.gif" onclick="removeClicked(dojo.widget.manager.getWidgetById('treeSelector').selectedNode, 'treeController', this);"/> | 
						|
 | 
						|
</div> | 
						|
<hr/> | 
						|
 | 
						|
 | 
						|
 | 
						|
<!-- | 
						|
	Every node must have widgetId to get recognized by server (ajax) | 
						|
	!!! wipe toggle from widget.Tree is buggy in FF (try open a lot of nodes) | 
						|
--> | 
						|
<table class="treeTable" cellpadding="10"> | 
						|
<tr> | 
						|
<td style="border:1px dashed black;"> | 
						|
<h4>firstTree</h4> | 
						|
 | 
						|
 | 
						|
 | 
						|
<div dojoType="Tree" menu="treeContextMenu" DNDMode="between" selector="treeSelector" actionsDisabled="addChild" toggler="fade" widgetId="firstTree" DNDAcceptTypes="secondTree" controller="treeController"> | 
						|
 | 
						|
    <div dojoType="TreeNode" widgetId="1.1" title="Can't remove me" actionsDisabled="remove"> | 
						|
 | 
						|
	<div dojoType="TreeNode" widgetId="1.1.1" title="<span style='color:blue'>node with HTML title</span>" isFolder="true"> | 
						|
	</div> | 
						|
 | 
						|
 | 
						|
    </div> | 
						|
 | 
						|
	<div dojoType="TreeNode" widgetId="1.2" title="Can't add child to me" actionsDisabled="addChild" isFolder="true"></div> | 
						|
	<div dojoType="TreeNode" widgetId="1.3" title="Can't move me" actionsDisabled="remove" isFolder="true"></div> | 
						|
 | 
						|
</div> | 
						|
</td> | 
						|
<td style="border:1px dashed black;"> | 
						|
<h4>secondTree</h4> | 
						|
<div dojoType="Tree" DNDMode="between" selector="treeSelector" widgetId="secondTree" DNDAcceptTypes="secondTree;firstTree"  controller="treeController"> | 
						|
 | 
						|
    <div dojoType="TreeNode" title="Item 2.1" widgetId="2.1" isFolder="true"></div> | 
						|
    <div dojoType="TreeNode" title="Item 2.2" widgetId="2.2" isFolder="true"></div> | 
						|
 | 
						|
</div> | 
						|
</td> | 
						|
</tr> | 
						|
</table> | 
						|
 | 
						|
 | 
						|
<hr> | 
						|
 | 
						|
<h3>Read the description first.<br/> | 
						|
Also, if something does not work, please read more carefully before reporting.</h3> | 
						|
 | 
						|
<ol> | 
						|
<li>Every node can be initially opened or closed. Also, some actions upon it may be disabled, you'll see that on demo</li> | 
						|
<li> | 
						|
You can <u>drag'n'drop a node</u> to change parent | 
						|
<ul> | 
						|
<li>FirstTree accepts only sources from secondTree, secondTree accepts both (for demo purposes)</li> | 
						|
<li>You can only drop to folder ("+/-" sign)</li> | 
						|
<li>You can't drop an ancestor to any of its descenants</li> | 
						|
<li>You can't drop a child to its closest parent</li> | 
						|
<li>A node is highlighted if you can drop onto it</li> | 
						|
<li>There are two DnD modes: "between" and "onto". Between is used in the demo.</li> | 
						|
<li>Nodes autoexpand on dragOver after delay</li> | 
						|
</ul> | 
						|
</li> | 
						|
 | 
						|
<li> | 
						|
<u>Move nodes up and down, remove them</u> by selecting and pressing tool buttons. | 
						|
You surely can't move top nodes higher and bottom nodes lower. | 
						|
</li> | 
						|
 | 
						|
<li> | 
						|
<u>You can create nodes</u> by clicking create button. | 
						|
<ul> | 
						|
<li>Currently only simple same nodes are created, but this can be changed easily.</li> | 
						|
<li>Nodes are created on top for convinience.</li> | 
						|
</ul> | 
						|
</li> | 
						|
 | 
						|
<li>All editing operations use <u>server requests(ajax)</u> | 
						|
<ul> | 
						|
 | 
						|
<li>Empty folders get loaded dynamically.</li> | 
						|
<li>In this demo "test" node can be expanded infinitely (from server).</li> | 
						|
<li>Remote communication process is indicated.</li> | 
						|
</ul> | 
						|
</li> | 
						|
 | 
						|
<li>FirstTree has <u>context menu</u> (right-click on node), attached using events. | 
						|
Its main functionality inherits dojo.widget.PopupMenu2.</li> | 
						|
 | 
						|
<li> | 
						|
A bunch of <u>events</u> is fired by both tree and controller to simplify integration. | 
						|
</li> | 
						|
 | 
						|
 | 
						|
 | 
						|
<li> | 
						|
<b>Yes, it is OpenSource, and yes, you are free to use & contribute to it.</b> | 
						|
</li> | 
						|
 | 
						|
</ol> | 
						|
 | 
						|
<p align="right">Ilia Kantor, ilia at manual dot ru</p> | 
						|
 | 
						|
<hr> | 
						|
 | 
						|
<h4>Here go debug messages</h4> | 
						|
 | 
						|
 | 
						|
</body> | 
						|
</html>
 | 
						|
 |