Tutoriel : Ma première application Dojo


Tutoriel original par Cyril Berthenet

Pour bien commencer…

Avant de commencer à implémenter l’exemple présenté dans ce tutoriel, il vous faut tout d’abord :

  1. Avoir fait le tutoriel « mon premier widget Dojo » (où au moins avoir télécharger le code source du tutoriel)
  2. # Copier les librairies dijit, dojo et dojox du framework Dojo dans le répertoire tutoDojo
    Télécharger le framework Dojo à cette adresse http://download.dojotoolkit.org/
  3. Créer ensuite le répertoire exemple2 en effectuant un simple copier/coller du dossier exemple1.
    Arborescence du projet.
  4. Editer les fichiers Search.js et searchWidget.html pour modifier le namespace

    Search.js

    /**********************************************/
    /*                                            */
    /* Widget : Search                            */
    /* Author : Berthenet Cyril                   */
    /*                                            */
    /**********************************************/
    dojo.provide("exemple2.widget.Search");
     
    dojo.require("dijit._Templated");
    dojo.require("dijit._Widget");
     
    dojo.require("dijit.form.Button");
    dojo.require("dijit.Menu");
     
    dojo.requireLocalization("exemple2", "Locale");
    dojo.requireLocalization("exemple2", "Ressources");
     
    /* Class: Search */
    dojo.declare("exemple2.widget.Search", [dijit._Widget,dijit._Templated], {
     
    /* Object: _nls
    stockage du wording et des ressources du widget */
    _nls:{locale:null,ressources:null},
     
    /* String: templatePath
    chemin d'acces vers le template du widget */
    templatePath: dojo.moduleUrl("exemple2.widget", "template/Search.html"),
     
    /* Object: _dropdown
    Bouton de selection du moteur de recherche */
    _dropdown:null,
     
    /* Array: _engines
    Liste des moteurs de recherche */
    _engines:null,
     
    /* Function: constructor
    Constructeur */
    constructor: function(){
    console.log("exemple2.widget.Search::constructor");
    this._nls.locale=
    dojo.i18n.getLocalization("exemple2","Locale").searchWidget;
    this._nls.ressources=
    dojo.i18n.getLocalization("exemple2","Ressources").searchWidget;
    this._engines=this._nls.locale.engines;
    this._dropdown={};
    },
     
    /* Function: destroy
    Destructeur */
    destroy: function(){
    console.log("exemple2.widget.Search::destroy");
    this.inherited("destroy",arguments);
    if(this._dropdown){this._dropdown.destroy();}
    delete this._nls;
    delete this._engines;
    },
     
    /* Function: startup
    Methode publique appelee apres l'instanciation du widget et la creation de tous
    ses noeuds DOM dans document.body */
    startup: function(){
    console.log("exemple2.widget.Search::startup");
    this.inherited("startup",arguments);
     
    this.searchField.value=(this.text==null||this.text=="")?
    this._nls.locale.text:this.text;
     
    var menu = new dijit.Menu();
     
    dojo.forEach(this._engines, function(engine){
     
    var menuItem = new dijit.MenuItem({
    label: engine,
    onClick: dojo.hitch(this, function(param) {
    this._dropdown.attr("label",param);
    this._dropdown.attr("engine",param);
    },engine)
    });
     
    menu.addChild(menuItem);
     
    },this);
     
    this._dropdown = new dijit.form.DropDownButton({
    label: this._engines[0],
    engine: this._engines[0],
    dropDown: menu
    }, dojo.byId(this.id+"Selector"));
     
    this._dropdown.startup();
     
    },
     
    /* Function: _onKeyPress
    Methode privee executee lors de la saisie d'un caractere dans le champs de recherche */
    _onKeyPress: function(/*Object*/evt) {
    console.log("exemple2.widget.Search::_onKeyPress");
    if(evt.keyCode == dojo.keys.ENTER){
    this._search();
    dojo.stopEvent(evt);
    return;
    }
    },
     
    /* Function: _clear
    Methode privee permettant d'effacer le texte du champs de saisie */
    _clear: function() {
    console.log("exemple2.widget.Search::_clear");
    if(this.searchField.value==this._nls.locale.text||this.searchField.value==this.text) {
    this.searchField.value="";
    }
    },
     
    /* Function: _search
    Methode privee executant la recherche */
    _search: function() {
    console.log("exemple2.widget.Search::_search");
     
    if(  this.searchField.value!=this._nls.locale.text &&
    this.searchField.value!=this.text &&
    this.searchField.value != "") {
     
    var url = "";
    var fieldValue = this.searchField.value;
    var engines = this._nls.ressources.engines;
     
    switch(this._dropdown.attr('engine')){
    case this._engines[0]:
    url = engines.google;
    break;
    case this._engines[1]:
    url = engines.yahoo;
    break;
    case this._engines[2]:
    url = engines.wikipedia;
    break;
    }
     
    dojo.byId("viewer").src=url+escape(fieldValue);
     
    }
    else {
     
    var dialogbox = dijit.byId("dialogbox");
     
    var content = this._nls.ressources.popup;
    dialogbox.attr("title",this._nls.locale.popup.title);
    dialogbox.attr("content",dojo.string.substitute(content,{
    message:this._nls.locale.popup.message,
    btnLabel:this._nls.locale.popup.btnLabel
    }));
     
    dialogbox.show();
    }
    }
    });

    searchWidget.html

    <script type="text/javascript">// <![CDATA[
     
     
          dojo.require("dojo.i18n");
          dojo.require("dijit.Dialog");
     
    	  dojo.require("exemple2.widget.Search"); 
     
          dojo.addOnLoad(init);
     
          function init(){ 
     
            var _search = new exemple2.widget.Search({
    		  id:"search",
              text:"saisir votre texte ici..."
            }, dojo.byId("search"));
     
            _search.startup();
     
            var dialog = new dijit.Dialog({
              title: "title" 
    		}, dojo.byId("dialogbox"));
     
            dialog.startup();
     
          }
     
     
    // ]]></script>

Conventions de codage adoptées dans ce tutoriel

  1. commentaires : /* commentaire sur une ou plusieurs lignes */
  2. ajout d’une ligne console.log en début de fonction pour identifier les méthodes appelées lors de l’exécution du code
  3. les méthodes privées sont préfixées par un underscore
  4. afin d’éviter les problèmes d’encodage, les caractères accentués sont proscrit du code Dojo

Définition du template du widget ‘Viewer’

Ce composant graphique va nous permettre d’afficher le résultat de la recherche sous forme d’une page HTML.
Il est composé des éléments suivants :

  1. un div container qui nous permettra par la suite de définir le style de notre widget
  2. d’une iframe pour l’affichage

Viewer.html

 

<div class="viewer">class="iframe"&lt;br /&gt;           src="${_nls.ressources.defaultPage}"&lt;br /&gt;           dojoAttachPoint="viewer"&lt;br /&gt;           scrolling="yes"&lt;br /&gt;           frameborder="no"&gt;&lt;br /&gt;</div>

lignes :
4 : url de la page qui sera affichée par défaut dans le viewer (gestion du lien dans les ressources)

Modification des ressources

nls/Ressources.js et nls/fr/Ressources.js

},
"viewerWidget" : {
"defaultPage": "static/empty.html"
}

Définition du style du widget ‘Viewer’

viewer.css

.viewer .iframe {
width: 800px;
height: 400px;
border:3px solid #B0B0B0;
}

Modification de la page statique

empty.html

 
 
 
 
Le résultat de votre recherche s'affichera dans ce viewer

Définition de la classe ‘Viewer’

Diagramme de classe

Viewer

– _nls : object
– templatePath : string
– _topics : array
+ constructor()
+ destroy()
+ postCreate()
+ setContent()
+ reset()

Viewer.js

/**********************************************/
/*                                            */
/* Widget : Viewer                            */
/* Author : Berthenet Cyril                   */
/*                                            */
/**********************************************/
dojo.provide("exemple2.widget.Viewer");
 
dojo.require("dijit._Templated");
dojo.require("dijit._Widget");
 
dojo.requireLocalization("exemple2", "Ressources");
 
