Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Zend Framework - Dynamically add subforms to form using Ajax

By: janenz00 on Nov 3rd, 2012  |  syntax: PHP  |  size: 5.14 KB  |  views: 947  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /**
  2.  * An extension to Jeremy Kendall's code (http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/). Instead of adding single element, the code below attempts to dynamically add a set of elements to a form.
  3.  
  4. /*
  5. index controller:
  6.  
  7. <?php
  8.  
  9. class IndexController extends Zend_Controller_Action
  10. {
  11.    public function indexAction ()
  12.     {
  13.         $form = new Application_Form_Dynamic();
  14.         // Form has not been submitted - pass to view and return
  15.         if (! $this->getRequest()->isPost()) {
  16.             $this->view->form = $form;
  17.             return;
  18.         }
  19.         // Form has been submitted - run data through preValidation()
  20.         $form->preValidation($_POST);
  21.         // If the form doesn't validate, pass to view and return
  22.         if (! $form->isValid($_POST)) {
  23.             $this->view->form = $form;
  24.             return;
  25.         }
  26.         // Form is valid
  27.         $this->view->form = $form;
  28.     }
  29.    
  30.     public function newfieldAction ()
  31.     {
  32.         $this->_helper->layout->disableLayout();
  33.         $ajaxContext = $this->_helper->getHelper('AjaxContext');
  34.         $ajaxContext->addActionContext('addelm', 'html')->initContext();
  35.         $id = $this->_getParam('id', null);
  36.         $subform = new Zend_Form_SubForm();
  37.         $subform->setIsArray(true);
  38.         $subform->setName("child$id");
  39.         $Element1 = $subform->createElement('text', "newfield$id");
  40.         $Element1->setLabel("newfield$id")->setRequired(true);
  41.         $subform->addElement($Element1);
  42.         $Element1 = $subform->createElement('text', "nextfield$id");
  43.         $Element1->setLabel("nextfield$id")->setRequired(true);
  44.         $subform->addElement($Element1);
  45.         $this->view->field = $subform;
  46.     }
  47. }
  48. ?>
  49.  
  50. Form class:
  51. <?php
  52. class Application_Form_Dynamic extends Zend_Form
  53. {
  54.     public function init ()
  55.     {
  56.         $element = new Zend_Form_Element_Text('name');
  57.         $element->setRequired(true);
  58.         $this->addElement($element);
  59.         $this->addElement('hidden', 'id', array('value' => 1));
  60.         $element = new Zend_Form_Element_Button('addentries',
  61.         array('id' => 'add'));
  62.         $element->setOrder(90);
  63.         $this->addElement($element);
  64.         $element = new Zend_Form_Element_Button('removeentries',
  65.         array('id' => 'remove'));
  66.         $element->setOrder(91);
  67.         $this->addElement($element);
  68.         $element = new Zend_Form_Element_Submit('submit');
  69.         $element->setOrder(92);
  70.         $this->addElement($element);
  71.     }
  72.     /**
  73.      * After post, pre validation hook
  74.      *
  75.      * Finds all fields where name includes 'newName' and uses addNewField to add
  76.      * them to the form object
  77.      *
  78.      * @param array $data $_GET or $_POST
  79.      */
  80.     public function preValidation (array $data)
  81.     {
  82.         // array_filter callback
  83.         function findForms ($field)
  84.         {
  85.             // return field names that include 'newName'
  86.             if (strpos($field, 'child') !== false) {
  87.                 return $field;
  88.             }
  89.         }
  90.         $subForms = array_filter(array_keys($data), 'findForms');
  91.         $children = array();
  92.         foreach ($subForms as $subform) {
  93.             if (is_array($data[$subform])) { // subforms added earlier will be passed to post as an array
  94.                 $children[$subform] = $data[$subform];
  95.             }
  96.            
  97.         }
  98.         foreach ($children as $key => $fields) {
  99.            
  100.             // strip the id number off of the field name and use it to set new order
  101.             $order = ltrim($key, 'child') + 1;
  102.             $this->addNewForm($key, $fields, $order);
  103.         }
  104.     }
  105.     public function addNewForm ($form, $elements, $order)
  106.     {
  107.         $subform = new Zend_Form_SubForm();
  108.         $subform->setIsArray(true);
  109.         foreach ($elements as $key => $el) {
  110.             $Element1 = $subform->createElement('text', $key);
  111.             $Element1->setLabel($form . $key)
  112.                 ->setValue($el)
  113.                 ->setRequired(true);
  114.             $subform->addElement($Element1);
  115.         }
  116.         $this->addSubForm($subform, $form, $order);
  117.     }
  118. }
  119. ?>
  120. index.phtml:
  121.  
  122. <script type="text/javascript">
  123.  
  124. $(document).ready(function() {
  125.         var id = $("#id").val();
  126.         $("#add").on('click', function() {
  127.                        
  128.                 $.ajax({
  129.                           type: 'POST',
  130.                           data: "id=" + id,
  131.                           url: "<?php echo $this->url(array('action' => 'newfield', 'format' => 'html'));?>",
  132.                           success: function(data) {
  133.                                           $("#addentries-label").before(data);
  134.                                            $("#id").val(++id);
  135.                           },
  136.                           dataType: 'html'
  137.                         });
  138.         });
  139.  
  140.         $("#remove").on('click', function() {
  141.                 // Get the last used id
  142.                   var lastId = $("#id").val() - 1;
  143.                  
  144.                   // Build the attribute search string.  This will match the last added  dt and dd elements.  
  145.                   // Specifically, it matches any element where the id begins with 'newName<int>-'.
  146.                   searchString = '*[id^=child' + lastId + '-]';
  147.                  
  148.                   // Remove the elements that match the search string.
  149.                   $(searchString).remove();
  150.                  
  151.                  
  152.                   // Decrement and store id
  153.                   $("#id").val(--id);
  154.         });
  155.  
  156. });
  157. </script>
  158. <div id="formdiv">
  159. <?php
  160. echo $this->form;
  161. ?>
  162. </div>