2011-11-09 7 views
6

Ho letto questo articolo: http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/Aggiungere una sottomaschera a un modulo con ajax sulla presentare

Questo è stato molto interessante e funziona benissimo.

Ho bisogno di fare lo stesso ma con una SubForm. Intendo dire che quando un utente preme un pulsante, chiamo, tramite ajax, un'azione che aggiunge, collega e visualizza una sottomaschera al mio modulo esistente.

Ad esempio:
Ho un modulo in cui un utente deve compilare il nome e il cognome dei suoi figli, quindi c'è un pulsante "Aggiungi bambino". Quando l'utente preme quel pulsante, una SubForm deve essere aggiunta al mio modulo esistente e visualizzata. Al momento dell'invio verrà convalidato esattamente come nell'esempio in quell'articolo. L'unica differenza è che lì semplicemente aggiunge un singolo campo. Devo aggiungere una SubForm, ma esattamente nello stesso modo.

Ho provato quanto segue nella mia azione (chiamato da Ajax):

public function clonerecursivegroupAction() 
{ 
    $this->_helper->layout->disableLayout(); 
    $ajaxContext = $this->_helper->getHelper('AjaxContext'); 
    $ajaxContext->addActionContext('clonerecursivegroup', 'html')->initContext(); 

    $id = $this->_getParam('id', null); 

    $subform1 = new Zend_Form_SubForm(); 

    $Element1 = $subform1->createElement('text', 'text1'); 
    $Element1->setLabel('text1')->setRequired(true); 
    $Element2 = $subform1->createElement('text', 'text2'); 
    $Element2->setLabel('text2')->setRequired(false); 

    $subform1->addElement($Element1); 
    $subform1->addElement($Element2); 

    $this->view->field = $subform1->__toString(); 
} 

Questo quasi funziona.
La vista di questa azione restituisce il codice html della SubForm, quindi in caso di successo della mia chiamata ajax lo visualizzo semplicemente.

Il problema è che all'invio esso convalida il modulo ma ha perso la nuova sottomaschera appena aggiunta. Questo non succede nell'articolo con un solo elemento. Penso che ho solo bisogno di aggiungere la SubForm al Form esistente, ma come?

+0

Ciao Samuele è necessario verificare convalida biblioteca js per assicurare quello che fa, Come ho Conosco la maggior parte della libreria aggiungi la convalida a form e id se aggiungi un modulo diverso (Form in form) Non convalida il modulo completo –

risposta

2

Aggiungere un prefisso della sottomaschera agli elementi della sottomaschera. Ho usato il prefisso "child" per rappresentare le sottomaschere. Ogni sottomaschera verrà creata come child1, child2 e così via.

public function clonerecursivegroupAction() 
{ 
     //.. Other code 

     $subform = new Zend_Form_SubForm(); 
    $subform->setIsArray(true); 
    $subform->setName("child$id"); 
    $Element1 = $subform->createElement('text', "newfield$id"); 
    $Element1->setLabel("newfield$id") 
      ->setRequired(true); 
    $subform->addElement($Element1); 

    $Element1 = $subform->createElement('text', "nextfield$id"); 
    $Element1->setLabel("nextfield$id") 
      ->setRequired(true); 

    $subform->addElement($Element1); 

    $this->view->field = $subform; 
// Rest of your statements 

} 

Poi, nella funzione prevalidazione, filtrare i sottomoduli utilizzando il prefisso sottomodulo, al posto del nome del campo:

public function preValidation(array $data) { 
     // array_filter callback 
     function findForms($field) { 
     // return field names that include 'child' 
      if (strpos($field, 'child') !== false) { 
       return $field; 
      } 
     } 

     $subForms = array_filter(array_keys($data), 'findForms'); //filter the subform elements 

     $children = array(); 
     foreach ($subForms as $subform) { 

      if (is_array($data[$subform])) { 
     $children[$subform] = $data[$subform]; 
     } 

     } 

     //Iterate the children 
     foreach ($children as $key => $fields) { //$key = subformname, $field=array containing fiend names and values 

     // strip the id number off of the field name and use it to set new order 
     $order = ltrim($key, 'child') + 2; 
     $this->addNewForm($key, $fields, $order); 
    } 

}

Aggiungi funzione nuova forma crea ciascuna delle forme secondarie e attribuisce alla maschera principale:

 public function addNewForm($form, $elements, $order) { 

      $subform = new Zend_Form_SubForm(); 
    $subform->setIsArray(true); 
    foreach ($elements as $key => $el) { 
      $Element1 = $subform->createElement('text', $key); 
       $Element1->setLabel($form.$key) 
      ->setValue($el) 
       ->setRequired(true); 
        $subform->addElement($Element1); 
    } 
     $this->addSubForm($subform, $form, $order); 

    } 

[EDIT] Utilizzando setIsArray un cre sottomaschera ates ogni elemento della sottomaschera come un elemento dell'array. Semplifica la funzione preValidate. Modificato il codice per utilizzare questa funzionalità.

Vedi l'complete code in pastebin

Ecco un'altra soluzione con belongsTo, fornendo notazione di matrice per gli elementi del modulo sotto: http://www.stephenrhoades.com/?p=364