Tutorial Dojo

par Vincent Demay

Présentation
Mise en place
Les concepts de base de Dojo
      La notion de classe
            Un exemple avant de commencer
            Ecrire une nouvelle classe
            La notion d'heritage
      Les classes principales définies dans Dojo
            Les librairies principales
            La Gestion des données
            Autres packages
            Animation, DnD, validation et widgets
      Le debugger de Dojo
Dojo et AJAX
      AJAX c'est quoi
      Mise en place d'une communication client/serveur asynchrone
Les widgets
      Les principes de mise en place de widget à travers le widget dialog
      Les effets visuel de dojo (dojo.lfx.toogle.js)
      Quelques widgets expliqués


Présentation

DojoTollkit est un framework de devellopement AJAX permettant une écriture simplifée de d'interfaces interactives pour les applications web.

Plus qu'un simple set de widget, dojo permet de plus une nouvelle approche de la programmation Javascript avec de nombreuse API telles que Reflect, Math, Lang et bien d'autres.

Nous allons dans ce tutorial voir, par l'exemple toutes les possibilités supplémentaires de programmation que propose ce framework

Mise en place

Lorsque vous télécharger une distribution de Dojo sur dojotoolkit.org vous obtenez une liste de fichiers avec un repertoire src contenant l'ensemble des sources de la distribution. Ces sources sont organisées sous forme de packages à  la Java.

Pour pouvoir utiliser le framework la première chose à  faire est d'importer le fichier dojo.js dans votre application web :

<html>
	<head>
		<script type="text/javascript" src="PathDeDojo/dojo.js"></script>
	</head>
</html>

				

Voila nous pouvons maintenant commencer à  utiliser Dojo...

Les concepts de base de Dojo

Comme nous l'avons déjà  dis plus haut, Dojo permet une approche différente de la programation Javascript en définissant de nouveaux concepts nottament au niveau de l'orientation objet de la programmation javascript. Nous allons dans cette partie décrire l'ensemble des concepts implémentés par Dojo.

La notion de Classe

Un exemple avant de commencer

Dojo defini un ensemble de classes organisées en packages à  la faà§on de Java. Ceci signifie donc qu'il est possible d'importer des classes dans une application web au niveau du code html des pages(Un équivalent de import en Java).

Nous allons ici voir un exemple d'application simple utilisant la classe dojo.collections.ArrayList : Tester la page

<html>
	<head>
		<script type="text/javascript" src="../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//on importe la classe qu l'on va utiliser
			dojo.require("dojo.collections.ArrayList");
			
			//on cree un nouveau tableau
			var tab = new dojo.collections.ArrayList(["foo","bar","test","bull"]);
			
			//on ajoute quelques éléments
			tab.add("foo2");
			tab.add("foo3");
			//puis un ensemble d'éléments à  la fois
			tab.addRange(["foo4", "foo5"]);
			//finalement on les affiches
			var e = tab.getIterator();
			while(!e.atEnd()){ 
				var toDisplay = e.get(); 
				alert(toDisplay);
			}
		</script>
	</head>
	<body>
	</body>
</html>
						

Dans cet exemple on voit qu'il est possible d'utiliser des facilement des classes de dojo en utilisant la directive d'importation dojo.required("package.class")

Ecrire une nouvelle classe

Nous avaons vu comment utiliser une classe de Dojo. Ce qui est plus interressant c'est l'écriture d'un classe personnalisée. Il est donc possible d'ajouter une classe grace à  la classe dojo.lang.declare. L'exemple suivant montre comment ecrire une classe simple : la classe personne

	<html>
	<head>
		<script type="text/javascript" src="../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//on importe la classe qu l'on va utiliser
			dojo.require("dojo.lang.declare");
			
			//on declare une nouvelle classe qui hérite de rien (d'ou le null)
			dojo.declare('net.demay.fr.exemples.personne', null, {
				nom: "",
				
				getNom : function(){
					return this.nom;
				},
				
				setNom : function(nom) {
					this.nom = nom;
				}
			});
			
			var personne = new net.demay.fr.exemples.personne();
			personne.setNom("test");
			alert(personne.getNom());
		</script>
	</head>
	<body>
	</body>
</html>
						

Il est aussi possible de définir un nouveau fichier .js dans le repertoire src/net/demay/fr/exemples/personne/ que l'on pourrait par la suite utiliser avec l'instruction dojo.require("dojo.net.demay.fr.exemple.personne.personne") - tester -

dojo.require("dojo.lang.declare");

dojo.provide("dojo.net.demay.fr.exemple.personne.personne");

dojo.declare('dojo.net.demay.fr.exemple.personne.personne', null, {
	nom: "",
	
	getNom : function(){
		return this.nom;
	},
	
	setNom : function(nom) {
		this.nom = nom;
	}
});
						

l'utilisation serait donc la suivante :

