array input like name="person[]" in zend form

jblue picture jblue · Feb 7, 2011 · Viewed 7.6k times · Source

In normal html, we could have an array field like person[]

<input name="person[]" type="text" />
<input name="person[]" type="text" />
<input name="person[]" type="text" />

As far as I know, Zend_Form doesn't have that. I read another answer that suggested it could be done using a decorator that would add the [] at the right place. This is the code for that specific question

$html = ''; // some code html
$i = 0;
foreach ($element->getMultiOptions() as $value => $label){
    $html .= '<input type="checkbox" '
          .         'name="'.$element->getName().'[]" '
          .         'id="'$element->getName()'-'.$i.'" '
          .         'value="'.$value.'" />';
    $i++;
}
return $html;

This looks like a good start, but I wonder if using a decorator is enough. The values that get returned back have to be read correctly and delivered to the server, then validated on the server side. So is a decorator the wrong idea? Would a custom element make more sense here? I haven't seen a good example that shows how this can be done.

Answer

Marcin picture Marcin · Feb 7, 2011

I think that ZF does not allow for creation of individual input text fields named person[], although you could do it for the whole form or a subform. However, it allows for something similar. Specifically, you could create fields named person[0], person[1], etc.

To do this, you could do the following:

$in1 = $this->createElement('text', '0');
$in2 = $this->createElement('text', '1');
$in1->setBelongsTo('person');
$in2->setBelongsTo('person');

This way you could normally attach your validators, filters, etc. to $in1 or $in2 and they would work as expected. In your action, after form validation, you could get an array of the person's input text fields as:

$values = $yourForm->getValues();
var_dump($values['person']);

Interestingly, the following will NOT work:

$in1 = $this->createElement('text', 'person[0]');
$in2 = $this->createElement('text', 'person[1]');

Hope this will help you.