2010-10-26 8 views
0

J'ai un peu de mal à ajouter/supprimer des champs d'un formulaire ExtJS. Mon cas d'utilisation est le suivant:Problème lié à l'ajout et à la suppression de champs de formulaire ExtJS

Fournir un ensemble de boutons radio sur le formulaire. Selon le bouton radio sélectionné, affichez un ensemble différent de champs de formulaire. Je ne suis pas familier avec ExtJS, mais ce que je fais est de mettre en cache les champs qui doivent être ajoutés/supprimés et les ajouter/les retirer du formulaire lorsque l'événement de changement de bouton radio est déclenché. Voici une version simplifiée de mon code:

var textFieldA = new Ext.form.TextField({ 
    fieldLabel: 'Text Field A', 
    name: 'text_field_a', 
    allowBlank: false 
}); 

var textFieldB = new Ext.form.TextField({ 
    fieldLabel: 'Text Field B', 
    name: 'text_field_b', 
    allowBlank: false 
}); 

var form = new Ext.FormPanel({ 
    autoScroll: true, 
    bodyStyle: 'padding: 5px 5px 0', 
    border: false, 
    frame: true, 
    layout: 'form', 
    items: [{ 
     xtype: 'fieldset', 
     fieldLabel: 'Fieldset', 
     autoHeight: true, 
     items: [{ 
      xtype: 'radiogroup', 
      fieldLabel: 'Show text field', 
      columns: 1, 
      vertical: true, 
      items: [ 
       { 
        xtype: 'radio', 
        boxLabel: 'Show field a', 
        name: 'field_to_show', 
        inputValue: 'a' 
       }, 
       { 
        xtype: 'radio', 
        boxLabel: 'Show field b', 
        name: 'field_to_show', 
        inputValue: 'b' 
       } 
      ], 
      listeners: { 
       'change': { 
        fn: function(radioGroup, selectedRadio) { 
         switch (selectedRadio.getGroupValue()) 
         { 
          case 'a': 
           radioGroup.findParentByType('fieldset').remove(textFieldB); 
           radioGroup.findParentByType('fieldset').add(textFieldA); 
           break; 
          case 'b': 
           radioGroup.findParentByType('fieldset').remove(textFieldA); 
           radioGroup.findParentByType('fieldset').add(textFieldB); 
           break; 
         } 
         radioGroup.findParentByType('fieldset').doLayout(); 
        } 
       } 
      } 
     }] 
    }] 
}); 

form.render('container'); 

Cela fonctionne la première fois chaque radio est sélectionné, mais les sélections suivantes ne fonctionnent pas comme j'attendre. Dans Firefox, une erreur JavaScript est déclenchée:

L'opération n'est pas prise en charge "code:" 9 [Pause sur cette erreur] return !! (p.compareDocumentPosition (c) & 16); dans le fichier ext-base-debug-w-comments.js

Dans Chrome, seules les étiquettes seront ajoutées au formulaire.

Est-ce que je m'attends à ce que cela fonctionne incorrect?

Répondre

2

Je ne reviendrai pas nécessairement prendre l'approche de l'ajout/suppression du fileds- pourquoi ne pas donner à chaque champ un id (aussi bonnes pratiques pour les champs de formulaire) en utilisant:

id:'fieldname' 

Ensuite, soit masquer/afficher le champ selon le cas en utilisant:

Ext.getCmp('fieldname').hide() 
Ext.getCmp('fieldname').show() 
+1

Ils seront toujours soumis mais pas? Malheureusement, certains champs auraient le même nom (en raison de la façon dont cela est traité côté serveur). –

+1

Avez-vous pensé à utiliser des fieldsets? – SW4

2

J'ai écrit une forme très similaire. Si le seul élément commun est le groupe radio, voici ce que je suggère:

Créez un conteneur externe qui contient le groupe Radio, puis un sous-conteneur avec CardLayout. Chaque enfant de cette disposition de carte contient un formulaire avec les champs pour les différents états du RadioGroup. Ajoutez des écouteurs à RadioGroup. Lorsque la sélection change, vous modifiez l'élément actif dans le conteneur de carte.

Code de base pour vous lancer à partir de quand je l'ai fait:

OuterForm = Ext.extend(Ext.Container, { 
    initComponent: function() { 
     Ext.apply(this, { 
      layout: "vbox", 
      layoutConfig: { align: "stretch" } 
     }); 
     this.items = [{ 
      xtype: "container", 
      layout: "form", 
      items: [{ 
       xtype: "radiogroup", 
       fieldLabel: "Form to fill out", 
       ref: "../../formSelector", 
       items: [{ 
        name: "type", 
        inputValue: "1", 
        boxLabel: "Form 1" 
       }, { 
        name: "type", 
        inputValue: "2", 
        boxLabel: "Form 2" 
       }], 
       listeners: { 
        scope: this, 
        change: function(rg, checkedItem) { 
         this.formContainer.layout.setActiveItem(parseInt(checkedItem.inputValue)); 
        } 
       } 
      }] 
     }, { 
      xtype: "container", 
      layout: "card", 
      flex: 1, 
      ref: "formContainer", 
      items: [{ 
       xtype: "form1" 
      }, { 
       xtype: "form2" 
      }] 
     }]; 

     OuterForm.superclass.initComponent.call(this); 
    } 
}); 

Non testé les fautes de frappe/bugs, mais juste définir une hauteur de la forme extérieure, créez vos xtypes de Form1 et Form2 et il devrait fonctionner .

Si vous avez besoin de tous les champs d'un même formulaire, faites OuterForm étendre FormPanel au lieu de définir form1 et form2 comme FormPanels indépendants.

+0

C'est en gros l'approche que j'ai prise dans le passé également. Vous prédéfinissez les champs sur des panneaux de contenu distincts qui sont affichés/masqués en fonction de la sélection du bouton radio. Vous pouvez également personnaliser vos paramètres de soumission de formulaire en fonction du panneau de formulaire actuellement utilisé. –