Mots-clé : javascript

ExtJS et grids : double click, comment faire, howto ?

Cela fait une bonne heure que je cherche comment avoir le double click sur une grid générée dynamiquement.

C’est très simple :

Ce code ne fonctionnait pas, donc si vous êtes dans le même cas que moi, n’ayez pas peur :

this.gridAttributs = Ext.create('Ext.grid.Panel', { 
    border: 0,
    store: this.store,
    columns: [ 
        { text: "id", dataIndex: 'id', sortable: true },
        { ... },
        { ... }
    ],
    celldblclick: function(evt, elem, opts ) { 
        console.log('dblclick');
    }
});

Voici le code qui fonctionne :

this.gridAttributs = Ext.create('Ext.grid.Panel', { 
    border: 0,
    store: this.store,
    columns: [ 
        { text: "id", dataIndex: 'id', sortable: true },
        { ... },
        { ... }
    ]
});
this.gridAttributs.on('cellDblClick', function(evt, elem, opts ) {
    console.log('dblclick');
});

J’espère vous avoir évité de perdre l’heure que moi même j’ai perdu ! 😉

jQuery et changement de css / class / classname

Encore la petite astuce pratique qui vous évitera de chercher des heures :

Très souvent, on veut changer la propriété d’un div. C’est facile via la fonction jQuery

$('#mondiv').css('propriété', 'nouvelle valeur');

Mais si on veut applique carrément tout une classe ?

C’est très simple, c’est la fonction .toggleClass() :

$('#mondiv').toggleClass('nouvelle classe');

jQuery : différence entre visible et hidden

Je voulais tester si un élément est visible, ou non, en jQuery.

Après quelques recherches sur le net, on tombe souvent sur des exemples comme cela :

if ( $("#monid").is(':visible')) {
...
}

C’est une grossière erreur.

Voici l’explication, et le principe qu’il faut avoir en tête :

Lorsqu’on cache ou qu’on montre un élément avec jQuery ou jQueryUI, cela va presque toujours modifier la propriété display (display:none, display:block, etc).

La propriété visible est complètement différente, et est utilisée pour cacher un élément, mais en gardant la place qu’elle occupe.

Pour vérifier si quelque chose est « caché » (notez la subtilité avec la différence de « pas visible« ) il faut vérifier la propriété css display.

Exemple concret :

if ( $("#monid").css('display')!='none') {
...
}

ExtJS 4 first look : le livre que j’ai révisé est sorti !

Voilà, on m’a demandé d’être relecteur technique (technical reviewer) du livre « Ext js 4 first look » que vous pouvez trouver ici :

http://www.packtpub.com/ext-js-4-first-look/book

Ce livre parle de ExtJS 4 et de toutes les (nouvelles) possibilités qu’offre le nouveau framework de Sencha, ansi que des comparaisons avec les anciennes versions, pour ceux qui connaissent déjà ExtJS.

Je suis au début :

Livre Ext js 4 first look

C’est un livre très pédagogique, qui vous servira bien si vous débutez.
Vous aurez certainement quelques marque page, notamment en ce qui concerne le MVC, qui n’est pas facile à appréhender (selon moi). J’avais d’ailleurs fait un howto ici.

Mon conseil serait : achetez-le, il est très bien.

Notez cependant qu’il faut un bon niveau JavaScript pour comprendre le livre.

ExtJS : exemple d’un développement

Voici une petite capture d’image d’un Intranet que j’ai développé.

Temps de développement : trois jours à temps plein.

Tout fonctionne parfaitement, en AJAX, synchronisation, etc.

Tout ça pour dire que ExtJS est vraiment une librairie formidable dans ce type de cadre :

Image d'exemple de développement d'un intranet en ExtJS

Firefox : javascript et bookmarklets

On peut éxecuter du javascript dans Firefox directement dans la ligne de l’adresse Internet.

Attendez, c’est génial, je le redis, vous n’avez pas compris :

Savez vous qu’on peut éxecuter du javascript dans Firefox directement dans la ligne de l’adresse Internet ?

