Zend_Form - Array Based Elements

Zend_Form - Array based elements?

You can either use subforms:

$form = new Zend_Form();

$subForm = new Zend_Form_SubForm();
$subForm->addElement('Text', '1')
->addElement('Text', '2');

$form->addSubForm($subForm, 'element');

Or you should also be able to use setBelongsTo() on the form elements (untested):

$form = new Zend_Form();
$form->addElement('Text', '1', array('belongsTo' => 'element'))
->addElement('Text', '2', array('belongsTo' => 'element'));

Zend Framework: Working with Form elements in array notation

To use array notation, you need to specify that the element "belongs to" a parent array:

$form->addElement('hidden', 'contact123', array('belongsTo' => 'contacts', 'value' => '123'));
$form->addElement('hidden', 'contact456', array('belongsTo' => 'contacts', 'value' => '456'));

Render an array of input using Zend_Form

Here is a code of the form

class MyForm extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$this->setEnctype('application/x-www-form-urlencoded');

$my_name = $this->addElement('text', 'my_name');
$wife_name = $this->addElement('text', 'wife_name');
$child_name1 = $this->addElement('text', "child_name", array(
'attribs' => array(
'id' => 'child-name-1'
),
'isArray' => true,
));

$subForm = new Zend_Form(array('disableLoadDefaultDecorators' => true));

$subForm->setDecorators(array(
'FormElements',
));

$subForm->addElement('text', 'child_name', array(
'isArray' => true,
'decorators' => Array(
'ViewHelper',
),
'attribs' => array(
'id' => 'child-name-2'
),
));

$subForm2 = new Zend_Form(array('disableLoadDefaultDecorators' => true));

$subForm2->setDecorators(array(
'FormElements',
));

$subForm2->addElement('text', 'child_name', array(
'isArray' => true,
'decorators' => Array(
'ViewHelper',
),
'attribs' => array(
'id' => 'child-name-3'
),
));

$this->addSubForm($subForm, 'subform');
$this->addSubForm($subForm2, 'subform2');

$this->addDecorator('FormElements')
->addDecorator('Form');

}

/**
* Add Element to form without default decorators
*
* @see Zend_Form::addElement()
*/
public function addElement($element, $name = null, $options = null)
{
parent::addElement($element, $name, $options);

if (isset($this->_elements[$name])) {
$this->removeDecorators($this->_elements[$name]);
}
}

/**
* Create form element without default decorators
*
* @see Zend_Form::createElement()
*/
public function createElement($type, $name, $options = null)
{
$element = parent::createElement($type, $name, $options);
$this->removeDecorators($element);
return $element;
}
/**
* Remove default decorators for $element
*
* @param Zend_Form_Element $element
*/
protected function removeDecorators($element)
{
$element->removeDecorator('Label');
$element->removeDecorator('HtmlTag');
$element->removeDecorator('DtDdWrapper');
$element->removeDecorator('Description');
}
}

Then in your template just echo the form.

Zend_Form - multiArray based elements

You have to use sub forms:

$form = new Zend_Form;

// 'element'
$elements = new Zend_Form_SubForm();
$form->addSubForm($elements, 'element');

And each element is a subform of the 'elements' sub form:

$element = new Zend_Form_SubForm;
$element->addElement('Text', 'name');
$element->addElement('Text', 'text');
$elements->addSubForm($element, '0');

$element = new Zend_Form_SubForm;
$element->addElement('Text', 'name');
$element->addElement('Text', 'text');
$elements->addSubForm($element, '1');

In the controller you can iterate over elements like this:

foreach($form->elements as $element) {
var_dump($element->getValue('name'));
}

Multidimensional Array based Elements

Use a SubForm:

$form = new Zend_Form;
$subForm = new Zend_Form_SubForm('SubForm', 'element');
$subForm->addElements(array(
$subForm->createElement('Text', '0'),
$subForm->createElement('Text', '1'),
));
$form->addSubForm($subForm, 'element');

I'm sure this can be written with array notation somehow too.

zend form with arrays having same index

Zend_Form has a feature for this named setElementsBelongTo. See
http://framework.zend.com/manual/1.12/en/zend.form.advanced.html

