HighCharts : Dojo Adapter

Pour ceux qui ne connaissent pas, Highcharts est une librairie très complète écrite en pure JavaScript et permettant de générer des graphiques.

Elle offre un des graphs intuitifs et interactifs.

Highcharts supporte de nombreux formats de graphs : line, spline, area, areaspline, column, bar, pie et scatter.

Cette librairie fonctionne nativement avec jQuery, mais est conçut pour s’interfacer avec d’autres libraires, en utilisant un Adapter.

Les releases actuelles (Highcharts 2.2.1Highstock 1.1.5) sont livrées avec un adapter Mootools et Prototype mais rien pour Dojo…

Alors… Je m’en suis occupé.
Et voici donc sans plus attendre, l’Adapter Dojo pour Highchartsdojo-adapter

Et n’oubliez pas, si vous aimez, donnez ;)

Note: Si vous rencontrez des problemes avec le « Navigator » de HighChart, vous devez appliquer ce patch.

Mise a jour 07/11/2012 : Ajout de la fonction inArray

Mise a jour 29/08/2012 : Bug Fix dans les animations

Mise a jour 10/07/2012 : Bug Fix

Mise a jour 03/07/2012 : Prise en charge de HighStock 1.1.6

Mise a jour 28/05/2012 : Ajout de la normalisation des évènements pour éviter d’avoir des erreurs sous IE (type pageX is not defined)

4 commentaires

Dojo version 1.6

 

Depuis le début de l’année 2011, deux versions de DojoToolkit sont sorties : la version 1.6.0 et la version 1.6.1.

 

Principales nouveautés et changements de la version 1.6.0

 

Navigateurs supportés

Il n’y a pas de changement par rapport à la version 1.5 excepté pour Chrome où l’on passe de la version 5 à la version 8 :

  • Firefox 3.6
  • Safari 4/Safari 5 and Chrome 8
  • IE6, IE7, IE8
  • Opera 10.50 and later (Dojo core seulement)

 

AMD

Préparation au support de AMD( Modules/AsynchronousDefinition). Cette fonctionnalité sera effective dans la version 1.7.

 

djConfig

L’utilisation de la variable djConfig n’est plus recommandée. Son utilisation ne sera plus possible à partir de Dojo v2.0. Il faut remplacer djConfig par dojoConfig.

  1. var dojoConfig = { parseOnLoad:true }

 

Les attributs data de HTML5

Dojo permet de déclarer des widgets et d’indiquer d’autres informations directement dans  le HTML. Afin d’être compatible avec la syntaxe HTML 5, ces attributs sont préfixés par data-dojo- (cf spec HTML 5).

djConfig est remplacé par data-dojo-config

  1.  

 

L’attribut jsId est remplacé par  data-dojo-id

 

<div data-dojo-id="bar" data-dojo-type="some.Thinger">I am exported to window.bar by reference</div>

 

L’attribut dojoType est remplacé par  data-dojo-type

<div data-dojo-type="dijit.form.Button" data-dojo-props="disabled:true, onClick: someNamedFunction">Click</div>

 

remarque : Tous les anciens attributs sont opérationnels jusqu’à la version 2.0

 

Graphiques

Deux nouveaux types de graphique ont été ajoutés : le graphique en radar (ou toile d’araignée) et le diagramme de Gantt.

Dojo Websockets

Dojo version 1.6 introduit une nouvelle api permettant une communication en temps réelle du style Comet. Cette api est basé sur la WebSocket api qui permet de réaliser une connexion bi-directionnelle idéale pour envoyé (push) en temps réel des messages du serveur vers le client.

 

Thème

L’adoption du framework Less va rendre plus facile et plus rapide la personnalisation des feuilles de style.

 

Object store

La réécriture des classes de stockage rend plus facile à utiliser dans la classe data.store

 

Changements de la version 1.6.1

Cette version étant une version mineure, elle apporte des corrections de bugs et quelques améliorations mineures. Cependant, il faut noter que Dojo supporte maintenant Internet Explorer 9 et Firefox 4.

 

Marqué avec , | Laisser un commentaire

utiliser Dojo pour un site en plusieurs langues

Voici un petit tutoriel pour vous expliquer comment utiliser « requireLocalization » de Dojo pour un site en plusieurs langues.
Merci à ManiT4c

1. Création des fichiers langues


La première étape consiste à créer les fichiers langues et à les placer dans les bons dossiers. Pour notre exemple le site ne comportera que deux langues: l’Anglais et le Français.

  • Dans le dossier « dojo » créez un dossier nommé « langue » puis un sous dossier « nls » puis enfin un sous dossier par langue c’est à dire « en » et « fr » dans notre cas.
  • Dans chaque dossier « nls », « en » et « fr » vous devrez placer un fichier « langue.js »

Les fichiers « langue.js » contenu dans les dossiers « en » et « fr » seront respectivement utilisés pour les visiteurs anglophone et francophone, tandis que le fichier « langue.js » placé dans le dossier « nls » sera le fichier langue par défaut. C’est à dire celui qui sera utilisé si aucune langue n’est détectée.

2. Modification du djConfig

Maintenant il faut préciser à dojo la langue utilisée, vous avez pour cela deux possibilités: soit vous laissez dojo détecter la langue du navigateur, soit vous l’indiquez directement lors du chargement de dojo.


Pour ma part je préfère utiliser la seconde méthode. Pour cela il suffit de préciser lors de l’appel de dojo la langue utilisée dans l’attribut « djConfig ».

  1. <script type="text/javascript" src="dojo/dojo/dojo.js" djConfig="parseOnLoad: true, locale:'fr'"></script>

Il faut ici préciser la langue entre les guillemets ‘fr’ pour français ‘en’ pour anglais. Cela correspond au dossiers que vous avez précédemment créé dans ‘dojo/langue/nls’.

3. dojo.requireLocalization et dojo.i18n

Il faut maintenant demander à dojo de prendre en compte la localisation afin de charger le bon fichier de langue. Il suffit pour cela de rajouter (après avoir charger dojo bien sûr) les lignes suivantes.

  1. dojo.require("dojo.i18n");
  2. dojo.requireLocalization("langue", "langue");

Pour « requireLocalization » le premier argument sera le nom du dossier que vous avez créé dans « dojo ». Le second argument sera le nom du fichier à appeler (sans l’extension « .js »). C’est ce qui permettra à dojo de savoir où trouver le fichier langue adéquate.


Il cherchera donc le fichier « langue.js » dans « dojo/langue/nls » (« nls » étant ajouté automatiquement par dojo) et dans le dossier correspondant à la langue de l’utilisateur.


A noter: Il est important que les dossiers de langue (« en », « fr »,etc..) correspondent à la localisation indiquée dans « djConfig ».

4. Contenu des fichiers langues

Il faut maintenant remplir vos fichiers langues avec vos différents termes. Nous allons ici n’en ajouter que deux mais vous n’aurez bien évidemment aucune limite à ce niveau.


