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 :
-
dojo.lang :
Suite de fonctions pour rendre le javascript plus facile à utiliser. Nous en avons vu un exemple avec
declare
-
dojo.string :
Fonctions de manipulation de chaines de caractères
-
dojo.dom :
Fonctions de manipuation de DOM
-
dojo.style :
Fonctions de manipulation de CSS
-
dojo.html :
Fonctions de manipulation de HTML basée sur DOM
-
dojo.event :
Gestion des événements (librairie très utilisée pour la geston des widgets)
-
dojo.reflect :
Fonctions d'introspection
-
dojo.date :
Fonctions de manipulation de date
-
dojo.login.Logger :
Logger pour le javascript. Très pratique pour le débuggage et compatible FireBug
-
dojo.profile :
Profiler pour javascript
-
dojo.regexp :
Gestionnaire d'expressions régulieres
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):
-
Dictionary : Objet disctionnaire(hash)
-
ArrayList
-
Queue : Objet FIFO
-
SortedList List ordonnées et indexée
-
Set
-
Stack : Objet FILO
Autres packages
D'autres packages sont disponibles tels que :
-
dojo.storage : Routine de stockages de données coté client
-
dojo.xml.Parse : Parser XML
-
dojo.uri : Manipulation d'URL et URI
-
dojo.io : gestionnaire d'I/O (Voir la partie Dojo et Ajax)
-
dojo.rpc
-
dojo.json
-
dojo.crypto
-
dojo.math
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
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
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 :
-
dojoType="dialog" : est obligatoire sur tout les widgets Dojo. Il sert à savoir quelle
est la classe du widget
-
id="dlg" : comme en Html sert à identifier un noeud. Ici pour construire le widget
-
bgColor="blue" : Le dialog en s'affichant enlève le focus sur toute la page en affichant un voile en arrière plan de la fenàªtre
qui va s'ouvrir. bgColor sert donc à définir la couleur de ce voile
-
bgOpacity="0.5" : est l'opacité de ce voile
-
toggle="fade" : il s'agit de l'effet visuel lors de l'affichage et de la fermeture du dialog
-
toggleDuration="250" : la durée en ms de cet effet
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
- Les arbres et la gestions de évènements
- Edition de html en ligne
- Le TabContainer : les onglets