The way of use this is setting to the Zend_Form object the prefix with setElementsBelongTo, if you want iterate over each field then you can use subforms to encapsulate each group of fields

You can call to setElementsBelongTo in your controller or in the init() method of your form class:

$mainForm = new Zend_Form();

$phoneForm = new Zend_Form_Subform();
$element = $phoneForm->createElement('text', '1'); // 1 is the element inside of the brackets
$phoneForm->addElement($element);
$phoneForm->setElementsBelongTo('phone'); // phone is the part leading the brackets
$mainForm->addSubform($phoneForm, 'phone_form');

$phoneForm = new Zend_Form_Subform();
$element = $phoneForm->createElement('text', '2'); // 1 is the element inside of the brackets
$phoneForm->addElement($element);
$phoneForm->setElementsBelongTo('phone'); // phone is the part leading the brackets
$mainForm->addSubform($phoneForm, 'phone_form2');

$addressForm = new Zend_Form_Subform();
$element = $addressForm->createElement('text', '1');
$addressForm->addElement($element);
$addressForm->setElementsBelongTo('address');
$mainForm->addSubform($addressForm, 'address_form');

echo $mainForm;

var_dump($mainForm->getValues());

gives

 array(2) { 
["phone"]=> array(2) { [1]=> NULL [2]=> NULL }
["address"]=> array(1) { [1]=> NULL } }

To get your expected result you will need remove some decorators (Form, dt, etc):

<input type="text" name="phone[1]" value="" />
<input type="text" name="address[2]" value="" />

Then when you retrieve the values with $form->getValues() the result is:

Array(
'phone' = Array(
'1' => <value>,
),
'address' = Array(
'1' => <value>,
)
);

Zend_Form array of inputs

Please try with this

    $image = new Zend_Form_Element_File("image");
$image->setAttrib('multiple', true)
->setIsArray(true)
->addValidator('Extension', false, 'gif,jpg,jpeg,png,swf');

How to create elements in Zend Form with array names

Your code looks like a dynamic form rendered into table format. One possibility besides Zend Fieldsets is to generate your basic form structure dynamically wihtin OOP-Constructor, like @Sam said.

In your case, you should have a concept of which the form is structured. E.g. you have an array with data from a database, which gives you for example the number and names of your "columns" and so the structure how to build your dynamic form.

Following example uses Zend Form constructor to generate a dynamic form. Number of columns are dynamic and specified by given array $tableColumns

<?php

class DynamicForm extends Form {

/**
* This constructor builds a Zend Form dynamically
*
* @param array $tableColumns Dynamic data e.g. 'Column Name 1'
*/
public function __construct($tableColumns) {

// Add table name input
$this->add(array(
'type' => 'text',
'name' => 'name'
));

// Add table title input
$this->add(array(
'type' => 'text',
'name' => 'title'
));

// iterate each dynamic data
foreach($tableColumns as $column) {

$this->add(array(
'type' => 'text',
'name' => $column['name']
));
}
}
}

This is how you generate the Zend form structure. Rendering works similar, but within yout view code.

<?php 

echo "<table>";
echo "<tr>";

echo "<td>". $this->formElement($form->get('name')) . "</td>";
echo "<td>". $this->formElement($form->get('title')) . "</td>";

foreach($tableColumns as $column) {

echo "<td>". $this->formElement($column) ."</td>";

}

echo "</tr>";
echo "</table>";

?>

In my opinion it is much more comfortable to render a form dynamically into a table format, than it's possible a Fieldset.

But nevertheless Zend Form Collection (e.g. Fieldsets) is a good choice, if you have to add or remove Form-elements dynamically with Javascript and handle your form data also highly dynamically.

More information about Zend From Collections are described at the ZF2 Reference Manual

Zend_Form array notation and empty elements names

For multiple values:

$foo = new Zend_Form_Element_Text('foo');
// Other parameters
$foo->setIsArray(TRUE);
$this->addElement($foo);

Generates: name="foo[]"

--

If you're looking for given keys such as name="foo[bar]", use:

$bar= new Zend_Form_Element_Text('bar');
// Other parameters
$bar->setBelongsTo('foo');
$this->addElement($bar);

--

Tested on ZF 1.11.5



Related Topics



Leave a reply



Submit