Tutorial Dojo - Le widget "Tree" et ses évènements

TODO : index avec ancres

Présentation

Le widget Tree permet de représenter une structure arborescente sous la forme d'un arbre graphique dont les noeuds peuvent être ouverts et fermés.

Ces arbres permettent le drag'n'drop de noeud dans le même arbre ou dans un autre arbre, l'enregistrement de différents listener sur des événements tels que la suppression d'un noeud, le depplacement d'un, la selection d'un noeud. Ces arbres peuvent aussi bien être definit en HTML q'en pur javascript

La définition d'un arbre

Nous allons voir dans cette partie comment definir un arbre par le HTML ou entierement programmatiquement en javascript

Définition d'un arbre via des balises HTML

Les arbres se definissent avec Dojo de la même façon que n'importe quel widget : voir l'exemple

<html>
	<head>
		<script type="text/javascript" src="../../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//tous ce que l'on a besoin
			dojo.require("dojo.lang.*");
			dojo.require("dojo.widget.*");
			dojo.require("dojo.widget.Tree");
		</script>
	</head>
	<body>
	
		
		<div dojoType="Tree"toggle="fade">
			<div dojoType="TreeNode" title="Item 1">
				<div dojoType="TreeNode" title="Item 1.1" ></div>
				<div dojoType="TreeNode" title="Item 1.2" >
					<div dojoType="TreeNode" title="Item 1.2.1" >
						<div dojoType="TreeNode" title="Item 1.2.1.1" ></div>
					</div>
					<div dojoType="TreeNode" title="Item 1.2.2" ></div>
		
				</div>
				<div dojoType="TreeNode" title="Item 1.3" >
					<div dojoType="TreeNode" title="Item 1.3.1" ></div>
					<div dojoType="TreeNode" title="Item 1.3.2" ></div>
				</div>
				<div dojoType="TreeNode" title="Item 1.4" >
					<div dojoType="TreeNode" title="Item 1.4.1" ></div>
				</div>
			</div>
		
			<div dojoType="TreeNode" title="Item 2" ></div>
		</div>
	</body>
</html>
						

Ainsi un arbre est représenté en HTML par une div de DojoType:Tree suivi d'un ensemble de div herachique représentant chaque noeud de type DojoType:TreeNode

Notons que c'est l'attribut tilte qui definit le nom du noeud. D'un autre coté chaque noeud doit être défini par une balise ouvrante puis une fermante (<div dojoType="TreeNode" title="Item 1.4.1" ></div>). Les déclarations courtes (<div dojoType="TreeNode" title="Item 1.4.1" />) provoquent une erreur

Définition d'un arbre de façon programmatique

Tout widget Dojo peut être crée de façon programatique (plus ou moins facilement) via la methode dojo.widget.createWidget. Les widgets Tree et TreeNode sont particulierement bien adaptées pour ce genre de création. En effet ils fournissent les méthodes suivantes permettant de gérer les noeuds :

Les TreeNode on beaucoup d'autre fonctions qui peuvent être interressantes: voir l'exmple

<html>
	<head>
		<script type="text/javascript" src="../../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//tous ce que l'on a besoin
			dojo.require("dojo.lang.*");
			dojo.require("dojo.widget.*");
			dojo.require("dojo.widget.Tree");
			
			//on le cree au chargement de la page
			dojo.addOnLoad(function(){
				var tree = dojo.widget.createWidget("Tree", {toggle: "wipe", expandLevel: 2});
				//on le cree directement à la racine du tag body
				document.body.appendChild(tree.domNode);
				
				var rootNode = dojo.widget.createWidget("TreeNode", {title: "Root Node"});
				tree.addChild(rootNode);
		
				var node1 = dojo.widget.createWidget("TreeNode", {title: "Node 1"});
				rootNode.addChild(node1);
		
				var node2 = dojo.widget.createWidget("TreeNode", {title: "Node 2"});
				node1.addChild(node2);
		
				rootNode.addChild(dojo.widget.createWidget("TreeNode", {title: "Node 2"}));
				var node3 = dojo.widget.createWidget("TreeNode", {title: "Node 3"});
				rootNode.addChild(node3);
				var node3_1 = dojo.widget.createWidget("TreeNode", {title: "Node 3.1"});
				node3.addChild(node3_1);
				node3_1.addChild(dojo.widget.createWidget("TreeNode", {title: "Node 3.1.1"}))
		
		
				//allé on s'amuse un peu et on cré tout un tas de noeud
				for(var i=1;i<5;i++) {
					node1.addChild(dojo.widget.createWidget("TreeNode", {title: "Node 1."+i}));
				}
		
				tree.addChild(dojo.widget.createWidget("TreeNode", {title: "Root Node 2"}));
				
				rootNode.expand();

			});
		</script>
	</head>
	<body>
	
	
	</body>