Contenu du fichier « langue.js » du dossier « fr »

  1. ({
  2. bonjour:"Bonjour",
  3. toi:"toi",
  4. })

Contenu du fichier « langue.js » du dossier « en »

  1. ({
  2. bonjour:"Hello",
  3. toi:"you"
  4. })

Pour le fichier « langue.js » contenu dans le dossier « nls » je vous propose de copier la même chose que pour le fichier compris dans le dossier « fr ». Nous considérerons ainsi que la langue par défaut sera le français.

5. Création et utilisation de l’objet « lang »

Maintenant que tout est prêt, vous pouvez utiliser vos différents fichiers de langue.


Voici une petite fonction pour tester tous ça:

  1. function testLangue() {
  2. var lang = dojo.i18n.getLocalization("langue", "langue");
  3. alert(lang.bonjour+" "+lang.you);
  4. }

Et voila il ne vous reste plus qu’à lancer cette fonction en faisant varier à chaque fois la localisation dans « djConfig » pour constater que le texte de l’alerte change.

Marqué avec , , | Laisser un commentaire

Créer un formulaire d’inscription avec dojo

Dojo est particulièrement efficace lorsqu’il s’agit de faire de la validation de formulaire.
Je vais ici vous proposer un tutoriel étape par étape qui va vous permettre de créer un formulaire d’inscription basique, avec les vérifications nécessaires.
Le formulaire en question ne comportera que 4 champs: Email, vérification de l’email, mot de passe et vérification du mot de passe.

Pour info: Je suis un webmaster indépendant situé en Normandie.

Etape 1

Téléchargez la dernière version de dojo (ici) et la décompresser dans le dossier comprenant votre site. Pour plus de simplicité je renomme le dossier « dojo-release-x.x.x » en dojo pour me retrouver avec comme arborescence:
monsite/dojo/dijit
monsite/dojo/dojo
monsite/dojo/dojox

Etape 2

Je créé mon fichier « acces_pro.php » (ouai, pour le coup, je vous fait le tuto en temps réel car je développe un site avec un accès professionnel. Libre à vous de renommer les fichiers comme bon vous semblera) et j’y insère les entêtes HTML nécessaires

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  5. <title></title>
  6. <meta name="description" content="" />
  7. <meta name="keywords" content="" />
  8. </head>
  9. <body>

D’avance pour pas oublier je referme mes balises à la fin de mon fichier

  1. </body>
  2. </html>

Etape 3

J’appelle mon fichier dojo.js pour pouvoir utiliser les fonctions qu’il contiens, Pour cela je place entre les balises et de mon fichier le code suivant

  1. <script type="text/javascript" src="dojo/dojo.js" djConfig="parseOnLoad: true"></script>

djConfig= « parseOnLoad:true » indique à dojo de scanner le fichier une fois celui-ci chargé pour trouver des instructions « dojo ».

Etape 4

J’indique ensuite qu’elles sont les fonctions qui vont être utilisées dans mon fichier. Je rajoute donc le code suivant entre les balises

  1. <head>

et

  1. </head>
  1. <script type="text/javascript">
  2.    dojo.require("dijit.form.ValidationTextBox");
  3.    dojo.require("dojox.validate.regexp");
  4.    dojo.require("dijit.form.Form");
  5.    dojo.require("dijit.form.Button");
  6. </script>

dijit.form.ValidationTextBox permet d’utiliser les fonctions de validation des champ de texte.
dojox.validate.regexp contient des expression régulière toute faites (très utile dans notre cas).
dijit.form.Form permet de transformer le formulaire en widget.
dojo.require(« dijit.form.Button ») permet d’utiliser les widget bouton.

Etape 5

On ajoute maintenant les fichiers css nécessaires en plaçant ce code entre les balises

  1. <head>

et

  1. </head>
  1. <link rel="stylesheet" href="dojo/dojo/resources/dojo.css" />
  2. <link rel="stylesheet" href="dojo/dijit/themes/tundra/tundra.css" />

tundra.css correspond au fichier css du thème tundra il en existe d’autre et vous pouvez créer vous même votre propre thème css.

Etape 6

On applique le thème tundra au document en ajoutant la class tundra sur la balise body

  1. <body class="tundra">

Etape 7

On ajoute les balises qui vont créer le formulaire

  1. <form action="acces_pro.php" method="post" enctype="multipart/form-data" id="formInscription" dojoType="dijit.form.Form">
  2. </form>

l’id nous servira par la suite lors de la validation globale du formulaire
le dojoType permet de signaler à dojo que cet élément est un formulaire.

On placera les codes qui vont suivre à l’intérieur des balise

  1. <form>

et

  1. </form>

Etape 8

On place notre premier champ email en utilisant le code dojo suivant:

  1. Email:
  2. <input id="email1" type="text" name="email1" class="long" value=""
  3.     dojoType="dijit.form.ValidationTextBox"
  4.     regExpGen="dojox.validate.regexp.emailAddress"
  5.     trim="true"
  6.     required="true"
  7.     invalidMessage="Email non valide." /><br />

- dojoType permet de signaler à dojo à quel type de champ on à a faire.
- RegExpGen permet de vérifier le format de ce qui sera tapé dans ce champ (ici un email)
- trim permet de supprimer les espaces avant et après le texte tapé dans le champ
- required indique que le champ ne peut rester vide
- invalidMessage vous permet d’indiquer le texte qui sera affiché si le champ est mal rempli.

Etape 9

On place le second champ email en ajoutant une vérification par rapport au premier.

  1. Confirmation email:
  2.     <input type="text" name="email2" class="long" value=""
  3. 	    dojoType="dijit.form.ValidationTextBox"
  4. 	    trim="true"
  5. 	    required="true"
  6. 	    validator="return this.getValue() == dijit.byId('email1').getValue()"
  7. 	    invalidMessage="Retapez votre email à l'identique ici" /><br />

- On a supprimer le regExpGen qui devient inutile (car on fait une vérification sur un champ sensé être valide)
- validator permet de vérifier que la valeur du champ est identique à celle du champ email précédent. On fait référence au premier champ email en utilisant l’id « email1 »

Etape 10

On ajoute notre premier champ mot de passe.

  1.  mot de passe:
  2.     <input type="password"
  3.     	id="mdp1"
  4.     	name="mdp1"
  5.     	dojoType="dijit.form.ValidationTextBox"
  6.     	required="true"
  7.     	trim="true"
  8.     	invalidMessage="Le mot de passe est nécessaire" /><br />

Rien de nouveau ici.

Etape 11

On ajoute notre champ de confirmation de mot de passe.

  1. Confirmation mot de passe:  
  2. 	<input type="password"
  3.     	name="mdp2"
  4.     	dojoType="dijit.form.ValidationTextBox"
  5.     	required="true"
  6.     	trim="true"
  7.     	validator="return this.getValue() == dijit.byId('mdp1').getValue()"
  8.      	invalidMessage="Retapez votre mot de passe à l'identique ici" /><br />

