Добавить подчиненную форму в форму с помощью ajax при отправке

Я прочитал эту статью: http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/

Это было очень интересно и отлично работает.

Мне нужно сделать то же самое, но с подформой. Я имею в виду, что когда пользователь нажимает кнопку, я вызываю через ajax действие, которое добавляет, присоединяет и отображает подчиненную форму к моей существующей форме.

Например:
У меня есть форма, в которой пользователь должен заполнить имя и фамилию своих детей, поэтому есть кнопка «Добавить ребенка». Когда пользователь нажимает эту кнопку, к моей существующей форме должна быть добавлена ​​и отображена подформа. При отправке он будет подтвержден точно так же, как в примере из этой статьи. Единственная разница в том, что там он просто добавляет одно поле. Мне нужно добавить подформу, но точно так же.

В своем действии (вызванном 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();
}

Это почти работает.
Просмотр этого действия возвращает html-код SubForm, поэтому при успешном выполнении моего вызова ajax я просто отображаю его.

Проблема в том, что при отправке он проверяет форму, но теряет только что добавленную новую подчиненную форму. Этого не происходит в статье с одним элементом. Я думаю, мне просто нужно добавить подформу к существующей форме, но как?


person Samuele    schedule 09.11.2011    source источник
comment
Привет, Самуэле, вы должны проверить библиотеку проверки js, чтобы убедиться, что она делает.Как я знаю, большинство библиотек добавляют проверку к форме и идентификатору, если вы добавляете другую форму (Форма внутри формы) Она не проверяет полную форму   -  person Santosh kumar    schedule 31.10.2012


Ответы (1)


Добавьте префикс подчиненной формы к элементам подчиненной формы. Я использовал префикс «ребенок» для обозначения подчиненных форм. Каждая подчиненная форма будет создана как child1, child2 и так далее.

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

}

Затем в функции preValidation отфильтруйте подчиненные формы, используя префикс подчиненной формы вместо имени поля:

   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);
     }

}

Функция Добавить новую форму создает каждую из подформ и присоединяется к основной форме:

     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] Использование setIsArray для подчиненной формы создает каждый элемент подчиненной формы как элемент массива. Это упрощает функцию preValidate. Отредактировал код, чтобы использовать эту функцию.

См. полный код в pastebin

Вот еще одно решение с использованием ownTo, обеспечивающего нотацию массива для элементов подформы: http://www.stephenrhoades.com/?p=364

person janenz00    schedule 03.11.2012