<html>
	<head>
		<script type="text/javascript" src="../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//on importe la classe qu l'on va utiliser
			dojo.require("dojo.net.demay.fr.exemple.personne.personne");

			var personne = new dojo.net.demay.fr.exemple.personne.personne();
			personne.setNom("test");
			alert(personne.getNom());
		</script>
	</head>
	<body>
	</body>
</html>
						

Dans la mise en place précédente d'un nouveau widget, le package est totalement integré aux sources dojo. Ceci n'est pas un bonne solution en soit : Pour la maitenance de ces widgets d'une part et de plus pour la mise à jour des sources de Dojo elles-mêmes.
La structure à respecter dans ces cas la est la même que celle des packages de dojo. Comme le montre le schéma suivant:

Le fichier dojo-extention.js va declarer notre nouveau package :

//this script should be loaded after dojo.js
alert(dojo);
dojo.setModulePrefix("dojoExtention","../dojoExtention");
//deprecie a partir de 0.4 : utiliser dojo.registerModulePath()

							

Attention : A partir de la version 0.4 la méthode dojo.setModulePrefix est depreciée au profit de dojo.registerModulePath

La seconde étape est de déclarer un fichier __package__.js permettant de spécifier le contenu d'un packages :

dojo.kwCompoundRequire({
	common: [
		"dojoExtension.net.demay.fr.example.personne.personne",
		"dojoExtension.net.demay.fr.example.personne.personne2"
	]
});
dojo.provide("dojoExtention.net.demay.fr.example.personne.*");
							

Regardons maintenant comment la nouvelle classe personne est décalrée

dojo.require("dojo.lang.declare");

dojo.provide("dojoExtention.net.demay.fr.exemple.personne.personne");

dojo.declare('dojoExtention.net.demay.fr.exemple.personne.personne', null, {
	nom: "",
	
	getNom : function(){
		return this.nom;
	},
	
	setNom : function(nom) {
		this.nom = nom;
	}
});
							

Et finalement l'appel à ce nouveau package.

<META http-equiv="Content-Type" Content="text/html; charset=ISO-8859-15">
<html>
	<head>
		<script type="text/javascript" src="../dojo0.3/dojo.js"></script>
		<script type="text/javascript" src="../dojoExtention/dojo-extention.js"></script>
		<script type="text/javascript">
			//on importe la classe qu l'on va utiliser
			dojo.require("dojoExtention.net.demay.fr.exemple.personne.personne2");

			var personne = new dojoExtention.net.demay.fr.exemple.personne.personne2();
			personne.setNom("nom");
			personne.setPrenom("prenom");
			alert(personne.getNom());
		</script>
	</head>
	<body>
	</body>
</html>							
							

La notion d'héritage

On vient de voir dans les exemples précédents comment construire une nouvelle classe. si l'on regarde de plus près la méthode utilisée pour définir une classe : dojo.declare('dojo.net.demay.fr.exemples.personne', null, {...});, on voit que le second parametre est null. Ce parametre est utilisé pour définir un héritage. Dans l'exemple suivant nous allons hériter de notre classe personne pour ajouter un attribut prenom et redefinir le getter getNom :

dojo.require("dojo.lang.declare");
dojo.require("dojo.net.demay.fr.exemple.personne.personne");

dojo.provide("dojo.net.demay.fr.exemple.personne.personne2");

dojo.declare('dojo.net.demay.fr.exemple.personne.personne2', 
			  dojo.net.demay.fr.exemple.personne.personne, 
	{
	prenom: "",
	
	getNom : function(){
		return this.nom + " " + this.prenom;
	},
	
	setPrenom : function(prenom) {
		this.prenom = prenom;
	}
});
						

Et l'utilisation...

<html>
	<head>
		<script type="text/javascript" src="../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//on importe la classe qu l'on va utiliser
			dojo.require("dojo.net.demay.fr.exemple.personne.personne2");

			var personne = new dojo.net.demay.fr.exemple.personne.personne2();
			personne.setNom("nom");
			personne.setPrenom("prenom");
			alert(personne.getNom());
		</script>
	</head>
	<body>
	</body>
</html>
						

D'autres mécanismes d'heritage existe avec Dojo. Nous les verrons pas dans ce tutorial car celui qui vient d'àªtre présenté est à  mon sens le plus pratique à  utiliser

Les classes principales définies dans Dojo

Maintenant que nous connaissons les mécanismes d'écriture de classe nous pouvons nous pencher sur les principales classes proposées par Dojo pour manipuler des données ansi que les principales librairies.

Les librairies principales

Dojo fournit un ensemble de laibrairie pour travailler plus facilement avec Javascript, DOM et HTML et autres :

La Gestion des données

Dojo fourni de plus un ensemble de conteneur de données équivalent à  ceux existant en Java (voir la package collections):

Autres packages

D'autres packages sont disponibles tels que :

Animation, DnD, validation et widgets

Nous verrons ces aspects dans les paragraphes suivants

Pour plus d'informations sur ces objets, voir les sources Dojo ou l'API en ligne : http://dojotoolkit.org/api/?

Le debugger de Dojo

TODO