Ici on utilise à nouveau validator pour vérifier que les champs mot de passe son identiques. L’idée utilisée pour faire référence au premier champ mot de passe est ici « mdp1 »

Etape 12

On ajoute un bouton qui va soumettre le formuaire après avoir vérifié que tous les champs étaient correctement remplis.

  1. <input type="submit" label="inscription" dojoType="dijit.form.Button" onClick="dijit.byId('formInscription').validate();"/>

l’instruction dijit.byId(‘formInscription’).validate() ajouté dans le onclick permet de vérifier la validité de tous les champs du formulaire dont l’id est « formInscription » au moment du clic sur le bouton.

Voilà votre formulaire est terminé et les validations sont en place.

Marqué avec | Un commentaire

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

    1. /**********************************************/
    2. /*                                            */
    3. /* Widget : Search                            */
    4. /* Author : Berthenet Cyril                   */
    5. /*                                            */
    6. /**********************************************/
    1. dojo.provide("exemple2.widget.Search");
    2.  
    3. dojo.require("dijit._Templated");
    4. dojo.require("dijit._Widget");
    5.  
    6. dojo.require("dijit.form.Button");
    7. dojo.require("dijit.Menu");
    8.  
    9. dojo.requireLocalization("exemple2", "Locale");
    10. dojo.requireLocalization("exemple2", "Ressources");
    11.  
    12. /* Class: Search */
    13. dojo.declare("exemple2.widget.Search", [dijit._Widget,dijit._Templated], {
    14.  
    15. /* Object: _nls
    16. stockage du wording et des ressources du widget */
    17. _nls:{locale:null,ressources:null},
    18.  
    19. /* String: templatePath
    20. chemin d'acces vers le template du widget */
    21. templatePath: dojo.moduleUrl("exemple2.widget", "template/Search.html"),
    22.  
    23. /* Object: _dropdown
    24. Bouton de selection du moteur de recherche */
    25. _dropdown:null,
    26.  
    27. /* Array: _engines
    28. Liste des moteurs de recherche */
    29. _engines:null,
    30.  
    31. /* Function: constructor
    32. Constructeur */
    33. constructor: function(){
    34. console.log("exemple2.widget.Search::constructor");
    35. this._nls.locale=
    36. dojo.i18n.getLocalization("exemple2","Locale").searchWidget;
    37. this._nls.ressources=
    38. dojo.i18n.getLocalization("exemple2","Ressources").searchWidget;
    39. this._engines=this._nls.locale.engines;
    40. this._dropdown={};
    41. },
    42.  
    43. /* Function: destroy
    44. Destructeur */
    45. destroy: function(){
    46. console.log("exemple2.widget.Search::destroy");
    47. this.inherited("destroy",arguments);
    48. if(this._dropdown){this._dropdown.destroy();}
    49. delete this._nls;
    50. delete this._engines;
    51. },
    52.  
    53. /* Function: startup
    54. Methode publique appelee apres l'instanciation du widget et la creation de tous
    55. ses noeuds DOM dans document.body */
    56. startup: function(){
    57. console.log("exemple2.widget.Search::startup");
    58. this.inherited("startup",arguments);
    59.  
    60. this.searchField.value=(this.text==null||this.text=="")?
    61. this._nls.locale.text:this.text;
    62.  
    63. var menu = new dijit.Menu();
    64.  
    65. dojo.forEach(this._engines, function(engine){
    66.  
    67. var menuItem = new dijit.MenuItem({
    68. label: engine,
    69. onClick: dojo.hitch(this, function(param) {
    70. this._dropdown.attr("label",param);
    71. this._dropdown.attr("engine",param);
    72. },engine)
    73. });
    74.  
    75. menu.addChild(menuItem);
    76.  
    77. },this);
    78.  
    79. this._dropdown = new dijit.form.DropDownButton({
    80. label: this._engines[0],
    81. engine: this._engines[0],
    82. dropDown: menu
    83. }, dojo.byId(this.id+"Selector"));
    84.  
    85. this._dropdown.startup();
    86.  
    87. },
    88.  
    89. /* Function: _onKeyPress
    90. Methode privee executee lors de la saisie d'un caractere dans le champs de recherche */
    91. _onKeyPress: function(/*Object*/evt) {
    92. console.log("exemple2.widget.Search::_onKeyPress");
    93. if(evt.keyCode == dojo.keys.ENTER){
    94. this._search();
    95. dojo.stopEvent(evt);
    96. return;
    97. }
    98. },
    99.  
    100. /* Function: _clear
    101. Methode privee permettant d'effacer le texte du champs de saisie */
    102. _clear: function() {
    103. console.log("exemple2.widget.Search::_clear");
    104. if(this.searchField.value==this._nls.locale.text||this.searchField.value==this.text) {
    105. this.searchField.value="";
    106. }
    107. },
    108.  
    109. /* Function: _search
    110. Methode privee executant la recherche */
    111. _search: function() {
    112. console.log("exemple2.widget.Search::_search");
    113.  
    114. if(  this.searchField.value!=this._nls.locale.text &&
    115. this.searchField.value!=this.text &&
    116. this.searchField.value != "") {
    117.  
    118. var url = "";
    119. var fieldValue = this.searchField.value;
    120. var engines = this._nls.ressources.engines;
    121.  
    122. switch(this._dropdown.attr('engine')){
    123. case this._engines[0]:
    124. url = engines.google;
    125. break;
    126. case this._engines[1]:
    127. url = engines.yahoo;
    128. break;
    129. case this._engines[2]:
    130. url = engines.wikipedia;
    131. break;
    132. }
    133.  
    134. dojo.byId("viewer").src=url+escape(fieldValue);
    135.  
    136. }
    137. else {
    138.  
    139. var dialogbox = dijit.byId("dialogbox");
    140.  
    141. var content = this._nls.ressources.popup;
    142. dialogbox.attr("title",this._nls.locale.popup.title);
    143. dialogbox.attr("content",dojo.string.substitute(content,{
    144. message:this._nls.locale.popup.message,
    145. btnLabel:this._nls.locale.popup.btnLabel
    146. }));
    147.  
    148. dialogbox.show();
    149. }
    150. }
    1. });

    searchWidget.html

    1. <script type="text/javascript">// <![CDATA[
    2.  
    3.  
    4.       dojo.require("dojo.i18n");
    5.       dojo.require("dijit.Dialog");
    6.  
    7. 	  dojo.require("exemple2.widget.Search"); 
    8.  
    9.       dojo.addOnLoad(init);
    10.  
    11.       function init(){ 
    12.  
    13.         var _search = new exemple2.widget.Search({
    14. 		  id:"search",
    15.           text:"saisir votre texte ici..."
    16.         }, dojo.byId("search"));
    17.  
    18.         _search.startup();
    19.  
    20.         var dialog = new dijit.Dialog({
    21.           title: "title" 
    22. 		}, dojo.byId("dialogbox"));
    23.  
    24.         dialog.startup();
    25.  
    26.       }
    27.  
    28.  
    29. // ]]></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

 

  1. <div class="viewer">class="iframe"<br />           src="${_nls.ressources.defaultPage}"<br />           dojoAttachPoint="viewer"<br />           scrolling="yes"<br />           frameborder="no"><br /></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

  1. },
  2. "viewerWidget" : {
  3. "defaultPage": "static/empty.html"
  4. }