/* Class: Search */
dojo.declare("exemple2.widget.Viewer", [dijit._Widget,dijit._Templated], {
 
/* Object: _nls
stockage du wording et des ressources du widget */
_nls:{ressources:null},
 
/* String: templatePath
chemin d'acces au template du widget */
templatePath: dojo.moduleUrl("exemple2.widget", "template/Viewer.html"),
 
/* Function: constructor
Constructeur */
constructor: function(){
console.log("exemple2.widget.Viewer::constructor");
this._nls.ressources=
dojo.i18n.getLocalization("exemple2","Ressources").viewerWidget;
},
 
/* Function: destroy
Destructeur */
destroy: function(){
console.log("exemple2.widget.Search::destroy");
delete this._nls;
},
 
/* Function: setContent
Modification du contenu du viewer */
setContent: function(/*String*/url) {
console.log("exemple2.widget.Viewer::setContent");
this.viewer.src=url;
},
 
/* Function: reset
Remise a zero du contenu du viewer */
reset: function() {
console.log("exemple2.widget.Viewer::setContent");
this.setContent(this._nls.ressources.defaultPage);
}
});

lignes :
30 et 31 : chargement des ressources du widget
43 à 46 : méthode permettant de modifier le contenu de l’iframe avec une url passée en paramètre
50 à 53 : remise à zéro du contenu du viewer par l’affichage de la page par défaut

Création d’un sample de test

viewerWidget.html

 
<script type="text/javascript">// <![CDATA[
 
 
      var djConfig = {
        parseOnLoad: false,
        isDebug: true
      }; 
 
 
// ]]></script>
 
<script src="../dojo/dojo.js" type="text/javascript"></script>
 
<script type="text/javascript">// <![CDATA[
 
 
      dojo.require("dojo.i18n");
 
      dojo.require("exemple2.widget.Viewer"); 
 
      dojo.addOnLoad(init);
 
      function init(){
 
         var _viewer = new exemple2.widget.Viewer({
          id:"viewer"
        }, dojo.byId("viewer"));
 
        _viewer.setContent("http://www.google.fr");        
 
      }
 
 
// ]]></script>
 

lignes :
8 : chargement du style
31 à 33 : instanciation du widget « Viewer »
35 : affichage par défaut du moteur google

Définition de la classe de notre application

Nous avons fait le choix dans ce tutoriel de construire notre exemple à partir d’une classe appelant un template regroupant les widgets de base de notre application. Les widgets qui pourraient avoir d’autres fonctions que celle de la rechercher dans une application plus complète seront déportés vers le sample de test (ex: la boîte de dialogue)

MonAppli.js

/**********************************************/
/*                                            */
/* Widget : Mon application                   */
/* Author : Berthenet Cyril                   */
/*                                            */
/**********************************************/
dojo.provide("exemple2.widget.MonAppli");
 
dojo.require("dijit._Templated");
dojo.require("dijit._Widget");
 
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.Dialog");
 
dojo.require("exemple2.widget.Search");
dojo.require("exemple2.widget.Viewer");
 
dojo.requireLocalization("exemple2", "Ressources");
 
/* Class: Search */
dojo.declare("exemple2.widget.MonAppli", [dijit._Widget,dijit._Templated], {
 
/* Boolean: widgetsInTemplate
affichage de widgets dans un template (false par defaut) */
widgetsInTemplate: true,
 
/* String: templatePath
chemin d'acces au template du widget */
templatePath: dojo.moduleUrl("exemple2.widget", "template/MonAppli.html"),
 
/* Function: constructor
Constructeur */
constructor: function(){
console.log("exemple2.widget.MonAppli::constructor");
}
});

ligne :
27 : la variable widgetsInTemplate est très importante car elle permet l’interprétation des widgets à l’intérieur d’un template

Définition du template de notre application

Le template de notre application regroupe les composants graphiques permettant la mise en page (dijit.layout) et ceux liés à la fonction de recherche (Search et Viewer).

MonAppli.html

 

<div>
<div>
 
&nbsp;
 
</div>
<div>
 
&nbsp;
 
</div>
</div>

 

Distribution des données dans l’application

Les widgets publient leurs données et/ou s’abonnent pour en obtenir.
remplacer la ligne :

Search.js

dojo.byId("viewer").src=url+escape(fieldValue);

par :

Search.js

dojo.publish("displayResult",[url+escape(fieldValue)]);

Viewer.js

/* Array: topics */
_topics:null,
/* Function: constructor
Constructeur */
constructor: function(){
console.log("exemple2.widget.Viewer::constructor");
this._nls.ressources=dojo.i18n.getLocalization("exemple2","Ressources")
.viewerWidget;
this._topics=[];
},
 
/*Function: destroy
Destructeur */
destroy: function(){
console.log("exemple2.widget.Search::destroy");
delete this._nls;
delete this._topics;
},
 /* Function: postCreate
Methode appelee apres la creation du widget */
postCreate: function() {
this._topics[0]=dojo.subscribe("displayResult", this, "setContent");
},

lignes :
27 : définition d’un tableau pour le stockage des topics.
35 : initialisation du tableau de topics.
43 : destruction du tableau de topics.
48 à 50 : méthode appelée automatiquement après la création du widget.
49 : déclenchement de la méthode setContent() du Viewer lorsque un topic « displayResult » est publié dans l’application.

note : le widget ‘Search’ envoi un topic « displayResult » avec l’url de recherche dans toute l’application. Le widget ‘Viewer’ qui a souscrit à ce topic va exécuter sa méthode setContent() avec l’url passée en argument du topic

Modification des styles

Séparation des styles propres à chacun des widgets et ceux pouvants être réutilisé dans toute l’application. On a préféré faire ici plusieurs fichiers css qui seront compressés en un seul fichier css par le processus de buid.

search.css

.search {
height:30px;
}
.search .btn {
background: url(../images/loupe.png) no-repeat;
width:20px;
height:19px;
border-left:0px;
cursor:pointer;
}
.search input{
height:21px;
font:13px verdana, sans-serif;
}

monappli.css

.floatLeft {
float:left;
}
.greyBorder {
border:1px solid #B0B0B0;
}
/****************************************/
/*    Surcharge theme nihilo de Dojo       */
/****************************************/
.nihilo .dijitDropDownButton .dijitReset {
height:16px;
}
.nihilo .dijitDropDownButton {
float: left;
margin:0 !important;
}
.nihilo .dijitDropDownButton span {
font:10px verdana, sans-serif;
}
.nihilo .dijitButtonNode {
width:80px;
border:1px solid #B0B0B0 !important;
border-right:0px !important;
}

Test 

monApplication.html

 
 <!--       @import "../dijit/themes/dijit.css";       @import "../dijit/themes/nihilo/nihilo.css";      --><script type="text/javascript">// <![CDATA[
 
 
      var djConfig = {
        parseOnLoad: false,        
		isDebug: true
      };
 
 
// ]]></script>
 
<script src="../dojo/dojo.js" type="text/javascript"></script>
 
<script type="text/javascript">// <![CDATA[
 
 
      dojo.require("dojo.i18n");      
 
      dojo.require("exemple2.widget.MonAppli");
 
      dojo.addOnLoad(init);
 
	  function init(){
 
        var _appli = new exemple2.widget.MonAppli({}, dojo.byId("appli"));
 
        var dialog = new dijit.Dialog({}, dojo.byId("dialogbox")); 
 
        dialog.startup();
 
      }
 
 
// ]]></script>
 

lignes :
8 : chargement du style du widget ‘Viewer’
9 : chargement du style du widget ‘Search’
10 : chargement des styles communs partagés par toute l’application
12 à 15 : chargement des thèmes dijit et nihilo pour la création du bouton à menu déroulant
38 : instanciation de l’application
40 : instanciation de la boîte de dialogue pour l’affichage des erreurs. On aurait pu inclure ce widgets dans le template de notre application en imaginant qu’il puisse avoir une autre fonction que l’affichage des erreurs liées à la recherche dans une application plus complète.

L'application finale est composée des widgets 'Search' et 'Viewer'.


Berthenet Cyril

http://www.life-behind-the-mirror.com/codes/tutoDojo/myFirstDojoAppli.php

 

Publié dans tutoriels Tagués avec :

Générer une table des matieres

La table des matières (toc)


Une table des matières peut être généré côté serveur où côté client.
Si comme moi vous préférez utiliser Dojo pour la créer, voici de quoi vous ravir.

Fonctionnement

Le script va lire le contenu du DOM à la recherche de balise (par défaut les h1 et h2 mais cela est paramétrable).
Ces balises vont ensuite être utilisées pour générer une suite de balise LI.

Utilisation

Il ne suffit que de deux lignes pour générer votre table des matières :

//charge le code de création de la toc
dojo.require("dojox.toc");
 
