Archives de catégorie : Javascript

Jquery UI Dialog : Désactiver un bouton

Il peut être intéressant de pouvoir désactiver un bouton d’une boite de dialog jQuery UI. Une méthode simple et flexible consiste à utiliser les sélecteurs :button et :contains.

On peut alors désactiver un bouton en particulier :

$(":button:contains('Texte de mon bouton')").attr("disabled","disabled").addClass( 'ui-state-disabled' );

Et le réactiver le moment venu :

$(":button:contains('Texte de mon bouton')").removeAttr("disabled").removeClass( 'ui-state-disabled' );

Event Delegation ou comment utiliser la propagation des événements

De prime abord la gestion des événements en javascript semble assez simple. Cependant cela devient un peu plus pointu dès que l’on veut optimiser les performances.

L’un des problèmes que l’on rencontre souvent est une page lente à charger et consommant beaucoup de mémoire à cause de nombreux événements à charger.

Le cas classique est un tableau avec des événements sur chaque case du tableau. Si on à un tableaux de 10×10 celà nous fait … 100 événements à attacher.

Pour solutionner le problème et gagner énormément de temps la délégation d’événement ou Event delegation permet de se baser sur la propagation des événements pour n’en utiliser qu’un seul.
Ainsi on attache un événement sur l’élément père et on conditionne le traitement lors de la capture.
Voici un avant/après avec prototype permettant d’attacher un événement sur tous les éléments ayant la classe « change » :

Avant :

$$('.change').each(function(elem){Event.observe(elem,'click',function(){alert('Capture')})});

Ici on passe en revu tous les éléments de la page pour trouver tout ceux ayant la classe « change » et on leur attache un événement particulier.

Avec la délégation d’événement , on à un peu plus de code mais c’est nettement plus rapide :
Après :

Event.observe($('container'),'click',function(e){if(e.element().hasClassName('change')) alert('Capture');});

On attache donc un seul et unique événement sur le conteneur des éléments devant recevoir l’événement. L’événement se propageant les éléments fils , le reçoivent également. Il ne reste donc plus qu’à conditionner le code pour que l’action de l’événement ne s’exécute que sur les class choisie.

getElementsByClassName en javascript

Un des gros avantages avec les librairies javascript telles que prototype , jquery ou encore mootools c’est leur système de sélection d’élément dans le DOM.
Par exemple pour sélectionner tous les liens avec la class css « clickme » il suffit de faire :
[javascrip]var elements = $$(‘a.clickme’);[/javascript]
La syntaxe peut varier d’une librairie à l’autre mais dans l’esprit tout est récupérable avec de simples sélecteurs css.
Le problème étant qu’intégrer une librairie de plusieurs kilos pour une simple sélection est une mauvaise idée.
Voici donc une petite fonction getElementsbyClassName en javascript natif qui comme le selecteur $$ permet de retrouver tous les tags d’une page portant une class spécifique.

<pre>/**
* Récupère les éléments d'une classe précise
* @param string tag Nom de la balise
* @param string cssClass Nom de la class Css
* @return array
*/
function getElementByClassName(tag,cssClass){

var foundElements     = new Array();
var allElements        = document.getElementsByTagName(tag);
for(var i=0;i<allElements.length;i++)
    if(allElements[i].className == cssClass)
        foundElements.push(allElements[i]);

return foundElements;
}</pre>

Cette fonction renvoi donc un tableau des éléments retrouvés dans la page. Très simple elle ne prend cependant pas en compte les éléments avec plusieurs class css , mais c’est très facilement intégrable 🙂

Multilingue Javascript

Développer un site multilingue est assez simple , il existe certain standard tel que gettext sur lesquels il est possible de s’appuyer. En revanche quand arrive le délicat problème du javascript les choses se compliquent.
On peut utiliser la solution bourine du « tableau de traduction » :

<pre>var tabLangue = new Array;
tabLangue["pres_error"]          = "Le formulaire n'est pas correctement rempli";
tabLangue["pres_duree"]          = "La durée doit être une valeur numérique";</pre>

Mais dès qu’il faut intercaler des variables dans les traductions ça devient un enfer!.

J’ai finalement pris mon courage à deux mains et ai pondu une petite classe basée sur [prototype|http://www.prototypejs.org|en] (1.6) qui permet justement d’intégrer très facilement des variables dans les chaines à traduire. Ceux qui ont déjà utilisé gettext ne devrait pas être dépaysé :

var i18n = new I18n();
i18n.load(lang_fr);// On charge l objet de traduction
alert(i18n._('confirm',12)); // clé + argument pour remplacer les %x
alert(i18n._('players','Jean','50')) ;

Les objets de traduction se présentent sous cette forme :

var = lang_fr{
  'confirm' : 'Voulez vous supprimer %0 utilisateurs',
  'players'  : 'Le player de %0 lui à couté %1 euros',
}

Si la classe vous intéresse vous pourrez trouver la source ici : Internationalisation