Définition du style du widget ‘Viewer’

viewer.css

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

Modification de la page statique

empty.html

  1.  
  2.  
  3.  
  4.  
  5. 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

  1. /**********************************************/
  2. /*                                            */
  3. /* Widget : Viewer                            */
  4. /* Author : Berthenet Cyril                   */
  5. /*                                            */
  6. /**********************************************/
  1. dojo.provide("exemple2.widget.Viewer");
  2.  
  3. dojo.require("dijit._Templated");
  4. dojo.require("dijit._Widget");
  5.  
  6. dojo.requireLocalization("exemple2", "Ressources");
  7.  
  8. /* Class: Search */
  9. dojo.declare("exemple2.widget.Viewer", [dijit._Widget,dijit._Templated], {
  10.  
  11. /* Object: _nls
  12. stockage du wording et des ressources du widget */
  13. _nls:{ressources:null},
  14.  
  15. /* String: templatePath
  16. chemin d'acces au template du widget */
  17. templatePath: dojo.moduleUrl("exemple2.widget", "template/Viewer.html"),
  18.  
  19. /* Function: constructor
  20. Constructeur */
  21. constructor: function(){
  22. console.log("exemple2.widget.Viewer::constructor");
  23. this._nls.ressources=
  24. dojo.i18n.getLocalization("exemple2","Ressources").viewerWidget;
  25. },
  26.  
  27. /* Function: destroy
  28. Destructeur */
  29. destroy: function(){
  30. console.log("exemple2.widget.Search::destroy");
  31. delete this._nls;
  32. },
  33.  
  34. /* Function: setContent
  35. Modification du contenu du viewer */
  36. setContent: function(/*String*/url) {
  37. console.log("exemple2.widget.Viewer::setContent");
  38. this.viewer.src=url;
  39. },
  40.  
  41. /* Function: reset
  42. Remise a zero du contenu du viewer */
  43. reset: function() {
  44. console.log("exemple2.widget.Viewer::setContent");
  45. this.setContent(this._nls.ressources.defaultPage);
  46. }
  1. });

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

  1.  
  1. <script type="text/javascript">// <![CDATA[
  2.  
  3.  
  4.       var djConfig = {
  5.         parseOnLoad: false,
  6.         isDebug: true
  7.       }; 
  8.  
  9.  
  10. // ]]></script>
  11.  
  12. <script src="../dojo/dojo.js" type="text/javascript"></script>
  13.  
  14. <script type="text/javascript">// <![CDATA[
  15.  
  16.  
  17.       dojo.require("dojo.i18n");
  18.  
  19.       dojo.require("exemple2.widget.Viewer"); 
  20.  
  21.       dojo.addOnLoad(init);
  22.  
  23.       function init(){
  24.  
  25.          var _viewer = new exemple2.widget.Viewer({
  26.           id:"viewer"
  27.         }, dojo.byId("viewer"));
  28.  
  29.         _viewer.setContent("http://www.google.fr");        
  30.  
  31.       }
  32.  
  33.  
  34. // ]]></script>
  1.  

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

  1. /**********************************************/
  2. /*                                            */
  3. /* Widget : Mon application                   */
  4. /* Author : Berthenet Cyril                   */
  5. /*                                            */
  6. /**********************************************/
  1. dojo.provide("exemple2.widget.MonAppli");
  2.  
  3. dojo.require("dijit._Templated");
  4. dojo.require("dijit._Widget");
  5.  
  6. dojo.require("dijit.layout.ContentPane");
  7. dojo.require("dijit.layout.BorderContainer");
  8. dojo.require("dijit.Dialog");
  9.  
  10. dojo.require("exemple2.widget.Search");
  11. dojo.require("exemple2.widget.Viewer");
  12.  
  13. dojo.requireLocalization("exemple2", "Ressources");
  14.  
  15. /* Class: Search */
  16. dojo.declare("exemple2.widget.MonAppli", [dijit._Widget,dijit._Templated], {
  17.  
  18. /* Boolean: widgetsInTemplate
  19. affichage de widgets dans un template (false par defaut) */
  20. widgetsInTemplate: true,
  21.  
  22. /* String: templatePath
  23. chemin d'acces au template du widget */
  24. templatePath: dojo.moduleUrl("exemple2.widget", "template/MonAppli.html"),
  25.  
  26. /* Function: constructor
  27. Constructeur */
  28. constructor: function(){
  29. console.log("exemple2.widget.MonAppli::constructor");
  30. }
  1. });

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

 

  1. <div>
  2. <div>
  3.  
  4. &nbsp;
  5.  
  6. </div>
  7. <div>
  8.  
  9. &nbsp;
  10.  
  11. </div>
  12. </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

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

par :

Search.js

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

Viewer.js

  1. /* Array: topics */
  2. _topics:null,
  1. /* Function: constructor
  2. Constructeur */
  3. constructor: function(){
  4. console.log("exemple2.widget.Viewer::constructor");
  5. this._nls.ressources=dojo.i18n.getLocalization("exemple2","Ressources")
  6. .viewerWidget;
  7. this._topics=[];
  8. },
  9.  
  10. /*Function: destroy
  11. Destructeur */
  12. destroy: function(){
  13. console.log("exemple2.widget.Search::destroy");
  14. delete this._nls;
  15. delete this._topics;
  16. },
  1.  /* Function: postCreate
  2. Methode appelee apres la creation du widget */
  3. postCreate: function() {
  4. this._topics[0]=dojo.subscribe("displayResult", this, "setContent");
  5. },

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

  1. .search {
  2. height:30px;
  3. }
  4. .search .btn {
  5. background: url(../images/loupe.png) no-repeat;
  6. width:20px;
  7. height:19px;
  8. border-left:0px;
  9. cursor:pointer;
  10. }
  11. .search input{
  12. height:21px;
  13. font:13px verdana, sans-serif;
  14. }

monappli.css

  1. .floatLeft {
  2. float:left;
  3. }
  4. .greyBorder {
  5. border:1px solid #B0B0B0;
  6. }
  1. /****************************************/
  2. /*    Surcharge theme nihilo de Dojo       */
  3. /****************************************/
  1. .nihilo .dijitDropDownButton .dijitReset {
  2. height:16px;
  3. }
  4. .nihilo .dijitDropDownButton {
  5. float: left;
  6. margin:0 !important;
  7. }
  8. .nihilo .dijitDropDownButton span {
  9. font:10px verdana, sans-serif;
  10. }
  11. .nihilo .dijitButtonNode {
  12. width:80px;
  13. border:1px solid #B0B0B0 !important;
  14. border-right:0px !important;
  15. }

