Add sub form to form from ajax to submit

I read this article: http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/

It was very interesting and it works great.

I need to do the same, but with SubForm. I mean, when the user clicks the button, I invoke through ajax an action that adds, attaches and displays the subform for my existing form.

For instance:
I have a form where the user must fill in the name and surname of their children, so there is a button "Add child". When the user clicks this button, SubForm should be added to my existing form and displayed. On a view, it will be checked in the same way as the example in this article. The only difference is that there it just adds one field. I need to add SubForm, but exactly the same.

I tried the following in my action (called by 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(); } 

It almost works.
Representation of this action returns the SubForm html code, so when I successfully complete my ajax call, I just show it.

The problem is that when it submits, it validates the form, but lost the newly added new subform. This does not occur in an article with only one element. I think I just need to add SubForm to an existing form, but how?

+6
source share
1 answer

Add the subform prefix to the subform elements. I used the prefix "child" to represent subforms. Each subformation will be created as child1, child2, etc.

 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 } 

Then, in the preValidation function, filter the subforms using the subform prefix instead of the field name:

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

}

Add function "New form" creates each of the subforms and attaches to the main form:

  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] Using setIsArray for a subform creates each subform element as an array element. This simplifies the preValidate function. Edited the code to use this feature.

See the full code in pastebin

Here is another solution using ownTo that provides array notation for subform elements: http://www.stephenrhoades.com/?p=364

+2
source

Source: https://habr.com/ru/post/901139/


All Articles