En pratique ça donne quoi ?

J’en ai marre de taper systématiquement mon identifiant et mon mot de passe pour me connecter à un intranet.
J’ai un bouton qui est un raccourci classique :

Firefox - javascript et bookmarklets

Et au lieu d’un raccourci « simple » genre http://translate.google.com/ c’est un code JavaScript comme ça :
javascript:(function(){m='http://translate.google.com/translate?u='+encodeURIComponent(document.location)+'&langpair=en%7Cfr&hl=en&ie=UTF-8&oe=UTF-8';w=window.open(m,'addwindow','resizable=yes');setTimeout(function(){w.focus();},%20250);})();

Qu’est ce que ça fait : je peux être sur n’importe quelle page en anglais, je clique sur le bouton, et hop ! Il m’ouvre une autre fenêtre avec la page traduire via http://translate.google.com/. Magique !

Mais on peut faire encore plus pratique !

Par exemple, moi j’ai un raccourci pour me connecter sur un site personnel, mais ce dernier me demande toujours mon identifiant et mon mot de passe, qui sont systématiquement effacés, alors j’ai fait un second bouton dans lequel il y a du JavaScript qui remplit les champs automatiquement et simule le clic sur « valider ». Donc en pratique, je clique une fois, hop, la page s’affiche, je clique une seconde fois et je suis connecté. Je gagne un temps fou !

Et même chose pour les développeurs de paiement en ligne : vous en avez marre de remplir systématiquement les champs avec les numéros de cartes factices afin de tester, et de mettre une bonne date ? Hop il suffit de créer correctement un bon morceau de JavaScript et ça y est vous remplissez systématiquement TOUS les champs en un seul clic ! Gain de temps phénoménal.

Vous avez plein d’exemples ici :

http://mozillalinks.org/resources/bookmarklets-collection/

Pour la note, cela fonctionne aussi sur Chrome.

En espérant que cela serve à la communauté !

jQuery : animate(), queue() et dequeue() solution

Voilà le problème que je viens de rencontrer et que vous avez sûrement rencontré si vous faites un petit peu de jQuery : j’ai fait un <div></div> qui était un petit rectangle, et je voulais, que lorsque la souris entre dedans, il s’agrandisse, et lorsqu’elle en sort, il diminue.

Le problème (qui est la plupart du temps un avantage) avec jQuery, c’est que lorsqu’une animation commence, s’il y en a une autre pour le même élément, il la met dans une queue() (toute plaisanterie grivoise mise à part).
Donc, si, comme moi, vous voulez faire une animation assez lente, et que vous entrez et sortez rapidement avant la fin de l’animation, il va y avoir plein d’éléments qui vont aller à l’intérieur, et… même si vous éloignez la souris, les animations d’entrée-sortie vont continuer à jusqu’à ce que la queue soit vide ! …là aussi toute plaisanterie grivoise mise à part.

La solution est simple : il faut non seulement dire à l’élément concerné d’arrêter l’animation via stop(), mais aussi :

  1. dire de supprimer tout ce qu’il y a dans la queue (premier paramètre = true)
  2. dire de jouer immédiatement l’animation qui suit (premier paramètre = true)

Exemple de code qui fonctionne :

  $('tr')
    .mouseenter(function() {
      var id=$(this).attr('id').substring(3);
      var c=$(this).children('.principal').children('.texte');
      c.stop(true, true).animate({ height: '400px'}, 'slow');
    })  
    .mouseleave(function() {
      var c=$(this).children('.principal').children('.texte');
      c.stop(true, true).animate({ height: '89px'}, 'slow');
    }); 

ExtJs, DataGrid, Store et événements : mémo pour le déboguage

Voici un petit mémo simple : si vous essayez de comprendre dans quel ordre se font les événements, je vous conseille de lire la page ici.

Parmi tout ce qui est expliqué, voici ce que j’utilise le plus souvent : une fonction de trace des événements.
Faites comme moi : un bon copier-coller des familles, et vous aurez dans votre console tous les événements concernant l’objet que vous voulez :

