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