dojo.addOnLoad(function() {
    //creation de la toc
    dojox.toc.create();
}

Note : Utilisé sans argument, dojox.toc.create() va générer la TOC en parcourant tous les enfants du body de la page à la recherche de h1 et h2.

Les arguments

dojox.toc.create() accepte un argument de type objet :

	{
		rootNode : dojo.body() /*Racine a parcourir. La recherche se fait à l'intérieur de cette balise*/,
		classToIgnore : [] /*Tableau listant les classes à ignorer. Un élément qui comporte l'une de ces classes sera ignoré.*/,
		appendNode : dojo.body() /*Noeud de référence autour duquel sera ajouté la table des matières. S'il vaut nul, le noeud ne sera pas ajouté au DOM*/,
		position : "before" /*Position à laquelle le noeud de la TOC sera ajouté autour du noeud défini par appendNode*/,
		"class" : "toc" /*Classe ajoutée au UL de la TOC*/,
		query : "h1,h2" /*Noeuds qui seront recherché pour générer la TOC*/,
		stripHtml : true /*Supprime l'HTML trouvé dans les noeuds utilisés pour la TOC*/,
		rootAnchor : "dojox.toc." /*Texte ajouté dans les ancres (avant la position numérique de l'ancre)*/
	}

Exemple et téléchargement

Vous trouverez le code à télécharger ainsi qu’un exemple ici :

http://ben.dojotoolkit-fr.org/test_toc.html

Publié dans code Tagués avec :

Tutoriel : Mon premier widget Dojo

Création d’un composant graphique Dojo pour interfacer l’accès à plusieurs moteurs de recherche

tutoriel original écrit par Berthenet Cyril

Partie 1 : Le widget ‘Search’ simplifié

Le widget 'Search' simplifié est composé d’un champ de saisie et d’un bouton pour exécuter la recherche.

Partie 2 : Le widget ‘Search’ avancé

Le widget 'Search' avancé comporte un bouton supplémentaire à menu déroulant pour la sélection du moteur de recherche

Pour bien commencer…

  1. Créer dans le répertoire servant de localhost à votre serveur web (par défaut www pour easyphp, wamp,…) le dossier tutoDojo.
    Ce répertoire servira de racine à notre tutoriel.
  2. Copier les librairies dijit, dojo et dojox du framework Dojo dans le répertoire
    Télécharger le framework Dojo à cette adresse http://download.dojotoolkit.org/
    (Préférer le package src du framework, contenant l’ensemble des sources de la distribution, pour vos futurs développements)
  3. Créer ensuite le dossier exemple1 en respectant l’arborescence présentée sur la figure ci-dessous.

Arborescence du projet.

Conventions de codage adoptées dans ce tutoriel

  1. commentaires : /* commentaire sur une ou plusieurs lignes */
  2. ajout d’une ligne console.log en début de fonction pour identifier les méthodes appelées lors de l’exécution du code
  3. les méthodes privées sont préfixées par un underscore
  4. afin d’éviter les problèmes d’encodage, les caractères accentués sont proscrit du code Dojo

Définition du template

Nous aurons besoin des éléments suivants :

  • un div container qui nous permettra par la suite de définir le style de notre widget
  • une balise input type= »text » pour le champ de saisie
  • un div que nous utiliserons comme bouton pour lancer la recherche

Search.html :

Définition du widget

Pour créer un widget Dojo, notre classe « Search » doit hériter des méthodes et propriétés des classes _Widget et _Templated de la librairie dijit.

dojo.declare("exemple1.widget.Search", [dijit._Widget,dijit._Templated], {});

Diagramme de classe

Search

– _nls : object
– templatePath : string
– _dropdown : object
– _engines : array
+ constructor()
+ destroy()
+ startup()
– _onKeyPress(evt object)
– _clear()
– _search()

Search.js :

/**********************************************/
/*                                            */
/* Widget : Search                            */
/* Author : Berthenet Cyril                   */
/*                                            *
//**********************************************/
 
dojo.provide("exemple1.widget.Search");
 
dojo.require("dijit._Templated");dojo.require("dijit._Widget");
 
/* Class: Search */
dojo.declare("exemple1.widget.Search", [dijit._Widget,dijit._Templated], {
   /* String: templatePath
     chemin d'acces vers le template du widget */
  templatePath: dojo.moduleUrl("exemple1.widget", "template/Search.html"),
 
  /* Function: constructor     Constructeur */
  constructor: function(){
    console.log("exemple1.widget.Search::constructor");
  }
 });

lignes :
10. importation de la classe _Templated
11. importation de la classe _Widget
18. chemin d’accès vers le template du widget
22. constructeur de notre classe

Définition du style

search.css :

.floatLeft {
  float:left;
}
.greyBorder {
  border:1px solid #B0B0B0;}
.search .btn {
  background: url(../images/loupe.png) no-repeat;
  width:20px;
  height:19px;  border-left:0px;
  cursor:pointer;
}
.search input{  
  height:21px;  font:13px verdana, sans-serif;
}

lignes :
1 à 6 : styles génériques qui pourront être déportés vers le fichier css de l’application
7 à 13 : définition du style du bouton
14 à 17 : définition du style du champ de saisie

Le fichier loupe.png est disponible en bas de page

Modification du code du template de notre widget afin d’appliquer le style défini dans le fichier css

Search.html :

<div class="search"><input class="floatLeft greyBorder" type="text" name="Field" value="saisir le texte ici..." />
<div class="btn greyBorder floatLeft" id="Button" title="lancer la recherche"></div>
</div>

lignes :
3 et 8 : ajout des classes définies dans le fichier css

Création d’un sample de test

searchWidget.html :

<meta http-equiv="Content-Type" content="text/html; charset=" />
 
			<link href="./css/search.css" rel="stylesheet" type="text/css" /><script type="text/javascript">// <![CDATA[
var djConfig = {
        parseOnLoad: false,
        isDebug: true
      };
// ]]></script><script charset="utf-8" type="text/javascript" src="../dojo/dojo.js"></script><script type="text/javascript" language="javascript">// <![CDATA[
dojo.require("exemple1.widget.Search");
 
      dojo.addOnLoad(init);        
      function init(){
 
        var _search = new exemple1.widget.Search({
          id:"search"        }, dojo.byId("search"));
 
        _search.startup();
 
      }
// ]]></script>

lignes :
lignes 8 : chargement du style du widget
12 à 15 : paramètres qui seront utilisés au chargement du framework
19 : chargement du framework Dojo
23 : importation du widget ‘Search’
25 : chargement de la fonction init après la création de tous les noeuds DOM
29 à 31 : instanciation du widget ‘Search’
30 : l’ajout d’un id n’est pas obligatoire car Dojo crée des identifiants uniques lors de l’exécution du code. nous utilisons ici un id « fixe » que nous réutiliserons plus tard.
31 : une fois créé, le widget remplacera le div « search » dans la page HTML (ligne 40)
33 : exècution de la mèthode startup() de la classe ‘Search’

Test du widget ‘Search’

Afin de debbuger, afficher les message de Log ou observer le chargement des classes Dojo de notre code, nous allons activer le plugin firebug avant d’exécuter le sample.
Si vous ne l’avez pas, téléchargez firebug sur le site http://getfirebug.com/

Exécution du sample

http://localhost/tutoDojo/exemple1/searchWidget.html

vous devez obtenir le résultat suivant :
Visualisation du chargement des classes de notre projet. Sur les 2 dernières lignes de la console, on observe que le constructeur et le template du widget sont bien chargés.

Internationalisation

Gestion des langues pour le wording de notre widget.

Modification du template

lignes :
4 et 8 : création d’identifiants uniques pour les éléments du template à partir de l’id du widget fixé dans le sample par exemple ${id}Field deviendra searchField
6 : utilisation d’un attachPoint pour accéder directement au noeud DOM dans la classe : this.searchField
10 et 11 : utilisation d’un fichier de wording Locale.js pour le label et le titre du bouton

note : nous traiterons uniquement la langue française dans ce tutoriel

Modification de la classe

/**********************************************/
/* */
/* Widget : Search */
/* Author : Berthenet Cyril */
/* */
/**********************************************/
 
dojo.provide("exemple1.widget.Search");
 
dojo.require("dijit._Templated");
dojo.require("dijit._Widget");
 
dojo.requireLocalization("exemple1", "Locale");
 
/* Class: Search */
dojo.declare("exemple1.widget.Search", [dijit._Widget, dijit._Templated], {
 
/* Object : _nls
stockage du wording */
_nls:{locale:null},
 
/* String: templatePath
chemin d'acces au template du widget */
templatePath: dojo.moduleUrl("exemple1.widget", "template/Search.html"),
 
/* Function: constructor
Constructeur */
constructor: function(){
console.log("exemple1.widget.Search::constructor");
this._nls.locale=dojo.i18n.getLocalization("exemple1","Locale").searchWidget;
},
 
/* Function: destroy
Destructeur */
destroy: function(){
console.log("exemple1.widget.Search::destroy");
this.inherited("destroy",arguments);
delete this._nls;
},
 
/* Function: startup
Methode publique appelee apres l'instanciation du widget et
la creation de tous ses noeuds DOM dans document.body */
startup: function(){
console.log("exemple1.widget.Search::startup");
this.inherited("startup",arguments);
this.searchField.value = this._nls.locale.text;
}
 
});

lignes :
13 : définit le dossier où se trouve le répertoire « nls » pour la gestion des langues (native language support).
20 : objet qui contiendra l’ensemble du wording de notre widget.
30 : chargement du wording correspondant à la langue du navigateur. Nous avons choisi ici d’optimiser le code en ne chargeant que le wording de notre widget (.searchWidget).
35 : création d’un destructeur héritant des propriétés de _Widget.
38 : destruction de l’objet contenant le wording
44 à 48 : méthode startup() héritant des propriétés de _Widget. Elle est appelée après l’instanciation du widget dans le sample.
47 : remplissage du champ de saisie avec une chaîne de caractères définie dans les locales.

note : attention de bien ajouter une virgule entre chaque déclaration de fonctions (lignes 31 et 39).

Création des fichiers pour le wording

nls/fr/Locale.js :

Ce fichier sera utilisé par Dojo si la langue de votre navigateur est le français :

({
 
  "searchWidget" : {
    "search": "rechercher",
    "send": "lancer la recherche",
    "text": "saisir le texte ici..."
  }
 
})

nls/Locale.js :

Dans le cas où votre navigateur n’est pas en langue française, Dojo utilisera ce fichier de langue. Il s’agit donc de mettre ici la langue la plus internationale possible (à savoir, l’anglais) :

({
 
  "searchWidget" : {
    "search": "search",
    "send": "go",
    "text": "enter your keywords here..."
  }
 
})

note: les fichiers Locale.js doivent être complétés au format JSON.

Modification du sample

searchWidget.html :

<script type="text/javascript" language="javascript">// <![CDATA[
dojo.require("dojo.i18n");
 
  dojo.require("exemple1.widget.Search");

lignes :
24 : importation de la classe Dojo « i18n » pour l’internationalisation.

Test

Chargement des locales du widget.

Gestion d’un évènement « souris »

Exécution de la recherche lors d’un clic de souris sur le bouton « loupe »

Search.html :

<div id="${id}Button" 
     class="btn greyBorder floatLeft" 
     label="${_nls.locale.send}" 
     title="${_nls.locale.send}" 
     dojoAttachEvent="onclick:_search"></div>

lignes :
12 : ajout d’un évènement onclick sur le div que nous utiliserons comme bouton.

note : attention en Dojo les méthodes pour la gestion des évènements DOM sont toujours écrites en minuscule : onclick

Search.js :

},
 
  /* Function: _search
     Methode privee executant la recherche */
  _search: function() {
    console.log("exemple1.widget.Search::_search");
 
     if( this.searchField.value!=this._nls.locale.text &#038;&#038;
         this.searchField.value != "") {
        console.info("lancer la recherche sur : ", this.searchField.value);
    }
    else {
      console.info("vous devez saisir une chaine de caracteres...");
    }
  }

lignes :
55 et 56 : on exécute la recherche si la chaîne de caractères est différente de celle affichée par défaut dans le champ de recherche et si la chaîne de caractères n’est pas vide

Gestion d’un évènement « clavier »

Exécution de la recherche lorsque l’utilisateur appuie sur la touche « entrée » dans le champ de saisie.

Search.html :

<input type="text" 
         class="floatLeft greyBorder" 
         name="${id}Field" 
         value="" 
         dojoAttachPoint="searchField"
         dojoAttachEvent="onkeypress:_onKeyPress"
 />

lignes :
7 : ajout d’un évènement « onkeypress » sur le champ de saisie

Search.js :

},
 
  /* Function: _onKeyPress
     Methode privee executee lors de la saisie d'un caractere dans le champ
      de recherche */
  _onKeyPress: function(/*Object*/evt) {
    console.log("exemple1.widget.Search::_onKeyPress");
    if(evt.keyCode == dojo.keys.ENTER){
      console.info("vous avez appuye sur la touche ENTREE");
      this._search();
      dojo.stopEvent(evt);
      return;
    }
  }

