Si vous souhaitez participer à la vie de dojotookit-fr, nous recherchons : des traducteurs, des personnes pour animer le blog ou écrire des articles, etc...
Prévenez nous par mail (ben_AT_dojotoolkit-fr_DOT_org) ou par chat (#dojo-fr sur irc.freenode.net)

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
2
3
4
5
6
7
8
9
<div>
  <input type="text" 
         name="Field" 
         value="saisir le texte ici..." 
  />    <div id="Button" 
       label="lancer la recherche" 
       title="lancer la recherche">
  </div>
</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
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**********************************************/
/*                                            */
/* 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 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.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 :

1
2
34
5
6
7
89
10
11
<div class="search">
  <input type="text" 
         class="floatLeft greyBorder"         name="Field" 
         value="saisir le texte ici..." 
  />  
  <div id="Button" 
       class="btn greyBorder floatLeft"       label="lancer la recherche" 
       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 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset="utf-8" />
            <title>Search</title>
        
    <link rel="stylesheet" type="text/css" href="./css/search.css" />
        
    <script>        
      var djConfig = {
        parseOnLoad: false,
        isDebug: true
      };        
    </script>
 
    <script type="text/javascript" src="../dojo/dojo.js" charset="utf-8"></script>
                    <script type="text/javascript" language="javascript">
          
      dojo.require("exemple1.widget.Search");
    
      dojo.addOnLoad(init);        
      function init(){
 
        var _search = new exemple1.widget.Search({
          id:"search"        }, dojo.byId("search"));
                                        
        _search.startup();
                        
      }    
    </script>
  </head>
  <body>
    <div id="search"></div>  </body>
</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
2
3
45
67
89
101112
13
<div class="search">
  <input type="text" 
         class="floatLeft greyBorder" 
         name="${id}Field"         value=""
         dojoAttachPoint="searchField"  />  
  <div id="${id}Button"       class="btn greyBorder floatLeft" 
       label="${_nls.locale.send}"        title="${_nls.locale.send}">  </div>
</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
4
5
6
7
8
9
10
11
12
1314
15
16
17
18192021
22
23
24
25
26
27
28
29
3031
32
3334353637383940414243444546474849
50
/**********************************************/
/*                                            */
/* 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 :

1
2
3
4
5
6
7
8
9
({
 
  "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) :

1
2
3
4
5
6
7
8
9
({
 
  "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 :

22
23
24
25
26
<script type="text/javascript" language="javascript">
  
  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 :

8
9
10
11
1213
<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 :

48
49
50515253545556575859606162
},
          
  /* Function: _search     Methode privee executant la recherche */  _search: function() {    console.log("exemple1.widget.Search::_search");      if( this.searchField.value!=this._nls.locale.text &&         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 :

2
3
4
5
6
78
<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 :

48
49
505152535455565758596061
},
 
  /* 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 :

2
3
4
5
6
78
<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 :

59
60
6162636465666768
},
 
  /* 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 :

32
33
3435
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 :

40
41
42
43
44
45
464748
/* 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

63
64
65
66
67
6869
70
71
72
73
74
75
76
77
78
7980
81
82
83
84
85
86
/* 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 &&
         this.searchField.value!=this.text &&                 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 :

1
23
4
5
6
7
8
9
10
11
12
13
14
15
16
<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 :

1
2
3
4
5
6
7
8
9
10
11
12
131415
16
1718
19
20
21
22
23
2425
26
27
28
29
3031323334353637
38
39
40
41
42
4344454647
48
49
50
51
52
53
5455
5657
58
59
60
61
62
63
64
65
66
67
68
697071727374757677787980818283848586878889909192
93
/**********************************************/
/*                                            */
/* 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 :

114
115
116
117
118
119
120
121
122
123124125126127128129130131132133134135136137138139140
141
142
/* Function: _search
    Methode privee executant la recherche */
  _search: function() {
    console.log("exemple1.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;          }                    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 :

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

nls/fr/Locale.js :

1
2
3
456789
10
11
12
13
14
({
 
  "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 :

:

1
2
3
4
5
6
7
8
9
10
({
 
  "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 :

1
2
3
4
5
6
7
8
9
10
({
 
  "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 :

10
11
12
13
<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

5455
56
<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 :

1
2
3
4
5
6
78910
11
12
13
14
15
16
17
18
19
20
212223242526272829303132333435
.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 :

1
2
34567891011
<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 :

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

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

par :
139
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 :

142
143
144
145
146
147
148
149
150
151
152
153
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 :

1
2
3
4
5
6
7
8
91011121314
15
16
17
18
19
{
 
  "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 :

1
2
3
4
5
6
7
8
91011121314
15
16
17
18
19
{
 
  "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 :

:

1
2
3
4
5
6
7
8
9101112131415161718192021
22
({
 
  "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 :

1
2
3
4
5
6
7
8
9101112131415161718192021
22
({
 
  "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 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2930
31
32
33
34
35
36
37
38
39
40
41
42
43
444546474849
50
51
52
53
54
55
56
57
58
59
60
61
62
63
6465
66
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset="utf-8" />
    
        <title>Search</title>
                
    <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" src="../dojo/dojo.js" charset="utf-8"></script>
                    
        <script type="text/javascript" language="javascript">
 
      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>
  </head>
  <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>
    <div id="dialogbox"></div>  </body>
</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
Fichier attachéTaille
loupe.png1.02 Ko
code source complet6.69 Ko