ExtJS ExtJS est un formidable framework JavaScript tout-en-un sous double licence dont la Gnu GPL3 et qui permet notamment de faire du MVC.

Toutefois, il génère lui-même l'interface utilisateur, ce qui le rend plus approprié pour des applications web d'entreprise (interface mimant du client lourd). Mais il faut bien dire que, quelque fois, certaines choses ne sont pas immédiates. Voici par exemple, comment faire en sorte, dans une application ExtJS MVC que le navigateur propose à l'utilisateur de mémoriser le mot de passe associé à l'identifiant saisi, ce qui ne fonctionne pas a priori avec un formulaire ExtJS.

Pour que cela fonctionne, c'est-à-dire pour que le navigateur se sente concerné et propose d'enregistrer le mot de passe, il lui faut plusieurs choses que ExtJS ne lui donne pas :

  • un formulaire HTML (balise form)
  • avec deux champs (input) text dont un de type password
  • sans attribut autocomplete positionné à off.

Or ExtJS:

  • ne crée pas de balise form dans ses formulaires
  • génère après chargement de la page le HTML contenant les champs mentionnés
  • ajoute systématiquement l'attribut autocomplete mis à off

Côté contrôleur, rien de spécial, on gère normalement le clic sur le bouton de notre formulaire. Tout va se passer côté vue, donc dans notre répertoire app/view. Dans notre cas, ce sera dans app/view/connexion. On commence par dériver le type textfield pour remettre autocomplete à on :

 Ext.define('Poum.view.Connexion.ACField', {
   extend: 'Ext.form.field.Text',
   alias: 'widget.ConnexionACField',
 
   initComponent: function() {
       Ext.each(this.fieldSubTpl, function(oneTpl, idx, allItems) {
           if (Ext.isString(oneTpl)) {
               allItemsidx = oneTpl.replace('autocomplete="off"', 'autocomplete="on"');
           }
       });
       this.callParent(arguments);
   }
 });

Note: Poum est l'espace de nommage de l'application.

Dans notre formulaire, on va d'abord indiquer la dépendance à notre ACField:

 Ext.require('Poum.view.Connexion.ACField');
 
 Ext.define('Poum.view.Connexion.Form', ...

Ensuite, on demande, dans la méthode initComponent, la génération de la balise form :

 initComponent: function() {
 ...
 this.autoEl = {
   tag: 'form',
   method: 'post'
 };

Enfin, on définit nos champs dans cette même méthode:

 this.items = [{
     xtype: 'ConnexionACField',
     fieldLabel: 'Identifiant',
     id: 'champ_identifiant_connexion',
     name: 'identifiant',
     emptyText: 'identifiant Intradef'
   },{
     xtype: 'ConnexionACField',
     fieldLabel: 'Mot de passe',
     id: 'password',
     name: 'mot_de_passe',
     inputType: 'password'
   }];

On finit la méthode avec notre bouton de type submit:

 this.buttons = [{
     text: 'Se connecter',
     action: 'authentification',
     formBind: true,
     type: 'submit',
   }];
 
   this.callParent(arguments);
 }

Dans le contrôleur, on instancie normalement le formulaire :

 Ext.create('Ext.panel.Panel ...

Enfin, dans le template ou la page HTML, on ajoute un formulaire statique pour feinter le navigateur:

<form id="loginForm" action="/connexion.json" method="post">
           <input class="x-hidden" type="text" name="identifiant" id="champ_identifiant_connexion"/>
           <input class="x-hidden" type="password" name="mot_de_passe" id="password"/>
</form>

Noter la class x-hidden pour que ce formulaire ne s'affiche pas.

Et voilà, ça devrait le faire sans passer par l'enregistrement dans un cookie, ce qui n'est pas recommandé du point de vue sécurité.