Test 

monApplication.html

  1.  
  1.  <!--       @import "../dijit/themes/dijit.css";       @import "../dijit/themes/nihilo/nihilo.css";      --><script type="text/javascript">// <![CDATA[
  2.  
  3.  
  4.       var djConfig = {
  5.         parseOnLoad: false,        
  6. 		isDebug: true
  7.       };
  8.  
  9.  
  10. // ]]></script>
  11.  
  12. <script src="../dojo/dojo.js" type="text/javascript"></script>
  13.  
  14. <script type="text/javascript">// <![CDATA[
  15.  
  16.  
  17.       dojo.require("dojo.i18n");      
  18.  
  19.       dojo.require("exemple2.widget.MonAppli");
  20.  
  21.       dojo.addOnLoad(init);
  22.  
  23. 	  function init(){
  24.  
  25.         var _appli = new exemple2.widget.MonAppli({}, dojo.byId("appli"));
  26.  
  27.         var dialog = new dijit.Dialog({}, dojo.byId("dialogbox")); 
  28.  
  29.         dialog.startup();
  30.  
  31.       }
  32.  
  33.  
  34. // ]]></script>
  1.  

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

 

Laisser un commentaire

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 :

  1. //charge le code de création de la toc
  2. dojo.require("dojox.toc");
  3.  
  4. dojo.addOnLoad(function() {
  5.     //creation de la toc
  6.     dojox.toc.create();
  7. }

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 :

  1. 	{
  2. 		rootNode : dojo.body() /*Racine a parcourir. La recherche se fait à l'intérieur de cette balise*/,
  3. 		classToIgnore : [] /*Tableau listant les classes à ignorer. Un élément qui comporte l'une de ces classes sera ignoré.*/,
  4. 		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*/,
  5. 		position : "before" /*Position à laquelle le noeud de la TOC sera ajouté autour du noeud défini par appendNode*/,
  6. 		"class" : "toc" /*Classe ajoutée au UL de la TOC*/,
  7. 		query : "h1,h2" /*Noeuds qui seront recherché pour générer la TOC*/,
  8. 		stripHtml : true /*Supprime l'HTML trouvé dans les noeuds utilisés pour la TOC*/,
  9. 		rootAnchor : "dojox.toc." /*Texte ajouté dans les ancres (avant la position numérique de l'ancre)*/
  10. 	}

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

Laisser un commentaire

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 :

  1. <div>
  2.   <input type="text" 
  3.          name="Field" 
  4.          value="saisir le texte ici..." 
  5.   />    <div id="Button" 
  6.        label="lancer la recherche" 
  7.        title="lancer la recherche">
  8.   </div>
  9. </div>

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.

  1. 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 :

  1. /**********************************************/
  2. /*                                            */
  3. /* Widget : Search                            */
  4. /* Author : Berthenet Cyril                   */
  5. /*                                            *
  6. //**********************************************/
  7.  
  8. dojo.provide("exemple1.widget.Search");
  9.  
  10. dojo.require("dijit._Templated");dojo.require("dijit._Widget");
  11.  
  12. /* Class: Search */
  13. dojo.declare("exemple1.widget.Search", [dijit._Widget,dijit._Templated], {
  14.    /* String: templatePath
  15.      chemin d'acces vers le template du widget */
  16.   templatePath: dojo.moduleUrl("exemple1.widget", "template/Search.html"),
  17.  
  18.   /* Function: constructor     Constructeur */
  19.   constructor: function(){
  20.     console.log("exemple1.widget.Search::constructor");
  21.   }
  22.  });

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 :

  1. .floatLeft {
  2.   float:left;
  3. }
  4. .greyBorder {
  5.   border:1px solid #B0B0B0;}
  6. .search .btn {
  7.   background: url(../images/loupe.png) no-repeat;
  8.   width:20px;
  9.   height:19px;  border-left:0px;
  10.   cursor:pointer;
  11. }
  12. .search input{  
  13.   height:21px;  font:13px verdana, sans-serif;
  14. }

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 :

  1. <div class="search">
  2.   <input type="text" 
  3.          class="floatLeft greyBorder"
  4.          name="Field" 
  5.          value="saisir le texte ici..." 
  6.   />  
  7.   <div id="Button" 
  8.        class="btn greyBorder floatLeft"
  9.        label="lancer la recherche" 
  10.        title="lancer la recherche">  </div>
  11. </div>

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

Création d’un sample de test

searchWidget.html :

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3.   <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset="utf-8" />
  5.             <title>Search</title>
  6.  
  7.     <link rel="stylesheet" type="text/css" href="./css/search.css" />
  8.  
  9.     <script>        
  10.       var djConfig = {
  11.         parseOnLoad: false,
  12.         isDebug: true
  13.       };        
  14.     </script>
  15.  
  16.     <script type="text/javascript" src="../dojo/dojo.js" charset="utf-8"></script>
  17.                     <script type="text/javascript" language="javascript">
  18.  
  19.       dojo.require("exemple1.widget.Search");
  20.  
  21.       dojo.addOnLoad(init);        
  22.       function init(){
  23.  
  24.         var _search = new exemple1.widget.Search({
  25.           id:"search"        }, dojo.byId("search"));
  26.  
  27.         _search.startup();
  28.  
  29.       }    
  30.     </script>
  31.   </head>
  32.   <body>
  33.     <div id="search"></div>  </body>
  34. </html>

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

  1. 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

  1. <div class="search">
  2.   <input type="text" 
  3.          class="floatLeft greyBorder" 
  4.          name="${id}Field"
  5.          value=""
  6.          dojoAttachPoint="searchField"
  7.   />  
  8.   <div id="${id}Button"
  9.        class="btn greyBorder floatLeft" 
  10.        label="${_nls.locale.send}"
  11.         title="${_nls.locale.send}">
  12.   </div>
  13. </div>

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

  1. /**********************************************/
  2. /*                                            */
  3. /* Widget : Search                            */
  4. /* Author : Berthenet Cyril                   */
  5. /*                                            */
  6. /**********************************************/
  7.  
  8. dojo.provide("exemple1.widget.Search");
  9.  
  10. dojo.require("dijit._Templated");
  11. dojo.require("dijit._Widget");
  12.  
  13. dojo.requireLocalization("exemple1", "Locale"); 
  14.  
  15. /* Class: Search */
  16. dojo.declare("exemple1.widget.Search", [dijit._Widget, dijit._Templated], {
  17.  
  18.   /* Object : _nls
  19.   stockage du wording */  
  20.   _nls:{locale:null},  
  21.  
  22.   /* String: templatePath
  23.      chemin d'acces au template du widget */
  24.   templatePath: dojo.moduleUrl("exemple1.widget", "template/Search.html"),
  25.  
  26.    /* Function: constructor
  27.      Constructeur */
  28.   constructor: function(){
  29.     console.log("exemple1.widget.Search::constructor");
  30.     this._nls.locale=dojo.i18n.getLocalization("exemple1","Locale").searchWidget;  
  31.   },
  32.  
  33.   /* Function: destroy     
  34.   Destructeur */  
  35.   destroy: function(){
  36. 	console.log("exemple1.widget.Search::destroy");
  37.     this.inherited("destroy",arguments);
  38. 	delete this._nls;
  39.   },
  40.  
  41. 	/* Function: startup
  42. 	Methode publique appelee apres l'instanciation du widget et
  43. 	la creation de tous ses noeuds DOM dans document.body */  
  44.   startup: function(){
  45. 	console.log("exemple1.widget.Search::startup");    
  46. 	this.inherited("startup",arguments);    
  47. 	this.searchField.value = this._nls.locale.text;  
  48.   } 
  49.  
  50. });

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 :

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "search": "rechercher",
  5.     "send": "lancer la recherche",
  6.     "text": "saisir le texte ici..."
  7.   }
  8.  
  9. })

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) :

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "search": "search",
  5.     "send": "go",
  6.     "text": "enter your keywords here..."
  7.   }
  8.  
  9. })

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

