2009-06-29 5 views
4

J'ai un FormPanel affichant un formulaire assez basique, essentiellement, il contient juste un champ "Nom", un champ "Description" et plusieurs zones de texte "Règles". Ce que je veux, c'est que l'utilisateur puisse taper du texte dans la première zone de texte Règle et avoir un autre TextField vide (quand il commence à taper) pour une règle supplémentaire.Ajouter dynamiquement des zones de texte à un FormPanel sur l'entrée utilisateur avec ExtJS

Actuellement, j'ai une fonction qui devrait générer de nouvelles TextAreas lorsqu'elle est appelée avec un nom spécifié (la fonction newRulesField), et une fonction pour gérer les événements KeyPress dans mes zones de texte.

Ce que je cherche essentiellement, c'est comment je peux modifier dynamiquement le nombre de TextAreas dans le formulaire.

est ici le code, au cas où il aide:

function handleRuleKeypress(a,b) { 
    Ext.Msg.alert('kp'); 
} 

function newRulesField(name) { 
    var rulesField = new Ext.form.TextArea({ 
    fieldLabel:  'Rules', 
    anchor:   '100%', 
    name:   name, 
    allowBlank:  false, 
    grow:   false, 
    enableKeyEvents: true, 
    listeners: { 
     keypress: handleRuleKeypress 
    } 
    }); 
    return rulesField; 
} 

function handleNewRuleSetClick(nodes) { 

    var nameField = new Ext.form.TextField({ 
    fieldLabel: 'Name', 
    name:  'ruleSetName', 
    anchor:  '100%', 
    allowBlank: false, 
    grow:  false 
    }); 

    var descField = new Ext.form.TextField({ 
    fieldLabel: 'Description', 
    name:  'ruleSetDescription', 
    anchor:  '100%', 
    allowBlank: false, 
    grow:  false 
    }); 

    var form = new Ext.FormPanel({ 
    labelWidth: 75, 
    defaultType: 'textfield', 
    bodyStyle: 'padding:30px', 
    id:   'newRuleSetPanel', 
    name:  'newRuleSetPanel', 
    title:  'New Rule Set', 
    buttons: [{ 
     text: 'Save', 
     id:  'saveBtn', 
     hidden: false, 
     handler: function() { 
     form.getForm().submit({ 
      url:  'server/new-rule-set', 
      waitMsg: 'Saving...', 
      success: function(f,a) { 
      Ext.Msg.alert('Success', 'It worked'); 
      }, 
      failure: function(f,a) { 
      Ext.Msg.alert('Warning', 'Error'); 
      } 
     }); 
     } 
    },{ 
     text: 'Cancel', 
     id:  'cancelBtn', 
     hidden: false 
    }] 
    }); 

    form.add(nameField); 
    form.add(descField); 
    form.add(newRulesField('rules1')); 

    this.add(form); 
    this.doLayout(); 
} 

Répondre

4

vous êtes très proche de le faire déjà - il suffit d'appeler votre fonction newRulesField de votre handleRuleKeypress fonction. quelque chose comme ceci:

function handleNewRuleSetClick(nodes) { 

    var nameField = new Ext.form.TextField({ 
     fieldLabel: 'Name', 
     name: 'ruleSetName', 
     anchor: '100%', 
     allowBlank: false, 
     grow: false 
    }); 

    var descField = new Ext.form.TextField({ 
     fieldLabel: 'Description', 
     name: 'ruleSetDescription', 
     anchor: '100%', 
     allowBlank: false, 
     grow: false 
    }); 

    var form = new Ext.FormPanel({ 
     labelWidth: 75, 
     defaultType: 'textfield', 
     bodyStyle: 'padding:30px', 
     id: 'newRuleSetPanel', 
     name: 'newRuleSetPanel', 
     title: 'New Rule Set', 
     buttons: [{ 
      text: 'Save', 
      id: 'saveBtn', 
      hidden: false, 
      handler: function() { 
       form.getForm().submit({ 
        url: 'server/new-rule-set', 
        waitMsg: 'Saving...', 
        success: function(f, a) { 
         Ext.Msg.alert('Success', 'It worked'); 
        }, 
        failure: function(f, a) { 
         Ext.Msg.alert('Warning', 'Error'); 
        } 
       }); 
      } 
     }, { 
      text: 'Cancel', 
      id: 'cancelBtn', 
      hidden: false 
}] 
     }); 

     function handleRuleKeypress(a, b) { 
      form.add(newRulesField('rules' + Ext.id())); 
     } 

     function newRulesField(name) { 
      var rulesField = new Ext.form.TextArea({ 
       fieldLabel: 'Rules', 
       anchor: '100%', 
       name: name, 
       allowBlank: false, 
       grow: false, 
       enableKeyEvents: true, 
       listeners: { 
        keypress: handleRuleKeypress 
       } 
      }); 
      return rulesField; 
     } 



     form.add(nameField); 
     form.add(descField); 
     form.add(newRulesField('rules1')); 

     this.add(form); 
     this.doLayout(); 
    } 

vous voulez une logique supplémentaire pour vérifier si vous avez déjà ajouté la nouvelle zone de texte (ou vous obtiendrez un nouveau pour chaque pression de touche), la suppression peut-être la zone de texte supplémentaire si la dernière la règle est vidée plus tard, et la fixation de l'identifiant de textarea est un peu plus jolie (tout ceci est votre handleRuleKeypress func). Mes réflexions générales sur la conception de votre application consistent à garder le FormPanel en tant que membre de la classe à la place d'un membre de la fonction privée, ce qui le rendra plus facile à modifier après la création - empiler des fonctions comme celles-ci. très joli ni lisible.

+0

Je trouve que les fonctions internes sont une merveilleuse façon de cacher vos données afin qu'elles ne soient disponibles que là où vous en avez besoin. Il se peut que pour de plus grandes applications vous ayez besoin d'accéder à ce var ailleurs, mais plusieurs fois vous ne le faites pas ... et cela vous aide à savoir que cette variable ne peut pas être utilisée ailleurs –

+0

Je préfère le même style de code que celui utilisé dans la source extjs, je marque la fonction comme private dans son commentaire plutôt que d'empiler des fonctions les unes dans les autres. Non seulement pour se conformer, mais aussi parce que je pense que c'est plus propre et plus facile à lire. Cela permet de réutiliser une fonction dans plusieurs autres fonctions (publiques/privées) de la classe. Mais finalement je suppose que c'est juste une question de goût ... – Tewr

Questions connexes