lignes :
55 à 60 : exécute la recherche si l’utilisateur appuie sur la touche « entrée » lorsque le focus est sur le champ de saisie

Suppression du contenu du champ de saisie

Suppression du contenu par défaut du champ de saisie à la prise du focus.

Search.html :

<input type="text" 
         class="floatLeft greyBorder" 
         name="${id}Field" 
         value="" 
         dojoAttachPoint="searchField"
         dojoAttachEvent="onkeypress:_onKeyPress,onclick:_clear"
  />

lignes :
7 : ajout d’un évènement « onclick » sur le champ de saisie

Search.js :

},
 
  /* Function: _clear
     Methode privee permettant d'effacer le texte du champ de saisie */
  _clear: function() {
    console.log("exemple1.widget.Search::_clear");
    if(this.searchField.value==this._nls.locale.text) {
       this.searchField.value="";
    }
  },

lignes :
65 à 67 : si le texte dans le champ de saisie est identique au texte affiché par défaut, on efface le contenu

Valeur par défaut

Mettre une valeur par défaut dans le champ de recherche à l’initialisation du widget.

searchWidget.html :

var _search = new exemple1.widget.Search({
      id:"search",
      text:"test"
    }, dojo.byId("search"));

lignes :
34 : passage d’un argument type chaîne de caractères au widget

Search.js :

/* Function: startup
    Methode publique appelee apres l'instanciation du widget et 
    la creation de tous ses noeuds DOM dans document.body */
  startup: function(){
    console.log("exemple1.widget.Search::startup");
    this.inherited("startup",arguments);
    this.searchField.value=(this.text==null||this.text=="")?
                            this._nls.locale.text:this.text;
  }

lignes :
46 : si aucune valeur n’a été passée en argument lors de l’instanciation du champ de saisie
47 : on affiche la valeur définie dans le fichier de wording sinon on affiche la valeur passée en argument

/* Function: _clear
    Methode privee permettant d'effacer le texte du champ de saisie */
  _clear: function() {
    console.log("exemple1.widget.Search::_clear");
    if( this.searchField.value==this._nls.locale.text ||
	this.searchField.value==this.text ) {
	this.searchField.value="";
    }
  },
 
/* Function: _search
    Methode privee executant la recherche */
  _search: function() {
    console.log("exemple1.widget.Search::_search");
 
	if(  this.searchField.value!=this._nls.locale.text &#038;&#038;
         this.searchField.value!=this.text &#038;&#038;
		 this.searchField.value != "") {
         console.info("lancer la recherche sur : ", this.searchField.value);
    }
    else {
      console.info("vous devez saisir une chaine de caracteres..."); 
    }
  }

Sélection du moteur de recherche

Sélection du moteur de recherche dans un bouton avec liste déroulante.

Modification du template

Search.html :

<div class="search">
<div id="${id}Selector"></div>
<input type="text" 
         class="floatLeft greyBorder" 
         name="${id}Field"
		 value="" 
         dojoAttachPoint="searchField" 
         dojoAttachEvent="onkeypress:_onKeyPress,onclick:_clear" 
  />
<div id="${id}Button"
  class="btn greyBorder floatLeft" 
       label="${_nls.locale.send}" 
       title="${_nls.locale.send}" 
       dojoAttachEvent="onclick:_search"></div>
</div>

lignes :
2 : ajout d’un div qui sera remplacé par le widget drop-down button de Dojo

Modification du widget

Search.js :

/**********************************************/
/*                                            */
/* Widget : Search                            */
/* Author : Berthenet Cyril                   */
/*                                            */
/**********************************************/
 
dojo.provide("exemple1.widget.Search");
 
dojo.require("dijit._Templated");
dojo.require("dijit._Widget");
 
dojo.require("dijit.form.Button");
dojo.require("dijit.Menu"); 
 
dojo.requireLocalization("exemple1", "Locale");
dojo.requireLocalization("exemple1", "Ressources"); 
 