Modification du sample

searchWidget.html :

  1. <script type="text/javascript" language="javascript">
  2.  
  3.   dojo.require("dojo.i18n");
  4.  
  5.   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 :

  1. <div id="${id}Button" 
  2.      class="btn greyBorder floatLeft" 
  3.      label="${_nls.locale.send}" 
  4.      title="${_nls.locale.send}" 
  5.      dojoAttachEvent="onclick:_search">
  6. </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 :

  1. },
  2.  
  3.   /* Function: _search
  4.      Methode privee executant la recherche */
  5.   _search: function() {
  6.     console.log("exemple1.widget.Search::_search");
  7.  
  8.      if( this.searchField.value!=this._nls.locale.text &&
  9.          this.searchField.value != "") {
  10.         console.info("lancer la recherche sur : ", this.searchField.value);
  11.     }
  12.     else {
  13.       console.info("vous devez saisir une chaine de caracteres...");
  14.     }
  15.   }

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 :

  1. <input type="text" 
  2.          class="floatLeft greyBorder" 
  3.          name="${id}Field" 
  4.          value="" 
  5.          dojoAttachPoint="searchField"
  6.          dojoAttachEvent="onkeypress:_onKeyPress"
  7.  />

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

Search.js :

  1. },
  2.  
  3.   /* Function: _onKeyPress
  4.      Methode privee executee lors de la saisie d'un caractere dans le champ
  5.       de recherche */
  6.   _onKeyPress: function(/*Object*/evt) {
  7.     console.log("exemple1.widget.Search::_onKeyPress");
  8.     if(evt.keyCode == dojo.keys.ENTER){
  9.       console.info("vous avez appuye sur la touche ENTREE");
  10.       this._search();
  11.       dojo.stopEvent(evt);
  12.       return;
  13.     }
  14.   }

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 :

  1. <input type="text" 
  2.          class="floatLeft greyBorder" 
  3.          name="${id}Field" 
  4.          value="" 
  5.          dojoAttachPoint="searchField"
  6.          dojoAttachEvent="onkeypress:_onKeyPress,onclick:_clear"
  7.   />

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

Search.js :

  1. },
  2.  
  3.   /* Function: _clear
  4.      Methode privee permettant d'effacer le texte du champ de saisie */
  5.   _clear: function() {
  6.     console.log("exemple1.widget.Search::_clear");
  7.     if(this.searchField.value==this._nls.locale.text) {
  8.        this.searchField.value="";
  9.     }
  10.   },

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 :

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

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

Search.js :

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

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

  1. /* Function: _clear
  2.     Methode privee permettant d'effacer le texte du champ de saisie */
  3.   _clear: function() {
  4.     console.log("exemple1.widget.Search::_clear");
  5.     if( this.searchField.value==this._nls.locale.text ||
  6. 	this.searchField.value==this.text ) {
  7. 	this.searchField.value="";
  8.     }
  9.   },
  10.  
  11. /* Function: _search
  12.     Methode privee executant la recherche */
  13.   _search: function() {
  14.     console.log("exemple1.widget.Search::_search");
  15.  
  16. 	if(  this.searchField.value!=this._nls.locale.text &&
  17.          this.searchField.value!=this.text &&
  18. 		 this.searchField.value != "") {
  19.          console.info("lancer la recherche sur : ", this.searchField.value);
  20.     }
  21.     else {
  22.       console.info("vous devez saisir une chaine de caracteres..."); 
  23.     }
  24.   }

Sélection du moteur de recherche

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

Modification du template

Search.html :

  1. <div class="search">
  2.   <div id="${id}Selector"></div>
  3.   <input type="text" 
  4.          class="floatLeft greyBorder" 
  5.          name="${id}Field"
  6. 		 value="" 
  7.          dojoAttachPoint="searchField" 
  8.          dojoAttachEvent="onkeypress:_onKeyPress,onclick:_clear" 
  9.   />  
  10.   <div id="${id}Button"
  11.   class="btn greyBorder floatLeft" 
  12.        label="${_nls.locale.send}" 
  13.        title="${_nls.locale.send}" 
  14.        dojoAttachEvent="onclick:_search">
  15.   </div>
  16. </div>

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

Modification du widget

