Mots-clé : extjs4

ExtJS : comment envoyer une form au format JSON ?

Je viens de passer 4 heures à chercher comment envoyer, avec ExtJS, une forme au format JSON.

Ce qui suit ne fonctionne pas :

form.submit({
    type: 'ajax',
    headers: {
        'Content-Type': 'application/json'
    },
    url: '/json/destination.php',
    jsonData: data,
    params: {
        mode: 'update'
    },
    success: function(form, action) {
        /* ok !! */
    },
    failure: function(form, action) {
        /* gérer les erreurs */
    }
});

Si vous essayez d’utiliser la fonction « submit » alors vous risquez, comme moi peut être, de ne pas y arriver.
La solution est :

  • récupérer soi même les données via getValues() ;
  • les encoder au format JSON ;
  • les envoyer avec la méthode Ext.Ajax.request().

Voici un exemple de code qui fonctionne :

var data = Ext.JSON.encode({ data: form.getValues(false) }); 
Ext.Ajax.request({
    headers: {
        'Content-Type': 'application/json'
    },
    url: '/json/destination.php',
    method : 'POST',
    jsonData : data,
    params : {
        mode: 'update'
    },
    success: function(form, action) {
        /* ok !! */
    },
    failure: function(form, action) {
        /* gérer les erreurs */
    }   
});

J’ai perdu 4 heures là dessus, alors si je vous en fais gagner 3, n’oubliez pas de me « flattr » 😉

Sencha / ExtJS : comment garder une colonne triée avec une grid ?

Quand on fait une grille de données (datagrid) et qu’on la lie avec un magasin (store) c’est facile.

On peut autoriser à trier par colonnes dans la datagrid.

Seul problème : si le store est un stocké sur le serveur, il fait une seule fois l’appel et ensuite c’est la datagrid qui gère les tris.

Quand on modifie un enregistrement, il est envoyé au serveur, le serveur l’enregistre, et renvoie le résultat de ce qu’il a enregistré. Généralement, il renvoie exactement ce qu’il a reçu. Le seul problème, c’est qu’au retour, la grille ne rafraichit pas l’ordre de tri selon les colonnes qu’on a choisies.

Exemple concret : vous avez une grille avec plein de noms. Vous cliquez sur la colonne « nom », pour la trier par ordre alphabétique. Vous changez le nom « Albert » par « Zoé ». Voici ce qu’il se passe :

  • Le store envoie id=54, nom="Zoé" au serveur ;
  • Le serveur fait la modification en base, et renvoie id=54, nom="Zoé" en retour ;
  • Le store reçoit id=54, nom="Zoé", fait son changement en interne et le transmet à la datagrid ;
  • La datagrid se rafraichit mais ne change pas le tri et laisse "Zoé" à la même place.

La solution : dans le store, lors de l’événement qui signale que le résultat de l’écriture a été intégré (« write« ) il faut forcer l’appel à sort(); qui sera répercuté sur la datagrid automatiquement.

Voici mon code (raccourci à l’extrême sur ma classe de store qui gère les exceptions et plein d’autres choses) :

Ext.define('Ext.data.StoreHandleErrors', {
    extend: 'Ext.data.Store',
    alias: 'data.storehandleerrors',

    constructor: function(config) {
        this.callParent([config]);

        this.on(
            'write',
            function(me, opts) {
                this.sort();
            },
            this
        );
    }
});