2

I have a form in which people shall be able to add the same portion of elements with a plus-button, so that something like this is produced:

<div id="person-1" class="person">
    <input type="text" name="name-1" id="name-1" />
    <input type="text" name="age-1" id="age-1" />
</div>
<!-- as of here, it's JS created -->
<div id="person-2" class="person">
    <input type="text" name="name-2" id="name-2" />
    <input type="text" name="age-2" id="age-2" />
</div>
<div id="person-3" class="person">
    <input type="text" name="name-3" id="name-3" />
    <input type="text" name="age-3" id="age-3" />
</div>

I already managed to write jquery-code that allows me to add the same elements once again with a new id (name-1, age-1, name-2, age-2, name-3, age-3, …).

Of course, Zend_Form does not know about name-2 and name-3, so it just drops them when the form contains an error and is displayed again. Neither can I access the value of name-2 with $form->getValue('name-2'). I have to go over raw $this->getRequest()->getPost().

Is there a better method I can use to combine Zend_Form and javascript-based added form elements (of same type like an hardcoded element).

Caveat: In the real problem, it’s select and not input. Found out this could make a difference (with ->setIsArray(true)), but using select would blow up the example code.

4
  • Have you considered using the notation name="names[]"? Wouldn't that help you? Commented Jan 6, 2012 at 13:56
  • Yeah, Zend does not seem to allow [] in the attribute name. I can call the element second[] within my application, but it will still be given name="second" in HTML. :/ And when I use setIsArray(true), it will make my select-field multiselect (I do not have text, but select in real problem). Commented Jan 6, 2012 at 15:00
  • 1
    Seems like I can introduce a preValidation() method to my form which checks for new elements and adds them to the Zend_Form hierarchy. Commented Jan 6, 2012 at 15:13
  • 1
    See: stackoverflow.com/questions/6691378/… Commented Apr 21, 2012 at 9:45

1 Answer 1

2

What you could do is create a subform container inside your main form and add an X amount of subforms to that container. For example:

class My_Form extends Zend_Form
{
    private $_numPersons = 1;

    public function setNumPersons($numPersons)
    {
        $this->_numPersons = (int) $numPersons;
    }


    public function init()
    {
        $container = new Zend_Form_SubForm();
        $this->addSubForm($container, 'persons');

        for($index = 0; $index < $this->_numPersons; $index++) {
            $personForm = new My_PersonForm();
            $container->addSubForm($personForm, $index+1);
        }
    }
}

When rendered, the input fields will have names like persons[1][name]. Note the $index+1, Zend_Form does not allow a form to be named '0'.

Ofcourse, you should only use this method if the amount of person subforms is limited.

Another strategy would be to override the isValid method and use a single My_PersonForm form to validate all the person data.

Sidenote; the above code will only work when you define the numPersons as part of the options set, when creating the form instance. E.g.;

$form = new My_Form(array('numPersons' => 10));

Sign up to request clarification or add additional context in comments.

3 Comments

Does not really seem to work :/ Always one level is missing. Now it’s: array(2) { ["persons"]=> array(2) { ["name"]=> string(2) "ab" ["age"]=> string(0) "" } ["submit"]=> string(23) "Save" } When I reduce complexity and add only one subform, this subform is directly copied into the root of the $_POST data (without the subform-name being an array index), like this: array(3) { ["name"]=> string(2) "ab" ["age"]=> string(0) "" ["submit"]=> string(23) "Save" }
Quite hard to help you without seeing the exact code you've written, but at least make sure that the Person form is an instance of Zend_Form_SubForm. If you're using the ViewScript renderer to render your form, you might want to prepend the PrepareElements decorator to the form decorator stack. Also note that you add the PersonForm to the $container subform and not the main form.
Yeah, it was not an instance of Zend_Form_SubForm. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.