Search.js :

  1. /**********************************************/
  2. /*                                            */
  3. /* Widget : Search                            */
  4. /* Author : Berthenet Cyril                   */
  5. /*                                            */
  6. /**********************************************/
  7.  
  8. dojo.provide("exemple1.widget.Search");
  9.  
  10. dojo.require("dijit._Templated");
  11. dojo.require("dijit._Widget");
  12.  
  13. dojo.require("dijit.form.Button");
  14. dojo.require("dijit.Menu"); 
  15.  
  16. dojo.requireLocalization("exemple1", "Locale");
  17. dojo.requireLocalization("exemple1", "Ressources"); 
  18.  
  19. /* Class: Search */
  20. dojo.declare("exemple1.widget.Search", [dijit._Widget,dijit._Templated], { 
  21.  
  22.   /* Object: _nls
  23.      stockage du wording et des ressources du widget */
  24.   _nls:{locale:null,ressources:null},
  25.  
  26.   /* String: templatePath
  27.      chemin d'acces vers le template du widget */
  28.   templatePath: dojo.moduleUrl("exemple1.widget", "template/Search.html"),
  29.  
  30.   /* Object: _dropdown
  31.   bouton de selection du moteur de recherche */
  32.   _dropdown:null,
  33.  
  34.   /* Array: _engines
  35.   liste des moteurs de recherche */
  36.   _engines:null, 
  37.  
  38.   /* Function: constructor
  39.      Constructeur */
  40.   constructor: function(){
  41.     console.log("exemple1.widget.Search::constructor");
  42.     this._nls.locale=dojo.i18n.getLocalization("exemple1","Locale").searchWidget;
  43.     this._nls.ressources=
  44.      	dojo.i18n.getLocalization("exemple1","Ressources").searchWidget;
  45. 	this._engines=this._nls.locale.engines;
  46.     this._dropdown={};
  47.   },
  48.  
  49.   /* Function: destroy
  50.      Destructeur */  
  51.   destroy: function(){
  52.     console.log("exemple1.widget.Search::destroy");
  53.     this.inherited("destroy",arguments);
  54.     if(this._dropdown){this._dropdown.destroy();}
  55.     delete this._nls;
  56.     delete this._engines;
  57.   },
  58.  
  59.   /* Function: startup
  60.      Methode publique appelee apres l'instanciation du widget et
  61. 	 la creation de tous ses noeuds DOM dans document.body */
  62.   startup: function(){
  63.     console.log("exemple1.widget.Search::startup");
  64.     this.inherited("startup",arguments);
  65.  
  66.     this.searchField.value=(this.text==null||this.text=="")?
  67.                            this._nls.locale.text:this.text;
  68.  
  69.     var menu = new dijit.Menu();
  70.  
  71. 	dojo.forEach(this._engines, function(engine){
  72.  
  73.     	var menuItem = new dijit.MenuItem({
  74. 		label: engine,
  75. 		onClick: dojo.hitch(this, function(param) {
  76. 			this._dropdown.attr("label",param);
  77. 			this._dropdown.attr("engine",param);
  78. 		},engine)
  79. 	});
  80.  
  81. 	menu.addChild(menuItem);
  82.  
  83.   },this);
  84.  
  85.   this._dropdown = new dijit.form.DropDownButton({
  86.      label: this._engines[0],
  87. 	 engine: this._engines[0],
  88. 	 dropDown: menu
  89.    }, dojo.byId(this.id+"Selector"));
  90.  
  91.    this._dropdown.startup(); 
  92.  
  93.   },

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 :

  1. /* Function: _search
  2.     Methode privee executant la recherche */
  3.   _search: function() {
  4.     console.log("exemple1.widget.Search::_search");
  5.  
  6.      if(  this.searchField.value!=this._nls.locale.text &&
  7.          this.searchField.value!=this.text && 
  8.          this.searchField.value != "") {
  9.  
  10.       var url = "";
  11.       var fieldValue = this.searchField.value;
  12.       var engines = this._nls.ressources.engines;
  13.  
  14. 	  switch(this._dropdown.attr('engine')){
  15. 	  case this._engines[0]:
  16. 		url = engines.google;
  17. 		break;
  18.       case this._engines[1]:
  19. 		url = engines.yahoo;
  20. 		break;
  21.       case this._engines[2]:
  22. 		url = engines.wikipedia;
  23. 		break;
  24. 	  }
  25.  
  26. 	  console.log("url pour la recherche : ", url+escape(fieldValue));                        
  27.  
  28.     }
  29.     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 :

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "engines" : [
  5.         "Google",
  6.         "Yahoo",
  7.         "Wikipedia"
  8.     ],
  9.     "search": "search",
  10.     "send": "go",
  11.     "text": "enter your keywords here..."
  12.   }
  13.  
  14. })

nls/fr/Locale.js :

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "engines" : [
  5.         "Google",
  6.         "Yahoo",
  7.         "Wikipedia"
  8.     ],
  9.     "search": "rechercher",
  10.     "send": "lancer la recherche",
  11.     "text": "saisir le texte ici..."
  12.   }
  13.  
  14. })

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

Ajout des url de recherche dans les ressources

nls/Ressources.js :

:

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "engines" : {
  5.         "google": "http://www.google.com/search?q=",
  6.         "yahoo": "http://uk.search.yahoo.com/search?p=",
  7.         "wikipedia": "http://en.wikipedia.org/wiki/Special:Recherche?search="
  8.     }
  9.   }
  10.  })

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

nls/fr/Ressources.js :

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "engines" : {
  5.         "google": "http://www.google.fr/search?q=",
  6.         "yahoo": "http://fr.search.yahoo.com/search?p=",
  7.         "wikipedia": "http://fr.wikipedia.org/wiki/Special:Recherche?search="
  8.     }
  9.   }
  10.  })

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 :

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

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

  1. <body class="nihilo">
  2.   <div id="search"></div>
  3. </body>

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

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

search.css :

  1. .floatLeft {
  2.   float:left;
  3. }
  4. .greyBorder {
  5.   border:1px solid #B0B0B0;
  6. }
  7. .search {  
  8.   height:30px;
  9. }
  10. .search .btn {
  11.   background: url(../images/loupe.png) no-repeat;
  12.   width:20px;
  13.   height:19px;
  14.   border-left:0px;
  15.   cursor:pointer;
  16. }
  17. .search input{  
  18.   height:21px;
  19.   font:13px verdana, sans-serif;
  20. }
  21. .nihilo .dijitDropDownButton .dijitReset {
  22.   height:16px;
  23. }
  24. .nihilo .dijitDropDownButton {
  25.   float: left;
  26.   margin:0 !important;
  27. }
  28. .nihilo .dijitDropDownButton span {
  29.   font:10px verdana, sans-serif;
  30. }
  31. .nihilo .dijitButtonNode {
  32.   width:80px;
  33.   border:1px solid #B0B0B0 !important;
  34.   border-right:0px !important;
  35. }

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 :

  1. <body class="nihilo">
  2.   <div id="search"></div>
  3.   <iframe id="viewer"
  4.     name="viewer"
  5.     src="./static/empty.html"
  6.     scrolling="yes"
  7.     height="400"
  8.     width="100%"
  9.     frameborder="yes">
  10.   </iframe>
  11. </body>

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

empty.html :

  1. <html>
  2.   <head>
  3.   </head>
  4.   <body>
  5.     Le r&eacute;sultat s'affichera dans cette iframe
  6.   </body>
  7. </html>

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

Search.js :

remplacer :

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

par :

  1. 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 :

  1. else {
  2.  
  3.     var dialogbox = dijit.byId("dialogbox");
  4.  
  5.     var content = this._nls.ressources.popup;
  6.     dialogbox.attr("title",this._nls.locale.popup.title);
  7.     dialogbox.attr("content",dojo.string.substitute(content,{
  8.         message:this._nls.locale.popup.message,
  9.         btnLabel:this._nls.locale.popup.btnLabel
  10.     }));                        
  11.     dialogbox.show();  
  12.   }

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 :

  1. {
  2.  
  3.   "searchWidget" : {
  4.     "engines" : [
  5.         "Google",
  6.         "Yahoo",
  7.         "Wikipedia"
  8.     ],
  9.     "popup": {
  10.         "btnLabel":"OK",
  11.         "message": "you must write more than one character",
  12.         "title": "Error"
  13.     },
  14.     "search": "search",
  15.     "send": "go",
  16.     "text": "enter your keywords here..."
  17.   }
  18.  
  19. })