/* Class: Search */
dojo.declare("exemple1.widget.Search", [dijit._Widget,dijit._Templated], { 
 
  /* Object: _nls
     stockage du wording et des ressources du widget */
  _nls:{locale:null,ressources:null},
 
  /* String: templatePath
     chemin d'acces vers le template du widget */
  templatePath: dojo.moduleUrl("exemple1.widget", "template/Search.html"),
 
  /* Object: _dropdown
  bouton de selection du moteur de recherche */
  _dropdown:null,
 
  /* Array: _engines
  liste des moteurs de recherche */
  _engines:null, 
 
  /* Function: constructor
     Constructeur */
  constructor: function(){
    console.log("exemple1.widget.Search::constructor");
    this._nls.locale=dojo.i18n.getLocalization("exemple1","Locale").searchWidget;
    this._nls.ressources=
     	dojo.i18n.getLocalization("exemple1","Ressources").searchWidget;
	this._engines=this._nls.locale.engines;
    this._dropdown={};
  },
 
  /* Function: destroy
     Destructeur */  
  destroy: function(){
    console.log("exemple1.widget.Search::destroy");
    this.inherited("destroy",arguments);
    if(this._dropdown){this._dropdown.destroy();}
    delete this._nls;
    delete this._engines;
  },
 
  /* Function: startup
     Methode publique appelee apres l'instanciation du widget et
	 la creation de tous ses noeuds DOM dans document.body */
  startup: function(){
    console.log("exemple1.widget.Search::startup");
    this.inherited("startup",arguments);
 
    this.searchField.value=(this.text==null||this.text=="")?
                           this._nls.locale.text:this.text;
 
    var menu = new dijit.Menu();
 
	dojo.forEach(this._engines, function(engine){
 
    	var menuItem = new dijit.MenuItem({
		label: engine,
		onClick: dojo.hitch(this, function(param) {
			this._dropdown.attr("label",param);
			this._dropdown.attr("engine",param);
		},engine)
	});
 
	menu.addChild(menuItem);
 
  },this);
 
  this._dropdown = new dijit.form.DropDownButton({
     label: this._engines[0],
	 engine: this._engines[0],
	 dropDown: menu
   }, dojo.byId(this.id+"Selector"));
 
   this._dropdown.startup(); 
 
  },

lignes :
13 : importation de la classe bouton de Dojo
14 : importation de la classe menu de Dojo pour la liste déroulante du bouton
17 : chargement des ressources
24 : ajout des ressources à l’objet _nls
32 : objet bouton
36 : liste des moteurs de recherche
43 : sélection des ressources en fonction de la langue du navigateur
45 : création du tableau avec la liste des moteurs de recherche
54 : destruction du bouton lors de la destruction de notre widget
56 : destruction du tableau
69 : instanciation d’un menu dojo
71 : pour chacun des moteurs de recherche on va créer un item dans le menu
75 à 78 : en cliquant sur un item du menu on va sélectionner un moteur et changer le label du bouton
81 : ajout des items au menu
85 à 89 : instanciation d’un bouton drop-down à partir du menu créé précédemment
89 : le bouton va remplacer div « searchSelector » dans le template
91 : affichage du bouton

Search.js :

/* Function: _search
    Methode privee executant la recherche */
  _search: function() {
    console.log("exemple1.widget.Search::_search");
 
     if(  this.searchField.value!=this._nls.locale.text &#038;&#038;
         this.searchField.value!=this.text &#038;&#038; 
         this.searchField.value != "") {
 
      var url = "";
      var fieldValue = this.searchField.value;
      var engines = this._nls.ressources.engines;
 
	  switch(this._dropdown.attr('engine')){
	  case this._engines[0]:
		url = engines.google;
		break;
      case this._engines[1]:
		url = engines.yahoo;
		break;
      case this._engines[2]:
		url = engines.wikipedia;
		break;
	  }
 
	  console.log("url pour la recherche : ", url+escape(fieldValue));                        
 
    }
    else {

lignes :
123 : url utilisée pour lancer la recherche
124 : chaîne de caractère saisie dans le champ de recherche
125 : url des moteurs de recherche sans les paramètres
127 à 137 : construction de l’url en fonction du moteur sélectionné dans le bouton drop-down
139 : affichage de l’url complète avec la chaîne à rechercher au format http

Ajout des moteurs de recherche dans les locales

nls/Locale.js :

({
 
  "searchWidget" : {
    "engines" : [
        "Google",
        "Yahoo",
        "Wikipedia"
    ],
    "search": "search",
    "send": "go",
    "text": "enter your keywords here..."
  }
 
})

nls/fr/Locale.js :

({
 
  "searchWidget" : {
    "engines" : [
        "Google",
        "Yahoo",
        "Wikipedia"
    ],
    "search": "rechercher",
    "send": "lancer la recherche",
    "text": "saisir le texte ici..."
  }
 
})

lignes :
4 à 8 : liste des moteurs de recherche disponibles dans notre tutoriel

Ajout des url de recherche dans les ressources

nls/Ressources.js :

:

({
 
  "searchWidget" : {
    "engines" : {
        "google": "http://www.google.com/search?q=",
        "yahoo": "http://uk.search.yahoo.com/search?p=",
        "wikipedia": "http://en.wikipedia.org/wiki/Special:Recherche?search="
    }
  }
 })

lignes :
4 à 8 : url anglaises de recherche sur les moteurs google, yahoo et wikipédia sans la chaîne à rechercher

nls/fr/Ressources.js :

({
 
  "searchWidget" : {
    "engines" : {
        "google": "http://www.google.fr/search?q=",
        "yahoo": "http://fr.search.yahoo.com/search?p=",
        "wikipedia": "http://fr.wikipedia.org/wiki/Special:Recherche?search="
    }
  }
 })

lignes :
4 à 8 : url française de recherche sur les moteurs google, yahoo et wikipédia sans la chaîne à rechercher

Ajout du style au sample de test

searchWidget.html :

<style type="text/css" title="text/css">
    @import "../dijit/themes/dijit.css";
    @import "../dijit/themes/nihilo/nihilo.css";
  </style>

lignes :
10 : ajout des thèmes css « dijit » et « nihilo » du framework Dojo pour le design des boutons

<body class="nihilo">
<div id="search"></div>
</body>

lignes :
54 : ajout de la class « nihilo » à la balise body du sample

Définition du style du bouton à liste déroulante

search.css :

.floatLeft {
  float:left;
}
.greyBorder {
  border:1px solid #B0B0B0;
}
.search {  
  height:30px;
}
.search .btn {
  background: url(../images/loupe.png) no-repeat;
  width:20px;
  height:19px;
  border-left:0px;
  cursor:pointer;
}
.search input{  
  height:21px;
  font:13px verdana, sans-serif;
}
.nihilo .dijitDropDownButton .dijitReset {
  height:16px;
}
.nihilo .dijitDropDownButton {
  float: left;
  margin:0 !important;
}
.nihilo .dijitDropDownButton span {
  font:10px verdana, sans-serif;
}
.nihilo .dijitButtonNode {
  width:80px;
  border:1px solid #B0B0B0 !important;
  border-right:0px !important;
}

lignes :
8. ajout d’un espace entre le widget de recherche et la zone d’affichage
21 à 35. surcharge du style « nihilo » de Dojo

Affichage du résultat de la recherche

Affichage du résultat de la recherche dans une iframe.

Ajout de l’iframe au sample

searchWidget.html :

<body class="nihilo">
<div id="search"></div>
<iframe id="viewer"
    name="viewer"
    src="./static/empty.html"
    scrolling="yes"
    height="400"
    width="100%"
    frameborder="yes">
  </iframe>
</body>

Définition du contenu par défaut de l’iframe

empty.html :

<html>
  <head>
  </head>
  <body>
    Le r&eacute;sultat s'affichera dans cette iframe
  </body>
</html>

Affichage du résultat de la recherche dans l’iframe

Search.js :

remplacer :

console.log("url pour la recherche : ", url+escape(fieldValue));

par :

dojo.byId("viewer").src=url+escape(fieldValue);

Affichage des erreurs

Création d’une popup pour l’affichage des erreurs.

Affichage de la popup si la recherche ne peut être exécutée

Search.js :

else {
 
    var dialogbox = dijit.byId("dialogbox");
 
    var content = this._nls.ressources.popup;
    dialogbox.attr("title",this._nls.locale.popup.title);
    dialogbox.attr("content",dojo.string.substitute(content,{
        message:this._nls.locale.popup.message,
        btnLabel:this._nls.locale.popup.btnLabel
    }));                        
    dialogbox.show();  
  }

lignes :
144 : on stock le noeud DOM du sample sur lequel on affichera la boîte de dialogue
146 : wording correspondant à la popup
147 : titre de la popup
148 à 151 : ajout du contenu sous forme d’un template
153 : affichage de la boîte de dialogue

Ajout des propriétés de la popup dans le wording

nls/Locale.js :

{
 
  "searchWidget" : {
    "engines" : [
        "Google",
        "Yahoo",
        "Wikipedia"
    ],
    "popup": {
        "btnLabel":"OK",
        "message": "you must write more than one character",
        "title": "Error"
    },
    "search": "search",
    "send": "go",
    "text": "enter your keywords here..."
  }
 
})

nls/fr/Locale.js :

{
 
  "searchWidget" : {
    "engines" : [
        "Google",
        "Yahoo",
        "Wikipedia"
    ],
    "popup": {
        "btnLabel":"OK",
        "message": "Veuillez saisir au moins un caract\u00e8re",
        "title": "Erreur"
    },
    "search": "rechercher",
    "send": "lancer la recherche",
    "text": "saisir le texte ici..."
  }
 
})

lignes :
10 : label du bouton de la boîte de dialogue
11 : message d’erreur
12 : titre de la popup

note : encodage des accents en unicode.

Création du template de la popup dans les ressources

nls/Ressources.js :

:

({
 
  "searchWidget" : {
    "engines" : {
        "google": "http://www.google.com/search?q=",
        "yahoo": "http://uk.search.yahoo.com/search?p=",
        "wikipedia": "http://en.wikipedia.org/wiki/Special:Recherche?search="
    },
    "popup" : "
<table> \
<tr> \
<td>${message}</td>
\</tr>
\
<tr> \
<td align=\"center\"> \
				<button dojoType=\"dijit.form.Button\" type=\"submit\"> \
					${btnLabel}\
				</button></td>
\</tr>
\</table>
"
    } 
 
 })

nls/fr/Ressources.js :

({
 
  "searchWidget" : {
    "engines" : {
        "google": "http://www.google.fr/search?q=",
        "yahoo": "http://fr.search.yahoo.com/search?p=",
        "wikipedia": "http://fr.wikipedia.org/wiki/Special:Recherche?search="
    },
    "popup" : "
<table> \
<tr> \
<td>${message}</td>
\</tr>
\
<tr> \
<td align=\"center\"> \
				<button dojoType=\"dijit.form.Button\" type=\"submit\"> \
					${btnLabel}\
				</button></td>
\</tr>
\</table>
"
    } 
 
})

lignes :
9 à 20 : template de la boîte de dialogue. Le message d’erreur et le label du bouton peuvent être modifiés dynamiquement.

note : par simplicité, nous avons basé notre template sur un tableau HTML. Afin de respecter les normes WAI (Web Accessibility Initiative) pour l’accessibilité, préférez des balises div pour vos templates.

Ajout de la boîte de dialogue au sample de test

searchWidget.html :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset="utf-8" />
			<link rel="stylesheet" type="text/css" href="./css/search.css" />
<style type="text/css" title="text/css">
      @import "../dijit/themes/dijit.css";
      @import "../dijit/themes/nihilo/nihilo.css";
    </style>
 
    <script> 
 
	  var djConfig = {
        parseOnLoad: false,
        isDebug: true
      };
// ]]></script> <script type="text/javascript" language="javascript">// <![CDATA[
dojo.require("dojo.i18n");
      dojo.require("dijit.Dialog");
 
	  dojo.require("exemple1.widget.Search");
 
      dojo.addOnLoad(init);
 
      function init(){ 
 
        var _search = new exemple1.widget.Search({
          id:"search",
          text:"toto"
        }, dojo.byId("search"));                                
 
        _search.startup();
 
        var dialog = new dijit.Dialog({
			title: "title"
		}, dojo.byId("dialogbox"));
 
		dialog.startup();                                        
 
      }
// ]]></script>
<iframe id="viewer" height="240" width="320"></iframe> name="viewer" src="./static/empty.html" scrolling="yes" height="400" width="100%" frameborder="yes"&gt;

lignes :
29 : importation de la classe Dialog de la librairie dijit.
44 à 46 : instanciation de la boîte de dialogue.
48 : affichage de la boîte de dialogue.
64 : div qui sera remplacé par le widget Dialog.

Résultat final

Résultat final.


Berthenet Cyril

http://www.life-behind-the-mirror.com/codes/tutoDojo/myFirstWidget.php

Publié dans tutoriels Tagués avec :

Tracer les dojo.publish pour faciliter le développement et le debug


Je rebondis sur un article publié ici http://www.vodori.com/vodori/archives/277 pour vous proposer moi aussi un petit bookmarklet qui va vous permettre d’afficher dans la console de firebug tous les dojo.publish qui seront exécuté dans votre application Web.

Installer le bookmarklet

Pour installer le bookmarklet, faites simplement glisser le lien suivant dans vos marques-pages :
Afficher les dojo. publish.

L’utiliser

Une fois installé, l’utilisation est simple. Il vous suffit de charger la page qui utilise Dojo et de cliquer sur le marque-page que vous venez d’ajouter.

Comprendre le bookmarklet

Celui-ci se décompose en 2 parties :

  • Ce qui transforme votre code javascript en bookmarklet :
    javascript:(
    function(){
    /* code qui va activer les traces*/
    })();
  • Et ce qui va ajouter des informations de trace aux méthodes Dojo.

Tracer les méthodes de Dojo

Pour tracer une méthode Dojo, nous allons simplement utiliser un dojo.connect et ajouter une ligne dans la console.
Pour notre bookmarklet, c’est dojo.publish qui nous intéresse donc :

dojo.connect(dojo,'publish',function() {
console.warn('dojo.publish(', arguments,')');
});

De la même façon, vous pourriez afficher des traces à chaque fois qu’un dojo.connect est exécuté :

dojo.connect(dojo,'connect',function() {
console.warn('dojo.connect(', arguments,')');
});

Note : Afin d’éviter les fuites mémoire, il est important que tous les dojo.connect de votre application soit ensuite déconnectés.
Ces traces peuvent donc vous aider à vérifier que chaque dojo.connect a son opposé (dojo.disconnect).

Le code complet du bookmarklet

Finalement, votre bookmarklet devrait ressembler à ceci :

javascript:(
function(){
dojo.connect(dojo,'publish',function() {
console.warn('dojo.publish(', arguments,')');
});
})();

Un peu de fioriture plus loin, votre bookmarklet est fin prêt :

javascript:(
function(){
if(typeof dojo=='undefined'){
console.error('Dojo est ind\u00e9fini');
return;
}else{
dojo.connect(dojo,'publish',function() {
console.warn('dojo.publish(', arguments,')');
});
console.info('Trace de dojo.publish activ\u00e9e');
};
})();

Il ne reste plus qu’a adapter ceci selon vous besoin pour créer vos propres bookmarklet.

Publié dans astuces Tagués avec :

Démystifier Dojo Toolkit


Traduit de : http://www.sitepen.com/blog/2008/10/27/debunking-dojo-toolkit-myths/

Dojo Toolkit existe depuis plus de 4 ans et a subît des changements significatifs, certains énormes d’autres plus petit, pour devenir un grand toolkit JavaScript. Cet article a pour but de supprimer les mythes et a priori (aussi grotesque que faux) qui entourent Dojo depuis le début de son développement.

Dojo n’est pas documenté

Loin s’en faut ! Au tout départ, la documentation de Dojo était le code source. Aujourd’hui nous avons une énorme quantité d’information disponible, et nous travaillons sur une meilleure organisation ainsi qu’un affinage de ces dernières.
Pour commencer, vous pouvez regarder Dojo QuickStart Guide, Dojo API Viewer et le projet de documentation de Dojo Campus (qui remplacera prochainement le vénérable Dojo Book)
Vous voulez une doc hors-ligne ? Utilisez Dojo Toolbox pour le moment et bientôt le projet de documentation de Dojo Campus sera aussi disponible.
Besoin d’un livre ? Vous pouvez choisir parmi 4 grands livres traitants exclusivement de Dojo.
Besoin d’un tutoriel ou d’un article ? Essayez l’un des cent et quelques liens.
Vous voulez voir des démos ? Faites un tour sur le Dojo Campus Feature Explorer ou sur le Dojo Spotlight.
Besoin de travaux pratiques ? Contactez l’assistance SitePen.
Est-ce que Dojo va continuer de simplifier et d’enrichir sa documentation ? Absolument, et nous apprécierons toutes votre aide et vos retours.

Dojo est lent

Toutes les librairies JavaScript peuvent être lentes si elles sont mal utilisées. Durant la période Dojo 0.4, il était très simple de créer une application lente car le parseur était activé par défaut et qu’il incluait tout un tas de fichiers externes et de codes source.
Aujourd’hui, le parseur est uniquement dans Dijit et n’est le problème que de ce dernier. Dojo est différent de Dijit, et aujourd’hui vous ne subissez les baisses de performance du parseur (qui sont bien plus faible qu’a l’époque de Dojo 0.4) que si vous avez besoin d’un environnement de widget complet.

Depuis les 18 derniers mois, Dojo a rendu simple la création de chose légère et rapide. Toutes les fonctionnalités de qui était dans Dojo 0.4 sont au moins 100% plus rapide dans le Dojo actuel, et certaines parties sont même 1000% plus rapide, voire plus. Les mesures de performance effectués avec SlickSpeed test suite sur les requêtes montre que dojo.query est aussi rapide, sinon plus, que la plus part des autres toolkits majeurs.

Et Dojo offre une pléthore de techniques et de suggestions d’optimisation pour faire gagner quelques Ko et millisecondes à votre code source. Être performant, fiable et cross-browser est un art guidé par les données qui requiert de laisser beaucoup d’idées reçues devant la porte, d’écouter les données, et faire des compromis si nécessaire.

Dojo est gonflé, plus gros et plus complexe que Prototype, jQuery, MooTools, YUI, etc.

Dojo est conçu pour vous fournir les outils nécessaires pour résoudre de problèmes complexes, tout en gardant simple les choses simples. Ce mythe existe uniquement parce que nous utilisons un système que packaging et que nous encourageons les développeurs à utiliser notre système de packaging pour optimiser les performances. Si vous téléchargez le code source complet de Dojo vous allez voir beaucoup de fichiers. De tous ces fichiers, vous ne devez en inclure qu’un seul avec une balise script dans votre code.
Nous avons rendu simple vos premiers pas en permettant d’inclure simplement dojo.js depuis les serveurs de contenu AOL ou Google. Nous appelons dojo.js « Dojo Base ». Il fait 26Ko (gzippé) et est comparable en taille, caractéristique, performances et fonctionnalités aux autres toolkit majeur.
Dojo Base fourni un set de fonctionnalités extrêmement riche et léger, utile à tous les développeurs web. Je pense qu’il vous sera difficile de trouver plus de fonctionnalités et de puissance dans moins de Ko.
Si 26Ko est encore trop vous pouvez aussi utiliser une version réduite de Dojo qui tient dans 5.5 Ko. Elle n’intègre que le module de chargement d’éléments de Dojo puis ajoute au fur et à mesure les fonctionnalités exactes dont vous avez besoin. Vous pouvez aussi prendre le Dojo SDK complet et le réduire à ce dont vous avez besoin.

Dans un navigateur, toutes les fonctionnalités ajoutent une légère baisse de performance, c’est pourquoi Dojo offre la flexibilité nécessaire pour n’inclure que ce dont vous avez besoin et rien de plus tout en offrant une énorme quantité de fonctionnalités, de manière organisé et cohérente. Si vous désirez utiliser plus de fonctionnalités de Dojo — c’est complètement optionnel — vous n’avez qu’à utiliser dojo.require pour ajouter ce dont vous avez besoin. La structure des classes, dans la plus part des cas, suit la structure logique des répertoires de votre projet. Par exemple, dijit.foo.Bar devrait se trouver dans /dijit/foo/Bar.js.

Ce système simple de namespace et d’inclusion facilite l’utilisation des codes Dojo et de ceux qui suivent ces règles. Ceci facilite la création d’applications avancées et puissantes autant que celle de fonctionnalités simples telles que le Dojo Flickr Badge.

Le système de package Dojo, s’il ajoute une légère complexité qui ne prend que 2 minutes à comprendre pour un nouveau développeur, le rend plus lisible et organisé. Il vous offre aussi la capacité de gérer simplement votre code quand la quantité de dépendance et d’inclusions auraient pu le rendre peu maniable. Dojo est une librairie et se comporte comme tel. Comme Java et beaucoup d’autre langage, nous n’incluons automatiquement que le strict minimum de code, et mettons a votre disposition une quantité d’autre package que vous pouvez inclure manuellement.
A l’intérieur de Dojo se trouve divers framework. Le plus largement connu étant Dijit. Les widgets de Dijit ont des dépendances avec le code du framework. Cette sorte de longue chaine de dépendance est rare dans Dojo, mais existe lorsque l’on a besoin de fournir des fonctionnalités plus riche.

Dojo à besoin de Java

Pas du tout, même s’il est vrai que le SDK complet de Dojo inclut quelques fichier jar.
En plus des capacités natives au navigateur, Dojo fourni de manière complètement optionnelles des outils (basé sur Rhino) d’optimisation de votre code, pour gagner en performance lors du processus de packaging. Rhino est le moteur JavaScript de la Fondation Mozilla, implémenté en Java.
Pourquoi voulons-nous toujours « builder » le JavaScript ? Pour réduire la taille de votre code, optimiser le cache, et réduire le nombre d’appel au serveur. Par exemple, vous pouvez fusionner les règles CSS, et incorporer les ressources HTML utilisées par les widgets directement dans le code JavaScript, en tant que chaine de caractère. Tous ça pour réduire le nombre de requête HTTP, la taille des fichiers et bien plus.

Dojo est verbeux et est « du Java pour JavaScript »

La seule chose dans Dojo qui ressemble à Java est notre désir d’inclure les éléments dans des namespaces. Notre structure de librairie encourage toujours la brièveté d’écriture, en mettant les fonctionnalités de Dojo Base directement dans le namespace Dojo*.
Dojo préfère dojo.byId et dojo.query plutôt que $, bien qu’il soit très facile d’utiliser votre propre fonction si vous le désirez.

Dojo préfère tout placer dans des namespaces pour réduire notre présence dans le namespace global, et ceci afin de permettre à Dojo de coexister avec d’autres librairies ou bout de code sans jamais avoir de problème de conflit de nommage. De plus, Dojo minimise la surcharge de fonction, ainsi l’utilisation complète des APIs n’entrave pas la maintenance du code.
Par souci de rapidité, tous ce qui est fortement utilisé est typiquement dans le namespace le plus haut d’une manière courte et simple à retenir, exemple dojo.connect et dojo.attr. La concision de notre API et la structure des namespaces ont tendance à étonner les gens qui n’ont pas utilisé Dojo depuis la 0.4 ou même avant.
Chaque composant est une « chose » distincte et nos seules options sont de l’adresser dans le namespace global (ce qui pourrait engendrer des conflits) ou de l’accrocher dans Dojo.
On peut admettre que certains toolkit n’ont pas de namespace simplement parce qu’ils ne fournissent pas assez de code pour en avoir besoin.
Les développeurs Java aiment vraiment Dojo (ou DWR ou même GWT ou Ext), vraisemblablement pour la largeur, la profondeur, et l’organisation des ses API.

Une grande partie de l’inspiration de Dojo est dérivée du Python, d’AOP, de PHP, de Java, ainsi que variété de construction fonctionnelle telle que hitch, mixins, delegation, et plus. De plus, nous refusons explicitement l’utilisation de quelconques patterns provenant d’autre langage, et nous faisons d’énorme effort pour faire de notre JavaScript un pattern unique.

Les constructeurs du Toolkit tels que dojo.declare() peuvent être considéré comme identique à Java, quoi que la plus part des librairies ont une sorte de modèle de constructeur et d’héritage. Dojo tire avantage de la flexibilité du JavaScript plutôt que d’essayer de fournir une gestion spécifique issue d’un autre langage que le JavaScript.

Dojo est uniquement utile pour les applications d’entreprise et surement pas pour de petits sites ou des blogs

Ce mythe existe parce que Dojo n’était pas aussi petit et simple dans Dojo 0.4 qu’il ne l’est aujourd’hui. Dojo Base fait 26Ko gzippé et Dojo Mini descend jusqu’à 5.5Ko. Les deux disposent de la même facilité d’utilisation des API, ce qui rend possible de faire facilement des améliorations progressives, du JavaScript non intrusif, de la récupération d’événements, de l’Ajax, des animations, du DOM, du querying, et bien plus.

Dojo n’est pas pour des applications sur une seule page

Les développeurs de Cappuccino, Objective-J et Sprout Core, argue qu’ils ont créé leur toolkit parce que les autres ne sont pas optimisé pour de réelle application dans un navigateur. Selon nous, c’est n’importe quoi.
Dojo est grandement utilisé dans des applications riches par une foule de société comme Sun Convergence, WebEx Connect de Cisco et Project Zero d’ IBM. Dojo est aussi très fortement utilisé pour créer des applications intranet, dans ce que j’appelle Ajax Dark Matter.

Dojo n’est pas pour les applications multipages et pour les sites web

Alors qu’il est peu probable qu’une personne croit en ce mythe et au précédent en même temps, ce point de vue n’est que perspective. Étant donné la taille du toolkit, certaines personnes ont supposée que Dojo ne devrait pas être utilisé pour des sites multipages, mais les options étendues d’optimisation de Dojo font de ce cas d’usage une force. L’Eye-Fi Manager ainsi que le site de la fondation Dojo lui-même montre combien sont rapides (à la fois d’éxécution et de chargement) ces applications et sites.

Dojo c’est juste pour les widgets

Dojo à un système de widgets hautement flexible, et extrêmement rapide appelé Dijit. Il s’agit d’un package complètement optionnel pour les gens qui ont besoin d’utiliser et de créer leurs propres widgets. C’est conçus pour répondre à une variété de cas d’utilisation de manière modulaire, en incluant l’accessibilité, l’internationalisation, la mise en page, la gestion de conteneur, les templates et bien plus. Le concept sous-jacent est que chaque widgets est simplement un template HTML, un template CSS et un fichier JavaScript pour la logique.
La plus part des utilisateurs n’ont jamais touché à Dijit.
Il existe d’autre moyen d’obtenir des comportements légers et réutilisables comme le montre l’implémentation de Django Templating Language (DTL) dans Dojo.

L’intérêt pour Dojo décline

Pourquoi les gens pensent ça ? Peut-être une mauvaise interprétation des stats. Les gens comparent les stats Google pour des recherches comme « jQuery JavaScript » « Prototype JavaScript » « Dojo JavaScript », etc. parce que les mots qu’ils contiennent sont en conflit avec des termes de recherche généraux. Mensonge, foutu mensonge, et les statistiques d’utilisation, hein ?
Tandis que l’intérêt des autres grands toolkit a grossi de façon significative, l’utilisation de Dojo en fait de même. En se basant sur le nombre d’applications déployées, le nombre de téléchargement, le trafic sur le site, les livres vendus et quantité d’autre statistique, on peut dire que Dojo continu de grossir très rapidement. De part chaque mesure, on constate que l’intérêt en Dojo croit plus vite que jamais.
Ajax est devenu de plus en plus populaire et l’on considère maintenant JavaScript comme un vrai langage. Dojo à toujours traiter JavaScript comme un langage de première classe, et c’est concentré strictement sur l’utilité plus que sur un aspect particulier du workflow, comme le DOM.

Dojo n’est pas valide

Une longue et persistante plainte est que Dojo n’est pas valide. DTD != d’HTML valide. Les attributs personnalisés ont toujours été de l’HTML valide, c’est juste qu’ils ne sont pas validé lorsqu’on les teste avec une DTD.
Si la validation DTD est véritablement importante pour votre projet, il aussi bien simple d’utiliser Dojo avec élégante dégradation ; l’utilisation des attributs personnalisés est un pattern d’implémentation uniquement, pas un pré-requis pour Dojo. Sinon, vous pouvez toujours créer votre propre DTD.
En plus des bénéfices de performance et de l’efficacité des attributs personnalisés, ils sont bien plus utilisables et proche de notre compréhension que les autres options. Par exemple, certain toolkit utilise l’attribut rel et le remplisse de data. Le populaire meta plugin de jQuery ressemble à ça :

<div class="hilight { background: 'red', foreground: 'white' }">

. Pourquoi est-ce mieux que la syntaxe Dojo qui aurait put être :

<div jQueryType="hilight" background="red" foreground="white">

?
La spécification HTML fait état que tout les attributs non reconnu sont ignoré par les moteurs de rendu HTML dans les applications, et Dojo profite optionnellement des ces avantages pour améliorer la facilité de développement.

Dojo est laid

Créer de belles applications web demande une grande connaissance du style, de l’interactivité, de l’expérience utilisateur et des possibilités graphique. Dojo fourni 3 thème professionnel : Tundra, Soria et Nihilo. Si vous voulez les améliorer ou créer votre propre thème alors soyez impliqué!
Les thèmes de Dojo sont délibérément minimaliste pour rendre facilement adaptable les composants à des designs ou des marques existantes. Mais chez SitePen, dans nos travaux pour des clients nous avons appliqué nos CSS et nos designs sur des applications basés sur Dojo afin de créer d’excellent design et des expériences époustouflantes.

http://www.sun.com/software/convergence/

http://www.sitepen.com/blog/2007/11/11/eye-fi-launches/

http://www.sitepen.com/blog/2008/10/14/dojo-sensei-reader/

Beaucoup d’autre société ont aussi réussit à appliquer leur propre thème à des applications basé sur Dojo.

http://dojotoolkit.org/spotlight/esri

Dojo n’offre pas certaines fonctionnalités fournis par une librairie particulière

C’est peut-être le cas, ou c’est peut être appelé autrement, ou disponible dans une API différente. Mais Dojo offre une extrême flexibilité. Par exemple, consultez le travail de Peter Higgins pour ajouter l’API de footprint de jQuery qu’il aime et qui manque dans Dojo en mois de 1Ko.

Dojo ne fonctionne pas avec un toolkit, un environnement ou un serveur particulier

Nous faisons tout pour nous assurer que Dojo fonctionne avec tout, même si un toolkit ou un serveur ne dispose pas de ce que nous souhaiterions. Si quelque chose ne fonctionne pas pour vous, posez la question du les forums Dojo ou au support SitePen, et s’il s’agit d’un bug, ouvrez un ticket et il sera fixé au plus vite. Nous avons poussé très loin pour être sur que Dojo fonctionne bien avec tous les toolkit populaire, aussi bien que dans une variété d’environnement tel que : XUL, ligne de commande, Jaxer, Air, etc., le support des préconisations de l’alliance OpenAjax autant que l’intégration avec DWR, Persevere, Zend Framework, IBM Websphere, Django, Ruby On Rails, et beaucoup, beaucoup plus.
Dojo a été initialement conçut pour arrêté de réinventé la roue du DHTML, avec un code source original significativement basé sur le travail de toolkit plus anciens comme netWindows, BurstLib, et f(m).

Les gens chez Dojo n’aiment pas de projet en particulier

En général, d’un point de vue interpersonnel, nous sommes amis avec les gens qui on créé jQuery, Prototype, YUI, MooTools, et autre. Même si bien sûr les développeurs de Dojo ont des opinions différentes sur la meilleure approche pour le développement (les grands développeurs devrais toujours être en désaccord, tant qu’ils gardent le débat centré sur le mérite plus que sur la forme du message). Nous avons trouvé des fans de Dojo et d’autre toolkits qui essaye de créer une plus grande rivalité que les auteurs de toolkit ne le font. Après tout, nous sommes en train de parler de toolkit open source qui sont sous licence libre (BSD, AFL, MIT, Apache, etc.), donc il est dur pour nous de pas s’étendre. Alex Russel, Peter Higgins et moi sommes aussi sur un enregistrement pour inviter les autres toolkit à collaborer et coopérer pour encore une fois arrêter de réinventer la roue.

The Ajax Experience Browser incompatibility panel

Dans la plus part des cas, c’est un problème de perspective. Je sais que beaucoup d’entre nous restent bloqués non par parce que quelqu’un a mal fait son travail mais parce que certaines personnes critiquent les fonctionnalités d’un toolkit au profit d’un autre s’en même comprendre pourquoi cette fonctionnalité existe.

Il est difficile de contribuer à Dojo ou d’être impliqué

A la différence de beaucoup de toolkit, Dojo requiert une CLA qui protège les droits de votre IP, et aussi requiert que pour contribuer au code, vous en aillez le droit. La fondation Dojo fait cela pour être certaine que nous seront capable de redistribuer chaque partie du code présent dans le Toolkit de manière complètement gratuite, et sous licence libre. C’est un processus simple qui doit prendre maximum 15 minutes et il vaut bien ce petit effort.
Pour plus d’informations sur comment s’impliquer, contribuer, faire un don, visitez le site de la fondation Dojo et celui de Dojo Toolkit ou venez sur le salon irc de Dojo sur irc.freenode.net dans #dojo

Dojo manque de support commercial

Un certain nombre de société, en incluant SitePen, offre des services de développement, d’entrainement et de support pour Dojo. La communauté Dojo offre un magnifique support gratuit, mais quand les problèmes dépasse ce qu’il est raisonnable de demandé à un bénévole, ou ont besoin d’être pris en compte immédiatement et/ou sous un accord de non divulgation, les sociétés comme SitePen sont disponible pour vous aider à être productif, du fixe de bug dans Dojo jusqu’à packager et designer votre application.

Résumé

Comme vous pouvez le voir, Dojo a parcouru un long chemin depuis sa création initiale il y a plus de 4 ans. Pendant les prochains mois, les développeurs de Dojo vont continuer à améliorer les sources du toolkit, la documentation, et le marketing afin de rendre Dojo simple a utilisé sur tous types d’application ou de site web que vous développez.

J’espère que vous prendrez la décision d’utiliser, ou pas, Dojo en vous basant sur le mérite plutôt que sur des mythes ou des informations qui ne sont plus ou n’ont jamais été exactes.

Dylan Schiemann

Publié dans actualités