Contribuez à la future faq Dojo
Salut à tous,
Je vous propose de recenser dans ce fil les sources, astuces et autres essais que vous avez découverts, essayés, voire créés et que vous jugez intéressant de partager. Dès que nous aurons atteint un nombre suffisant de contributions, nous pourrons certainement créer une FAQ Dojo.
Comment faire ?
Vous postez un message dans ce fil de discussion (une simple réponse) en inscrivant simplement votre code. Si ce code est décomposé en plusieurs fichiers, joignez un ZIP.
En aucune manière les codes postés ne doivent être commentés par les autres utilisateurs. Si quelqu'un souhaite faire une remarque, alors celle-ci a lieu dans le forum. En bref,
1 message du fil de la discussion = 1 exemple de code
Merci à tous !
Oui, je sais, c'est plus que du code :$
Je ne sais pas si ils sont encore tous les trois d'actualités ou bien si il y a des nouveautés mais j'ai utilisé ces trois choses-ci, donc j'en touche un mot. Mot qui devra être corrigé, j'en suis certain, ne serait-ce que pour une question de vocabulaire. Je me suis inspiré d'article sur le net.
Récupérer un noeud
Je vais parler de trois méthodes: dojo.byId(), dijit.byId et jsId.
En guise d'exemple, voici un ContentPane:
Code:
1 2 3 4 5 6
|
<div id="monIdDiv"
dojoType="dijit.layout.ContentPane"
jsId="monJSId">
Hello World!
</div> |
Il a un attribut HTML id (monIdDiv), ainsi qu'un attribut spécifique à Dojo jsId (monJSId).
dojo.byId
Là où nous avions document.getElementById(), nous avons dojo.byId() pour obtenir un noeud DOM selon son attribut id:
Code:
1 2 3
|
var monDiv = dojo.byId("monIdDiv");
monDiv.style.height = '100px'; |
dijit.byId
Dojo ajoute des attributs qui lui sont spécifiques. On parle ici d'un objet Dojo crée par le widget system lors de son initialisation en un dijit. Grâce à dijit.byId(), on peut accéder à ses attributs, ainsi qu'à ses méthodes. Ou bien accéder aux autres attributs comme précédemment. Cependant, selon l'héritage des classes Dojo, les dijit passe par la propriété domNode:
Code:
1 2 3 4
|
var monDiv = dijit.byId("monIdDiv");
monDiv.setContent("Bonjour à tous!");
monDiv.domNode.style.height = '100px'; |
Notez que cela permet de sauvegarder dans une variable locale le résultat du dijit.byId().
jsId
Lors du parsing Dojo, le jsId va être automatiquement lié à la création d'une variable Javascript globale ayant pour nom le jsId. Cette variable contient le même objet que celui retourné par dijit.byId(). Comprenez-donc la nécessité d'avoir des jsId uniques. Cependant, jsId n'est pas un attribut obligatoire.
Donc, étant donné que ma variable globale existe automatiquement, je n'ai plus besoin de passer par dijit.byId():
Code:
1 2 3
|
monJSId.setContent("Bonjour à tous!");
monJSId.domNode.style.height = '100px'; |
Modifier la valeur d'un attribut
Code:
1 2 3 4 5 6 7
|
//Modifier la valeur d'un attribut
var monObjet = dijit.byId("monObjet"); //Par exemple une TextBox avec un attribut value
var maValeur = "Bonjour!";
monObjet.attr("value", "Hello"); //En dur
monObjet.attr("value", maValeur); //Via une variable |
Ouvrir ou fermer un titlepane
Bonjour,
Utilisant les titlepane pour réaliser un menu, je me suis vite retrouvé confronté au fait que les titlepane restent ouverts. De ce fait, n'ayant pas envie de chercher une alternative sur le net, j'ai réalisé un petit script qui ferme tous les titlepane sauf celui sur lequel on clique.
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
function ouvferm(nom,id, nb){
var sub1 = dijit.byId(nom+id);
var ouvferm = sub1.attr('open');
for(i=1; i<=nb;i++){
if(i != id){
sub = dijit.byId(nom+i);
sub.attr('open', false);
}
}
} |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
<div id='menu1' class='menu' dojoType="dijit.TitlePane" title="Menu 1" open='true' onClick='ouvferm("menu","1","4");'>
menu 1
</div>
<div id='menu2' class='menu' dojoType="dijit.TitlePane" title="Menu 2" open='false' onClick='ouvferm("menu","2","4");'>
menu 2
</div>
<div id='menu3' class='menu' dojoType="dijit.TitlePane" title="Menu 3" open='false' onClick='ouvferm("menu","3","4");'>
menu 3
<div class='sousmenu' id='submenu1' dojoType="dijit.TitlePane" title="Sous menu 1" open='false' onClick='ouvferm("submenu","1","3");'>
Sous menu 1
</div>
<div class='sousmenu' id='submenu2' dojoType="dijit.TitlePane" title="Sous menu 2" open='false' onClick='ouvferm("submenu","2","3");'>
Sous menu 2
</div>
<div class='sousmenu' id='submenu3' dojoType="dijit.TitlePane" title="Sous menu 3" open='false' onClick='ouvferm("submenu","3","3");'>
sous menu 3
</div>
</div>
<div id='menu4' class='menu' dojoType="dijit.TitlePane" title="Menu 4" open='false' onClick='ouvferm("menu","4","4");'>
menu 4
</div> |
Initialiser de nombreux champs dans une page
Hello,
Lors de la fourniture des pages, normalement, c'est le serveur qui rempli les champs de la page en allant chercher les valeurs dans la base de données. Ceci étant effectué à l'aide de scripts php, ou de jsp+servlet.
Celà à pour inconvénient d'alourdir le code de la page html, surtout si comme moi, on a une vingtaine de champs à initialiser. De plus, quand les pages servent à la fois à la création/modification d'entités dans la base, il est préférable de fournir une page vierge; et pour la modification, le serveur génère un fichier "tmp/datas.json" qui est récupéré par la page lors de l'instanciation d'un Store.
Celà me donne une succession de couples {"identifiantvariable":"xxx","valeur":"yyy"} pour la structure du fichier datas.json :
Code:
1 2 3 4
| {"items":[{"valeur":"true","idvar":"chkboxnom"},{"valeur":"8","idvar":"xposnom"},
{"valeur":"10","idvar":"yposnom"},{"valeur":"Feb 1, 2010","idvar":"datcre"},
{"valeur":"Feb 1, 2010","idvar":"datmod"},{"valeur":"5-antique.jpg","idvar":"nomfichier"}],
"identifier":"idvar"} |
( idvar référencie presque toujours le nom donné à la variable lors de la création de l'objet Dojo ( TextBox, CheckBox, NumberSpinner, etc... )
Et pour l'initialisation des champs :
Code:
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 35 36 37 38 39 40
| // construction du store pour l'accès aux données
var jsonData = new dojo.data.ItemFileReadStore({url: 'tmp/datas.json'});
// fonction d'affectation des données
function initData(items, request){
var item;
for (i = 0; i < items.length; i++) {
item = items[i];
idvar = jsonData.getValue(item,"idvar");
switch(idvar){
case 'xposnom': xposnom.attr('value',jsonData.getValue(item,"valeur"));
break;
case 'yposnom': yposnom.attr('value',jsonData.getValue(item,"valeur"));
break;
case 'nomfichier': image.attr({content: '<img src="tmp/' + jsonData.getValue(item,"valeur") + '"/>'}); // ici image est un ContentPane
break;
case 'datcre': datcre.attr('value',jsonData.getValue(item,"valeur"));
break;
case 'datmod': datmod.attr('value',jsonData.getValue(item,"valeur"));
break;
case 'chkboxnom': if (jsonData.getValue(item,"valeur") == 'true'){
dijit.byId("caseNom").attr('value',true); // ici je ne suis pas parvenu à référencer la CheckBox directement.
}
break;
.........
}
}
// fonction de callback en cas d'erreur
function fetchError(error, request){
alert("Erreur sur la récupération des données : " + error);
}
// Initialisation des champs
jsonData.fetch(
{query: {idvar: '*'},
onComplete: initData,
onError: fetchError,
queryOptions: {deep: false}
}); |
Il y a peut-être moyen de faire plus dense, mais bon, ... je débute ;)
J'savais bien qu'il y avait possibilité de faire plus concis, comme la solution envoyée en MP par Daniel_Gibot, plus besoin de store et de fetch, et avec en prime un fichier JSON plus simple :
Code:
{"chkboxnom":"true","posnomx":"8","posnomy":"10","datcre":"Feb 1, 2010","datmod":"Feb 1, 2010","nomfichier":"5-antique.jpg"}
et pour initialiser les champs :
Code:
1 2 3 4 5 6 7 8 9 10
| var monForm = dojo.fromJson(data);
for(elem in monForm){
if(elem.substr(0,3 == 'chk']{ // cas particulier de la checkbox
dijit.byId(elem).attr('checked',monForm[elem]);
} else if ( .... ){ // autres cas particuliers
......
} else { // cas général
dijit.byId(elem).attr('value',monForm[elem]);
}
} |
Seul problème, celà diminue la taille de mon code ... et moi qui suis payé à la ligne :mouarf:
Comment vérifier les champs d'un formulaire ?
Citation:
Comment vérifier les champs d'un formulaire ?
Pour ce faire, nous utilisons plusieurs classes:
Code:
1 2 3 4 5 6 7
|
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dojox.validate.regexp");
</script> |
La première permet de transformer le formulaire en un widget dojo.
La seconde nous est utile pour obtenir un widget de type bouton, qui sera le bouton pour soumettre le formulaire.
La troisième, comme son nom l'indique, permet de valider la valeur encodée dans un champ de type text.
Et la quatrième fournit quelques expressions régulières toutes faites et bien utiles pour valider le format des valeurs encodées dans les champs d'un formulaire. La liste est bien entendu non exhaustive et vous pouvez l'agrandir selon vos exigences.
L'exemple tout fait le plus "international" est l'adresse e-mail. Lors de la création du champ e-mail, vous devez préciser plusieurs choses à Dojo:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
<form action="page_suivante.php" method="post" id="id_formulaire" dojoType="dijit.form.Form">
e Mail:
<input
id = "id_e_mail"
type = "text"
name = "mon_e_mail"
value = ""
required = "true"
dojoType = "dijit.form.ValidationTextBox"
regExpGen = "dojox.validate.regexp.emailAddress"
invalidMessage = "Erreur de format dans l'e Mail."
/>
</form> |
Tout d'abord, je donne un id à mon formulaire car je m'en servirai plus tard.
Mon champ e Mail a pour dojoType ValidationTextBox qui est très explicite. Il a aussi une regExpGen et dans notre cas, elle s'appelle emailAddress. Finalement, je précise le message d'erreur via l'invalidMessage.
Notez l'attribut required qui indique que le champ est obligatoire ou non.
Vous créez alors votre formulaire entier de cette manière en appelant les diverses regExpGen que vous désirez et pour finir, vous ajoutez le bouton qui soumettra le formulaire en testant les champs recensés:
Code:
1 2 3 4 5 6 7
|
<input
type = "submit"
label = "Soumettre"
dojoType = "dijit.form.Button"
onClick = "dijit.byId('id_formulaire').validate();"
/> |
Ce bouton, de type submit mais de dojoType dijit.form.Button, lance l'évènement onClick. On récupère le formulaire qui a pour id "id_formulaire" et la fonction validate() va vérifier tous les champs de ce formulaire.
Quelques auto manipulations de valeur de champ text (trim, uppercase, ...)
Citation:
Quelques auto manipulations de valeur de champ text (trim, uppercase, ...)
La class TextBox propose quelques attributs qui jouent sur la valeur encodée dans un champ text.
- trim : permet d'enlever les espaces inutiles en début et fin de chaine.
- uppercase: met tous les caractères en majuscules.
- lowercase: met tous les caractères en miniscules.
- propercase: met le premier caractère de chaque mot en majuscule.
Ils sont par défaut à false. Pour les activer, positionnez-les à true. Comme par exemple ici avec le uppercase:
Code:
1 2 3 4 5 6 7 8
|
<input
type = "text"
id = "id_champ"
name = "nom_champ"
dojoType = "dijit.form.TextBox"
uppercase = "true"
/> |
Vérifier qu'un champ à la même valeur qu'un autre
Citation:
Vérifier qu'un champ à la même valeur qu'un autre
Nous pouvons préciser l'attribut validator sur un champ text afin de vérifier sa valeur et dans ce cas-ci, on peut s'en servir pour vérifier que sa valeur est bien la même qu'un autre champ du formulaire. L'exemple courant est celui du mot de passe que l'on demande de taper deux fois:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
<!-- Le premier champ, avec un id -->
Mot de passe:
<input
type = "password"
id = "id_pass_1"
name = "nom_pass_1"
/>
<!-- Le second champ avec le validator qui référencie le premier champ grâce à son id -->
Confirmation:
<input
type = "password"
id = "id_pass_2"
name = "nom_pass_2"
dojoType = "dijit.form.ValidationTextBox"
validator = "return this.getValue() == dijit.byId('id_pass_1').getValue()"
invalidMessage = "La confirmation du mot de passe est incorrecte."
/> |
L'attribut validator reçoit un boolean qui selon sa valeur lancera le invalidMessage.
Différences entre dojo.declare dojo.provide et dojo.require
Citation:
Différences entre dojo.declare, dojo.provide et dojo.require
Les fichiers Javascript Dojo sont appelés des ressources. Y sont décrits des objets complets. Vous pouvez-vous même créer vos objets Dojo. On dit en quelques sorte qu'on déclare l'objet:
Code:
1 2 3 4 5 6 7 8 9 10
|
/* Déclarer la ressource */
dojo.declare(
"dijit.form.TextBox",
null,
{
//...
}
//...
) |
- Le premier paramètre est le nom de l'objet avec son chemin d'accès. Par exemple, les TextBox sont définies dans le répertoire form du répertoire dijit:
- Le second paramètre précise les éventuels ancêtres (de type String ou bien Array).
- Tandis que le dernier paramètre sont les méthodes et les propriétés de l'objet.
Déclarer un objet est une chose. Maintenant, si je veux que cette ressource soit utilisable par l'extérieur (c'est le fichier TextBox.js), je dois le préciser. Cela se fait avec le provide:
Code:
1 2 3
|
/* Mettre la ressource à disposition */
dojo.provide("dijit.form.TextBox"); |
Grâce à cette instruction (mise en tout début de fichier TextBox.js), je vais pouvoir utiliser la TextBox dans ma page. Pour que ma page sache où la trouver, je vais lui indiquer la classe/l'objet qui est requis(e) (en quelque sorte, charger la ressource) et pouvoir l'appeler à ma guise:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
<script>
/* Charger la ressource */
dojo.require("dijit.form.TextBox");
</script>
<!-- Utilisation de la ressource -->
<form name="mon_formulaire" method="post" dojoType="dijit.form.Form">
<input
type = "text"
id = "id_champ"
name = "mon_champ"
dojoType = "dijit.form.TextBox"
/>
</form> |
Syntaxe Déclarative et Syntaxe Programmatique
Citation:
Syntaxe Déclarative et Syntaxe Programmatique
Dojo accepte deux syntaxes pour créer ses widgets: la déclarative que l'on considère comme étant plus facile, et la programmatique qui est plus souple.
Syntaxe Déclarative
Vous créez votre élément comme un élément HTML auquel vous ajoutez des attributs spécifiques à Dojo. Grâce à une instruction ou deux, Dojo va comprendre qu'il doit parser l'arbre DOM d'une certaine manière et transformer les noeuds en widget Dojo selon les attributs spécifiques qu'il trouvera.
Pour préciser à Dojo de parser l'arbre DOM, vous pouvez le lui indiquer directement dans la balise principale du script avec l'instruction parseOnLoad dans l'attribut djConfig:
Code:
1 2
|
<script type="text/javascript" djConfig="parseOnLoad:true" src="dojo-release-1.4.1/dojo/dojo.js"></script> |
Ou bien en ajoutant ces quelques lignes en début de page:
Code:
1 2 3 4 5
|
dojo.require("dojo.parser");
dojo.addOnLoad(function() {
dojo.parser.parse();
}); |
Dès que Dojo rencontrera un dojoType, il remplacera le noeud DOM par le widget Dojo ainsi précisé.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
<script type="text/javascript">
dojo.require("dijit.form.TextBox");
</script>
<input
type = "text"
id = "id_champ"
name = "nom_champ"
dojoType = "dijit.form.TextBox"
jsId = "id_js_champ"
uppercase = "true"
/> |
Le widget créé tiendra compte des différents attributs qui le consitutent et sera sensible aux attributs spécifiques à Dojo comme par exemple le jsId. En effet, lors du parsing, si Dojo rencontre un jsId, il va créer une variable Javascript globale (son nom sera "id_js_champ" d'après l'exemple ci-dessus) dont la valeur est le widget (un objet).
Syntaxe Programmatique
La syntaxe programmatique est plus complexe mais elle permet un plus grand contrôle de ce que l'on désire faire.
On commence naturellement par une instanciation:
Code:
1 2 3 4
|
dojo.require("dijit.form.Button");
var mon_bouton = new dijit.form.Button(objet_proprietes, noeud_DOM); |
Les deux paramètres sont facultatifs. Le premier est un objet, une structure de propriétés spécifiques ou non à Dojo:
Code:
1 2 3 4 5 6 7
|
var objet_proprietes = {
id:"id_bouton",
label:"Mon Bouton!",
jsId:"id_js_bouton",
onClick: function(){alert("Hello World");}
} |
Le second paramètre précise le noeud auquel accrocher le widget:
Code:
1 2 3 4 5 6
|
<div id="mon_div">Ici, il y aura un bouton...</div>
<script type="text/javascript">
var noeud_DOM = dojo.byId("mon_div");
</script> |
Une fois le widget instancié, il faut le "démarrer", le rendre actif. C'est la méthode startup:
Code:
1 2 3
|
var mon_bouton = new dijit.form.Button(objet_proprietes, noeud_DOM);
mon_bouton.startup(); |
Remarque: lorsque le widget est attaché à un widget de type layout avec la méthode addChild() ou bien à un widget de type contentPane avec la méthode setContent(), alors vous ne devez pas faire de startup. Il est fait automatiquement pour peu que vous ayez précisé le djConfig à "parseOnLoad:true".