nls/fr/Locale.js :

  1. {
  2.  
  3.   "searchWidget" : {
  4.     "engines" : [
  5.         "Google",
  6.         "Yahoo",
  7.         "Wikipedia"
  8.     ],
  9.     "popup": {
  10.         "btnLabel":"OK",
  11.         "message": "Veuillez saisir au moins un caract\u00e8re",
  12.         "title": "Erreur"
  13.     },
  14.     "search": "rechercher",
  15.     "send": "lancer la recherche",
  16.     "text": "saisir le texte ici..."
  17.   }
  18.  
  19. })

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 :

:

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "engines" : {
  5.         "google": "http://www.google.com/search?q=",
  6.         "yahoo": "http://uk.search.yahoo.com/search?p=",
  7.         "wikipedia": "http://en.wikipedia.org/wiki/Special:Recherche?search="
  8.     },
  9.     "popup" : "<table> \
  10. 		<tr> \
  11. 			<td>${message}</td> \
  12. 		</tr> \
  13. 		<tr> \
  14. 			<td align=\"center\"> \
  15. 				<button dojoType=\"dijit.form.Button\" type=\"submit\"> \
  16. 					${btnLabel}\
  17. 				</button></td> \
  18. 		</tr> \
  19. 	</table>"
  20.     } 
  21.  
  22.  })

nls/fr/Ressources.js :

  1. ({
  2.  
  3.   "searchWidget" : {
  4.     "engines" : {
  5.         "google": "http://www.google.fr/search?q=",
  6.         "yahoo": "http://fr.search.yahoo.com/search?p=",
  7.         "wikipedia": "http://fr.wikipedia.org/wiki/Special:Recherche?search="
  8.     },
  9.     "popup" : "<table> \
  10. 		<tr> \
  11. 			<td>${message}</td> \
  12. 		</tr> \
  13. 		<tr> \
  14. 			<td align=\"center\"> \
  15. 				<button dojoType=\"dijit.form.Button\" type=\"submit\"> \
  16. 					${btnLabel}\
  17. 				</button></td> \
  18. 		</tr> \
  19. 	</table>"
  20.     } 
  21.  
  22. })

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 :

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3.   <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset="utf-8" />
  5.  
  6. 	<title>Search</title>
  7.  
  8.     <link rel="stylesheet" type="text/css" href="./css/search.css" />
  9.  
  10.     <style type="text/css" title="text/css">
  11.       @import "../dijit/themes/dijit.css";
  12.       @import "../dijit/themes/nihilo/nihilo.css";
  13.     </style>
  14.  
  15.     <script> 
  16.  
  17. 	  var djConfig = {
  18.         parseOnLoad: false,
  19.         isDebug: true
  20.       }; 
  21.  
  22.     </script>
  23.  
  24.     <script type="text/javascript" src="../dojo/dojo.js" charset="utf-8"></script>
  25.  
  26. 	<script type="text/javascript" language="javascript">
  27.  
  28.       dojo.require("dojo.i18n");
  29.       dojo.require("dijit.Dialog");
  30.  
  31. 	  dojo.require("exemple1.widget.Search");
  32.  
  33.       dojo.addOnLoad(init);
  34.  
  35.       function init(){ 
  36.  
  37.         var _search = new exemple1.widget.Search({
  38.           id:"search",
  39.           text:"toto"
  40.         }, dojo.byId("search"));                                
  41.  
  42.         _search.startup();
  43.  
  44.         var dialog = new dijit.Dialog({
  45. 			title: "title"
  46. 		}, dojo.byId("dialogbox"));
  47.  
  48. 		dialog.startup();                                        
  49.  
  50.       } 
  51.  
  52.     </script>
  53.   </head>
  54.   <body class="nihilo">
  55.     <div id="search"></div>    
  56. 	<iframe id="viewer" 
  57.             name="viewer" 
  58.             src="./static/empty.html"
  59.             scrolling="yes"
  60.             height="400"
  61.             width="100%"
  62.             frameborder="yes">
  63.     </iframe>
  64.     <div id="dialogbox"></div>  
  65. </body>
  66. </html>

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

Laisser un commentaire

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 :
    1. javascript:(
    2. function(){
    3. /* code qui va activer les traces*/
    4. })();
  • 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 :

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

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

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

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 :

  1. javascript:(
  2. function(){
  3. 	dojo.connect(dojo,'publish',function() {
  4. 		console.warn('dojo.publish(', arguments,')');
  5. 	});
  6. })();

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

  1. javascript:(
  2. function(){
  3. 	if(typeof dojo=='undefined'){
  4. 		console.error('Dojo est ind\u00e9fini');
  5. 		return;
  6. 	}else{
  7. 		dojo.connect(dojo,'publish',function() {
  8. 			console.warn('dojo.publish(', arguments,')');
  9. 		});
  10. 		console.info('Trace de dojo.publish activ\u00e9e');
  11. 	};
  12. })();

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

Laisser un commentaire

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 :

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

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

  1. <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

Laisser un commentaire

Custom build, singleton et fichier de localisation


Pour le projet sur lequel je travaille, nous avons découpé notre application en widgets et en singleton.
La différence entre les deux est minime.
Alors qu’un fichier de widget se termine par « }); » (pour clôturer le dojo.declare), le singleton ajoute 2 lignes qui servent à le créer :

  1.  
  2. if(!ext.mySingleton)
  3. 	ext.mySingleton = new ext.MySingleton();

Cela ne pose aucun problème à la build… sauf si votre singleton à besoin d’accéder aux localisations.
Au chargement de votre page, vous obtenez à peu près l’erreur suivante :

  1.  
  2.  	Error: Bundle not found: loading in dijit , locale=

Il faut savoir que lors de la build, tous vos widgets sont packagé en un seul fichier et à la fin de se fichier est ajouté une ligne pour charger les localisations.
Et tous le problème est la…
Comme votre singleton se crée (et donc demande à dojo les localisations) AVANT que celles-ci ne soient effectivement disponible (puisque chargées en fin de fichier) tout se met à planter.
Pour éviter ce problème, voici la la seule solution que j’ai trouvé :

  • Utiliser les même localisations dans les widgets et dans les singletons
    1. dojo.i18n.getLocalization("ext.myWidgets.lang","locale"); //pour les widgets et les singletons
  • Créer, lors de la build, 2 fichiers JS : un qui inclus les widgets, le second les singletons.
  • Charger (via une balise script normale) le fichier des widgets puis celui des singletons

Avec ça tout devrait bien se passer. Le chargement du fichier des widgets appelle le fichier de localisation qui sera réutilisé indirectement par le fichier des singletons.

Évidement il doit exister mieux. Donc si quelqu’un connais une meilleur façon de faire, je suis preneur :)

Laisser un commentaire