function captureEvents(observable) {
    Ext.util.Observable.capture(
        observable,
        function(eventName) {
            console.info(eventName);
        },
        this
    );		
}
 
Ext.onReady(function(){
    var grid = new Ext.grid.GridPanel({
        ... 
    });
 
    captureEvents(grid);
});

Exemple concret : j’avais un problème, lorsque je créais un nouvel enregistrement dans une DataGrid, j’avais beau essayer de le sélectionner, rien n’y faisait. J’ai cherché pendant des heures, j’ai essayé d’éliminer au fur et à mesure des choses, jusqu’à ce que je mette en place ce code, et là, magie, dans la console :

>beforeload
>datachanged
>load
>read
>add
>datachanged
>beforesync
>write
>datachanged

J’ai vu qu’en fait après l’événement d’ajout « add » sur lequel je comptais pour sélectionner l’élément en cours, il y avait… une mise à jour (« beforesync », « write », « datachanged ») !
En fait ça a fait tilt : j’avais activé la synchronisation automatique des données, et donc juste après l’insertion, le store tentait de se synchroniser, donc la sélection était inévitablement dé-sélectionnée.

Ici aussi, comme dans la plupart de mes articles techniques, j’espère avoir aidé la communauté et avoir évité à d’autre personnes de perdre des heures inutiles, comme celles que j’ai passées !

Smarty 3.1 et les plugins : comment faire / howto

Sur la toute dernière version de Smarty (3.1), voici comment créer un plugin personnalisé.
Pour résumer, l’un de mes sites n’était pas assez optimisé.
Le code qui sortait était :

<body class="sbody">
    <div>
....
    </div>
....
</body>

J’ai donc ajouté le filtre d’optimisation qui supprime les espaces en début :

$this->smarty->loadFilter('output', 'trimwhitespace');

Le code de sortie est devenu :

<body class="sbody"><img src="/title.jpg" /><div>....</div>....</body>

Tout mise en une ligne, super !
Le seul problème, c’est que ça ne fonctionnait pas avec le code JavaScript, il faut en effet les retours à la ligne.
J’ai donc crée mon plugin qui ne fait que supprimer les espaces en début de ligne, et remplacer de « retour + line feed » (deux octets) de fin de ligne par un seul octet « retour ».

Voici le code, je vous laisse comprendre, c’est extrêmement simple :

/* Déclarer un plugin "block".
 * Block = il faut un début et une fin.
 * Ici : {triml} {/triml}
 */
$this->smarty->registerPlugin('block',
  'triml', array($this,'smarty_block_trim_l'));

Après avoir déclaré le plugin, il faut faire la fonction adéquate :

/**
 * Fonction de plugin smarty pour supprimer tous les espaces
 * en début de ligne entre les blocs {triml}{/triml}
 * "triml" = trimleft
 * Voir le constructeur et chercher $this->smarty->registerPlugin()
 *
 * @param array $params les paramètres qu'on passe à {strip_nl}
 * @param variant $content Le contenu qu'il y a dans le bloc
 * @param variant $template Le nom du template
 * @param variant &$repeat
 *
 * @return int Description retour
 */
public function smarty_block_trim_l(
  array $params, $content, $template, &$repeat)
{
  $content = preg_replace('/\n[\s]+/', "\n", $content);
  return $content;
}

Et voilà maintenant, vous pourrez aussi optimiser votre site comme un professionnel.
Bien évidemment le gain le plus gros est dans la compression (voir mod_deflate)

JavaScript : comment tester, et faire partager très rapidement son code

Supposons que vous vouliez montrer quelques exemples de code JavaScript, mais surtout, le partager rapidement.
C’est très simple : avec http://jsfiddle.net/, vous tapez votre exemple de code, et à la fin vous cliquez sur « sauver » et hop, une URL automatique est créée. Il vous suffit de copier colle le lien pour partager votre code exemple (ou votre code qui démontre qu’une librairie a un problème, par exemple).