Dojo et AJAX

En plus de toutes ces fonctionnalités pour écrire du javascript, le principal interet de Dojo reste AJAX. Nous allons voir maintenant comment faire de l'AJAX, communication client/server asynchrone.

AJAX c'est quoi

TODO

Mise en place d'une communication client/serveur asynchrone

Le package dojo.io.* contient un ensemble de routines pour permettre de gerer les entrées/sortie réseaux. La méthode dojo.io.bind permet de faire des requettes AJAX avec Dojo. Voici un petit exemple de communication ajax : - tester -

La page html

<html>
	<head>
		<script type="text/javascript" src="../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//on importe la classe qu l'on va utiliser
			//Notons que l'on peut importer tout un package avec *!
			dojo.require("dojo.io.*");
			dojo.require("dojo.dom");
			
			var bindArgs = {
			    url:        "content.xml",
			    mimetype:   "text/xml",
			    error:      function(type, errObj){
			        alert("erreur");
			    },
			    load:      function(type, data, evt){
			        var node = document.getElementById("foo");
			        var html = data.getElementsByTagName("replace").item(0);
			        //on utilise une fonction dojo.dom
					node.innerHTML = dojo.dom.innerXML(html);
			    }
			};
		</script>
	</head>
	<body>
		<span id="foo">
			le contenu viendra ici
		</span>
		<div onclick="dojo.io.bind(bindArgs)">EssaieMoi</div>
	</body>
</html>
					

Ceux que l'on veux afficher (content.xml)

<response>
	<replace>
		<div>
			et voila <i>le contenu est remplacé</i>
			<input type="text"/>
		</div>
	</replace>
</response>
					

Les widgets

Nous connaissons maintenant l'essentiel de la base de Dojo, il est maintenant possible de se pencher sur quelques widgets proposé par Dojo

Les principes de mise en place de widget à  travers le widget dialog

Le widget Dialog permet d'afficher une fenetre en avant plan. Nous allons voir au travers de ce widget un ensemble de concept utilisé dans la gestion des widgets avec Dojo.Mais avant de commencer voici un exemple

<html>
	<head>
		<script type="text/javascript" src="../../dojo0.3/dojo.js"></script>
		<script type="text/javascript">
			//on importe la classe qu l'on va utiliser
			dojo.require("dojo.widget.Dialog");
			
			//on declare une variable pour l'objet dialog
			var dlg;
			
			//une fois que TOUT LE HTML sera charger on cré notre dialog
			//avec un bouton pour le fermer
			function init(e) {
				dlg = dojo.widget.byId("dlg");
				var btn = document.getElementById("hider");
				dlg.setCloseControl(btn);
			}
			dojo.addOnLoad(init);
		</script>
		
		<style type="text/css">
		.dojoDialog {
			background : #eee;
			border : 1px solid #999;
			-moz-border-radius : 5px;
			padding : 4px;
		}
		</style>
	</head>
	<body>
		<!-- tout ces parametres servent à  initialiser notre dialog -->
		<!-- Il correspondent à  des attributs de l'objet dialog     -->
		<!-- qui seront seront initialiser avec les valeurs par le  -->
		<!-- dojo.widget.byId("dlg")                                -->
		<div dojoType="dialog" id="dlg" bgColor="blue" bgOpacity="0.5" toggle="fade" toggleDuration="250">
			Mon premier dialogue
			<!-- Pour me fermer ;) -->
			<input type="button" id="hider" value="OK"></td>
		</div>
		
		<a href="javascript:dlg.show();">ouvre moi!</a>
	</body>
</html>
					

Commencons par la fonction dojo.addOnLoad(). Elle permet de lancer des fonctions une fois que la page est totalement chargée. Ici nous l'utilisons pour lancer la fonction init. Cette fonction init va creer le dialog par l'appel à  dojo.widget.byId("dlg");

La fonction dojo.widget.byId("dlg"); va aller parser le noeud HTML portant id dlg pour creer le widget Dialog. Ce noeud sera ensuite retiré du dom HTML.

dojo.widget.byId("dlg"); lit l'ensemble des attributs de l'element portant le nom dlg (par exemple bgColor="white" ou toggle="fade") qui sont des attributs de la classe dialog (voir la source de dojo.widget.Dialog) Pour les initialiser. Notons au passage que ces attributs ont une valeur par defaut (bgColor: "black").

Ainsi notre objet sera créé. Après cette création, la fonction postCreate (voir la source de dojo.widget.Dialog) sera appelée et génèrera dans le DOM de la page tout ce qui est necessaire pour l'affichage de ce dialog en utilisant un template (voir la source du template) qui servira de base à  la construction de l'objet graphique Dialog.

Regardons maintenant quelques attributs de ce dialog pour savoir à  quoi il servent :

Les effets visuel de dojo (dojo.lfx.toogle.js)

Nous avons vu avec le dialog que dojo permet des effets visuels sur les widgets, en voici la liste avec un exemple pour chaque effet

Quelques widgets expliqués