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.
334 lines
9.5 KiB
334 lines
9.5 KiB
2 years ago
|
<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>
|