</html>
						

Quelques possibilités de modifications graphiques

Des customizations sont possibles sur les arbres, comme par exemple la le mise en place d'icones sur les noeuds ainsi que l'écriture de label dans l'arbre en html. voir l'exemple

<html>
	<head>
		<script type="text/javascript" src="../../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//tous ce que l'on a besoin
			dojo.require("dojo.lang.*");
			dojo.require("dojo.widget.*");
			dojo.require("dojo.widget.Tree");
		</script>
	</head>
	<body>
	
		
		<div dojoType="Tree"toggle="fade">
			<div dojoType="TreeNode" title="<i style='color:red'>Item 1</i>">
				<div dojoType="TreeNode" title="Item 1.1" ></div>
				<div dojoType="TreeNode" title="Item 1.2" >
					<div dojoType="TreeNode" title="Item 1.2.1" >
						<div dojoType="TreeNode" title="Item 1.2.1.1" ></div>
					</div>
					<div dojoType="TreeNode" title="Item 1.2.2" ></div>
		
				</div>
				<div dojoType="TreeNode" title="Item 1.3" >
					<div dojoType="TreeNode" title="Item 1.3.1" ></div>
					<div dojoType="TreeNode" title="Item 1.3.2" ></div>
				</div>
				<div dojoType="TreeNode" title="Item 1.4" >
					<div dojoType="TreeNode" title="Item 1.4.1" ></div>
				</div>
			</div>
		
			<div dojoType="TreeNode" childIconSrc="check_on.gif" title="Item 2" ></div>
		</div>
	</body>
</html>
					

Le Drag'n'Drop

TODO : les explications voir l'exemple

<html>
	<head>
		<script type="text/javascript" src="../../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//tous ce que l'on a besoin
			dojo.require("dojo.lang.*");
			dojo.require("dojo.widget.*");
			dojo.require("dojo.widget.Tree");
			dojo.hostenv.writeIncludes();;
		
			dojo.addOnLoad(function() {
							
				//ajout d'un listener à la suppression d'un noeud
				dojo.event.topic.subscribe("nodeRemoved",
					 function(message) {
					 	alert(message.child.title +" enlevé de "+ message.oldParent.title + " dans l'arbre " + message.oldTree.widgetId); 
					 }
				);
				
				//il n'est pas possible de spécifier un listener sur un noeud seul!
			});
		</script>
	</head>
	<body>
	
		<div dojoType="Tree" DNDMode="onto" toggle="fade" DNDAcceptTypes="firstTree" widgetId="firstTree" eventNames="moveTo:nodeRemoved">
		    <div dojoType="TreeNode" title="Item 1">
		        <div dojoType="TreeNode" title="Item 1.1"><br/></div>
		        <div dojoType="TreeNode" title="Item 1.2">
		            <div dojoType="TreeNode" title="Item 1.2.1"></div>
		            <div dojoType="TreeNode" title="Item 1.2.2"></div>
		        </div>
		
		        <div dojoType="TreeNode" title="Can't add child to this node" actionsDisabled="addChild">
		            <div dojoType="TreeNode" isFolder="true" title="Empty folder"></div>
		            <div dojoType="TreeNode" title="Item 1.3.2"></div>
		        </div>
		        <div dojoType="TreeNode" title="Item 1.4">
		            <div dojoType="TreeNode" title="Item 1.4.1"></div>
		        </div>
			<div dojoType="TreeNode" actionsDisabled="move" title="Can't move this node"></div>
		    </div>
		
		</div>

		<hr/>
		<div dojoType="Tree" DNDMode="onto" toggle="wipe" DNDAcceptTypes="firstTree;secondTree" widgetId="secondTree">
		    <div dojoType="TreeNode" title="Node 1"></div>
		    <div dojoType="TreeNode" title="Node 2">
		        <div dojoType="TreeNode" isFolder="true" title="Node 2.1"></div>
		        <div dojoType="TreeNode" title="Node 2.2"></div>
		    </div>
		</div>
		
	</body>
</html>