ZEND form elements in a table containing also data from the database - forms

Hi there:) i've got a problem with decorators and form which would be in table and in this table want to have also data from database... I dont have any idea how to do this to have a structure like something below, lets say
<table>
<tr>
<td><?php echo array[0]['name']?>
//and here input from zend form
<td>
<select name='foo' id='bar'>
<option value='something'>Foo</option>
<option value='something2'>Foo2</option>
</select>
</td>
</tr>
</table>
Ofcourse tr will be more and generated with foreach or some loop.
I have something like this:
<?php
class EditArticles_Form_EditArticles extends Zend_Form
{
protected $uid;
public function render()
{
/* Form Elements & Other Definitions Here ... */
$this->setName('editarticles');
$data = new EditArticles_Model_DbTable_EditArticlesModel();
$datadata = $data->GetArticlesToEdit($this->getUid()); //here is my data from db
for ($i=0;$i<count($datadata);$i++)
{
$do = new Zend_Form_Element_Select(''.$i);
$do->addMultiOption('0', 'Aktywny');
$do->addMultiOption('1', 'Nieaktywny');
$this->addElements(array($do));
}
$submit = new Zend_Form_Element_Submit('updateart');
$this->addElement($submit);
//and here are decorators for array, and i would like to have in this table also data from array containing data from database
$this->addDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'table', 'id' => 'aaaa', 'style' => 'width:500px;')), 'Form',
));
$this->setElementDecorators(array(
'ViewHelper',
array( array('data' => 'HtmlTag'), array('tag' => 'td', 'style' => 'width:200px;')),
array('Label', array('tag' => 'td')),
array(array('row' => 'HtmlTag'), array('tag' => 'tr'))
),
//wykluczenie submita z overrida stulu
array('submit'), false);
return parent::render();
}
//setting user id for get content from db
public function setUid($uid) {
$this->uid = $uid;
return $this;
}
public function getUid() {
return $this->uid;
}
}
?>
output of code above is something like this: (in red marked where i would like to have that selects from form. In this image the table with data is an other table generated in phtml, but i would like to generate that table by form od just insert only the form elements to that table generated in phtml view).
http://img14.imageshack.us/img14/9973/clipboard01pw.png
Something found here:
Zend_Form: Database records in HTML table with checkboxes
but i dont know how to start with that...

Several comments:
Typically, adding elements to the form is done in init(), rather than render().
If a consumer object (this is this case, the form) needs a dependency (in this case, the article model) to do its work, it is often helpful to explicitly provide the dependency to the consumer, either in the consumer's constructor or via setter method (ex: $form->setArticleModel($model)). This makes it easier to mock the model when testing the form and clearly illustrates the form's dependence on the model.
Re: rendering other content in the form via decorators: Maybe, take a look at the AnyMarkup decorator. It looks like (sorry, can't fully understand the Polish) you want a select box on each row you output. So, you get your rows using the model, loop through the rows, creating your select box on each row. When you assign decorators to the select element - ViewHelper, Errors, probably an HtmlTag decorator to wrap it in a <td> - you also add the AnyMarkup decorator to prepend the a bunch of <td>'s containing your row data, finally wrapping the whole row in <tr>.
Perhaps something like this (not fully tested, just to give the idea):
class EditArticles_Form_EditArticles extends Zend_Form
{
protected $model;
public function __construct($model)
{
$this->model = $model;
parent::__construct();
}
public function init()
{
$rows = $this->model->GetArticlesToEdit($this->getUid());
$numRows = count($rows);
for ($i = 0; $i < $numRows; $i++) {
$do = new Zend_Form_Element_Select('myselect' . $i);
$do->addMultiOption('0', 'Aktywny');
$do->addMultiOption('1', 'Nieaktywny');
$do->setDecorators(array(
'ViewHelper',
array(array('cell' => 'HtmlTag'), array(
'tag' => 'td'
)),
array('AnyMarkup', array(
'markup' => $this->_getMarkupForRow($i, $row),
'placement' => 'PREPEND',
)),
array(array('row' => 'HtmlTag'), array(
'tag' => 'tr'
)),
));
$this->addElement($do);
}
}
protected function _getMarkupForRow($i, $row)
{
return '<td>' . $i . '</td>' .
'<td>' . $row['nazwa'] . '</td>' .
'<td>' . $row['typ'] . '</td>' .
'<td>' . $row['rozmiar'] . '</td>';
}
}
A final note: Remember to register an element decorator prefix path as follows (in the form, probably in init()):
$this->addElementPrefixPath('My_Decorator', 'My/Decorator', self::DECORATOR);
This allows the element to resolve the short name AnyMarkup into a full classname My_Decorator_AnyMarkup.

Related

How to populate zend form data of multi array input fields

Hi I have the following form in zend
<?php
/**
* Admin/modules/admin/forms/TransportRoute.php
* #uses TransportRoute Admission Form
*/
class Admin_Form_TransportRoute extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$stopageDetailsForm = new Zend_Form_SubForm();
$stopageDetailsForm->setElementsBelongTo('transport_route_stopage');
$sd_stopage = $this->CreateElement('text','stopage')
->setAttribs(array('placeholder'=>'Stopage Name', 'mendatory'=>'true'))
->setRequired(true)
->addFilter(new Zend_Filter_StringTrim())
->setDecorators(array( array('ViewHelper') ))
->setIsArray(true)
->addValidators(array(
array('NotEmpty', true, array('messages' => 'Please enter Stopage Name')),
array('stringLength',true,array(1, 6, 'messages'=> 'Stopage Name must be 2 to 40 characters long.'))
));
$sd_stopage_fee = $this->CreateElement('text','stopage_fee')
->setAttribs(array('placeholder'=>'Route Fee', 'mendatory'=>'true'))
->setRequired(true)
->addFilter(new Zend_Filter_StringTrim())
->setDecorators(array( array('ViewHelper') ))
->setIsArray(true)
->addValidators(array(
array('NotEmpty', true, array('messages' => 'Please enter Stopage Fee')),
));
$stopageDetailsForm->addElements ( array (
$sd_stopage,
$sd_stopage_fee,
) );
$this->addSubForm($stopageDetailsForm, 'transport_route_stopage');
//all sub form end here
$id = $this->CreateElement('hidden','id')
->setDecorators(array( array('ViewHelper') ));
$this->addElement($id);
$this->setDecorators(
array(
'PrepareElements',
array('viewScript'))
);
}
}
This is absolutely working fine when I render this form as below:
<div class="row-fluid stopage_block">
<div class="span5">
<?php echo $stopageDetail->stopage;?>
</div>
<div class="span4">
<?php echo $stopageDetail->stopage_fee;?>
</div>
</div>
But at the time of adding a record, I make clones of the div of class "stopage_block" and save them in the database. Now all my concerns are how to populate all the values by using a foreach loop that were inserted through clones of the div.
I have the following arrays
array('stopage' => 'India','stopage_fee' => 5000);
array('stopage' => 'US','stopage_fee' => 50000);
array('stopage' => 'Nepal','stopage_fee' => 2000);
How to populate back these values in my current form by using any loop or something else.
Thanks.
There is a method getSubForms in Zend_Form, you can use it.
Also, I would recommend you to take a look at the following article http://framework.zend.com/manual/1.11/en/zend.form.advanced.html. I guess it's exactly what you are looking for.

Yii CJuiAutoComplete for Multiple values

I am a Yii Beginner and I am currently working on a Tagging system where I have 3 tables:
Issue (id,content,create_d,...etc)
Tag (id,tag)
Issue_tag_map (id,tag_id_fk,issue_id_fk)
In my /Views/Issue/_form I have added a MultiComplete Extension to retrieve multiple tag ids and labels,
I have used an afterSave function in order to directly store the Issue_id and the autocompleted Tag_ids in the Issue_tag_map table, where it is a HAS_MANY relation.
Unfortunately Nothing is being returned.
I wondered if there might be a way to store the autocompleted Tag_ids in a temporary attribute and then pass it to the model's afterSave() function.
I have been searching for a while, and this has been driving me crazy because I feel I have missed a very simple step!
Any Help or advices of any kind are deeply appreciated!
MultiComplete in Views/Issue/_form:
<?php
echo $form->labelEx($model, 'Tag');
$this->widget('application.extension.MultiComplete', array(
'model' => $model,
'attribute' => '', //Was thinking of creating a temporary here
'name' => 'tag_autocomplete',
'splitter' => ',',
'sourceUrl' => $this->createUrl('Issue/tagAutoComplete'),
// Controller/Action path for action we created in step 4.
// additional javascript options for the autocomplete plugin
'options' => array(
'minLength' => '2',
),
'htmlOptions' => array(
'style' => 'height:20px;',
),
));
echo $form->error($model, 'issue_comment_id_fk');
?>
AfterSave in /model/Issue:
protected function afterSave() {
parent::afterSave();
$issue_id = Yii::app()->db->getLastInsertID();
$tag; //here I would explode the attribute retrieved by the view form
// an SQL with two placeholders ":issue_id" and ":tag_id"
if (is_array($tag))
foreach ($tag as $tag_id) {
$sql = "INSERT INTO issue_tag_map (issue_id_fk, tag_id_fk)VALUES(:issue_id,:tag_id)";
$command = Yii::app()->db->createCommand($sql);
// replace the placeholder ":issue_id" with the actual issue value
$command->bindValue(":issue_id", $issue_id, PDO::PARAM_STR);
// replace the placeholder ":tag_id" with the actual tag_id value
$command->bindValue(":tag_id", $tag_id, PDO::PARAM_STR);
$command->execute();
}
}
And this is the Auto Complete sourceUrl in the Issue model for populating the tags:
public static function tagAutoComplete($name = '') {
$sql = 'SELECT id ,tag AS label FROM tag WHERE tag LIKE :tag';
$name = $name . '%';
return Yii::app()->db->createCommand($sql)->queryAll(true, array(':tag' => $name));
actionTagAutoComplete in /controllers/IssueController:
// This function will echo a JSON object
// of this format:
// [{id:id, name: 'name'}]
function actionTagAutocomplete() {
$term = trim($_GET['term']);
if ($term != '') {
$tags = issue::tagAutoComplete($term);
echo CJSON::encode($tags);
Yii::app()->end();
}
}
EDIT
Widget in form:
<div class="row" id="checks" >
<?php
echo $form->labelEx($model, 'company',array('title'=>'File Company Distrubution; Companies can be edited by Admins'));
?>
<?php
$this->widget('application.extension.MultiComplete', array(
'model' => $model,
'attribute' => 'company',
'splitter' => ',',
'name' => 'company_autocomplete',
'sourceUrl' => $this->createUrl('becomEn/CompanyAutocomplete'),
'options' => array(
'minLength' => '1',
),
'htmlOptions' => array(
'style' => 'height:20px;',
'size' => '45',
),
));
echo $form->error($model, 'company');
?>
</div>
Update function:
$model = $this->loadModel($id);
.....
if (isset($_POST['News'])) {
$model->attributes = $_POST['News'];
$model->companies = $this->getRecordsFromAutocompleteString($_POST['News']
['company']);
......
......
getRecordsFromAutocompleteString():
public static cordsFromAutocompleteString($string) {
$string = trim($string);
$stringArray = explode(", ", $string);
$stringArray[count($stringArray) - 1] = str_replace(",", "", $stringArray[count($stringArray) - 1]);
$criteria = new CDbCriteria();
$criteria->select = 'id';
$criteria->condition = 'company =:company';
$companies = array();
foreach ($stringArray as $company) {
$criteria->params = array(':company' => $company);
$companies[] = Company::model()->find($criteria);
}
return $companies;
}
UPDATE
since the "value" porperty is not implemented properly in this extension I referred to extending this function to the model:
public function afterFind() {
//tag is the attribute used in form
$this->tag = $this->getAllTagNames();
parent::afterFind();
}
You should have a relation between Issue and Tags defined in both Issue and Tag models ( should be a many_many relation).
So in IssueController when you send the data to create or update the model Issue, you'll get the related tags (in my case I get a string like 'bug, problem, ...').
Then you need to parse this string in your controller, get the corresponding models and assigned them to the related tags.
Here's a generic example:
//In the controller's method where you add/update the record
$issue->tags = getRecordsFromAutocompleteString($_POST['autocompleteAttribute'], 'Tag', 'tag');
Here the method I'm calling:
//parse your string ang fetch the related models
public static function getRecordsFromAutocompleteString($string, $model, $field)
{
$string = trim($string);
$stringArray = explode(", ", $string);
$stringArray[count($stringArray) - 1] = str_replace(",", "", $stringArray[count($stringArray) - 1]);
return CActiveRecord::model($model)->findAllByAttributes(array($field => $stringArray));
}
So now your $issue->tags is an array containing all the related Tags object.
In your afterSave method you'll be able to do:
protected function afterSave() {
parent::afterSave();
//$issue_id = Yii::app()->db->getLastInsertID(); Don't need it, yii is already doing it
foreach ($this->tags as $tag) {
$sql = "INSERT INTO issue_tag_map (issue_id_fk, tag_id_fk)VALUES(:issue_id,:tag_id)";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":issue_id", $this->id, PDO::PARAM_INT);
$command->bindValue(":tag_id", $tag->id, PDO::PARAM_INT);
$command->execute();
}
}
Now the above code is a basic solution. I encourage you to use activerecord-relation-behavior's extension to save the related model.
Using this extension you won't have to define anything in the afterSave method, you'll simply have to do:
$issue->tags = getRecordsFromAutocompleteString($_POST['autocompleteAttribute'], 'Tag', 'tag');
$issue->save(); // all the related models are saved by the extension, no afterSave defined!
Then you can optimize the script by fetching the id along with the tag in your autocomplete and store the selected id's in a Json array. This way you won't have to perform the sql query getRecordsFromAutocompleteString to obtain the ids. With the extension mentioned above you'll be able to do:
$issue->tags = CJSON::Decode($_POST['idTags']);//will obtain array(1, 13, ...)
$issue->save(); // all the related models are saved by the extension, the extension is handling both models and array for the relation!
Edit:
If you want to fill the autocomplete field you could define the following function:
public static function appendModelstoString($models, $fieldName)
{
$list = array();
foreach($models as $model)
{
$list[] = $model->$fieldName;
}
return implode(', ', $list);
}
You give the name of the field (in your case tag) and the list of related models and it will generate the appropriate string. Then you pass the string to the view and put it as the default value of your autocomplete field.
Answer to your edit:
In your controller you say that the companies of this model are the one that you added from the Autocomplete form:
$model->companies = $this->getRecordsFromAutocompleteString($_POST['News']
['company']);
So if the related company is not in the form it won't be saved as a related model.
You have 2 solutions:
Each time you put the already existing related model in you autocomplete field in the form before displaying it so they will be saved again as a related model and it won't disapear from the related models
$this->widget('application.extensions.multicomplete.MultiComplete', array(
'name' => 'people',
'value' => (isset($people))?$people:'',
'sourceUrl' => array('searchAutocompletePeople'),
));
In your controller before calling the getRecordsFromAutocompleteString you add the already existing models of the model.
$model->companies = array_merge(
$model->companies,
$this->getRecordsFromAutocompleteString($_POST['News']['company'])
);

zend framework - group elements of a form within a subforms [duplicate]

I would like to be able to add a hidden form field using array notation to my form. I can do this with HTML like this:
<input type="hidden" name="contacts[]" value="123" />
<input type="hidden" name="contacts[]" value="456" />
When the form gets submitted, the $_POST array will contain the hidden element values grouped as an array:
array(
'contacts' => array(
0 => '123'
1 => '456'
)
)
I can add a hidden element to my form, and specify array notation like this:
$form->addElement('hidden', 'contacts', array('isArray' => true));
Now if I populate that element with an array, I expect that it should store the values as an array, and render the elements as the HTML shown above:
$form->populate($_POST);
However, this does not work. There may be a bug in the version of Zend Framework that I am using. Am I doing this right? What should I do differently? How can I achieve the outcome above? I am willing to create a custom form element if I have to. Just let me know what I need to do.
You have to use subforms to get the result you seek. The documentation was quite a ride but you can find it here
Using what I found there I constructed the following formL
<?php
class Form_Test extends Zend_Form {
public function init() {
$this->setMethod('post');
$this->setIsArray(true);
$this->setSubFormDecorators(array(
'FormElements',
'Fieldset'
));
$subForm = new Zend_Form(array('disableLoadDefaultDecorators' => true));
$subForm->setDecorators(array(
'FormElements',
));
$subForm->addElement('hidden', 'contacts', array(
'isArray' => true,
'value' => '237',
'decorators' => Array(
'ViewHelper',
),
));
$subForm2 = new Zend_Form(array('disableLoadDefaultDecorators' => true));
$subForm2->setDecorators(array(
'FormElements',
));
$subForm2->addElement('hidden', 'contacts', array(
'isArray' => true,
'value' => '456', 'decorators' => Array(
'ViewHelper',
),
));
$this->addSubForm($subForm, 'subform');
$this->addSubForm($subForm2, 'subform2');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setValue('Submit');
$this->addElement('submit', 'submit');
}
}
Wich outputs this html:
<form enctype="application/x-www-form-urlencoded" method="post" action=""><dl class="zend_form">
<input type="hidden" name="contacts[]" value="237" id="contacts">
<input type="hidden" name="contacts[]" value="456" id="contacts">
<dt id="submit-label"> </dt><dd id="submit-element">
<input type="submit" name="submit" id="submit" value="submit"></dd></dl></form>
And when submited the post looks like:
array(2) {
["contacts"] => array(2) {
[0] => string(3) "237"
[1] => string(3) "456"
}
["submit"] => string(6) "submit"
}
So thats how you can create the kind of forms you seek. Hope this helps! if you have a question post a comment!
Its quite hackish if you ask me. You basically create subforms but disable there form decorators so just the element gets output. Since the identical contacts[] elements are in different form object zend does'nt overwrite them and it works. But yeah..
Edit: changed it a bit to remove labels and garbage arount the hidden inputs.
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'));
This indeed seems to be a bug in Zend Framework - the value attribute for an element is properly set to array, but it's ignored when the element renders - it just uses$this->view->escape($value) to output element's html.
I've solved this by implementing a custom helper for such elements:
class My_View_Helper_HiddenArray extends Zend_View_Helper_FormHidden
{
public function hiddenArray($name, $value = null, array $attribs = null)
{
if (is_array($value)) {
$elementXHTML = '';
// do not give element an id due to the possibility of multiple values
if (isset($attribs) && is_array($attribs) && array_key_exists('id', $attribs)) {
unset($attribs['id']);
}
foreach ($value as $item) {
$elementXHTML .= $this->_hidden($name, $item, $attribs);
}
return $elementXHTML;
} else {
return $this->formHidden($name, $value, $attribs);
}
}
}
Which, when used the next way:
$contacts = $form->createElement('hidden', 'contacts')
->setIsArray(true)
->setDecorators(array(
array('ViewHelper', array('helper' => 'HiddenArray')),
));
$form->addElement($contacts);
generates the needed output.
The reason to extend Zend_View_Helper_FormHidden here is just to be able to call the default behaviour if no array value is set ( return parent::formHidden($name, $value, $attribs) ).
Hope this helps someone :)
For the newer versions of ZF you should use https://framework.zend.com/manual/2.1/en/modules/zend.form.elements.html#multicheckbox

How to render some html in Zend form?

In my form i need this:
<li class ="af_title"><div>Contact form</div></li>
I understand that if I need for example a text field - then I'd just create Zend_Form_Element_Text and wrap HtmlTag decorator around it - right?
questions:
1) how would I generate div form element so I can wrap decorator around it?
2) mmm. - how would I set content of said element to be "Contact form"?
Thanks:)
To wrap your Contact form around div which is inside <li class ="af_title"> you can do as follows:
$yourForm = new YourForm();
$yourForm->addDecorator(array('div' => 'HtmlTag'), array('tag' => 'div'));
$yourForm->addDecorator(array('li' => 'HtmlTag'), array('tag' => 'li', 'class' => 'af_title'));
EDIT:
I see that you speak of div form element. Such element does not exist, but you could easily create it. For this you need two things: new form element (i.e. div element) and a form view helper that would take care of generation of the html. I allowed myself to prepare simple examples of these two elements to show what I mean:
Div.php in APPLICATION_PATH . /forms/Element:
class My_Form_Element_Div extends Zend_Form_Element {
/**
* Default form view helper to use for rendering
* #var string
*/
public $helper = 'formDiv';
public function __construct($spec, $options = null) {
parent::__construct($spec, $options);
$this->removeDecorator('label');
$this->removeDecorator('htmlTag');
}
}
FormDiv.php in APPLICATION_PATH . /views/helpers:
class My_View_Helper_FormDiv extends Zend_View_Helper_FormElement {
public function formDiv($name, $value = null, $attribs = null) {
$class = '';
if (isset($attribs['class'])) {
$class = 'class = "'. $attribs['class'] .'"';
}
return "<li $class><div>$value</div></li>";
}
}
Having this, you can just add the div form element to any form element in their init() method as follows:
$div = new My_Form_Element_Div('mydiv');
$div->setValue('Contact form')->setAttrib('class', 'af_title');
$this->addElement($div);

Zend Framework: Working with Form elements in array notation

I would like to be able to add a hidden form field using array notation to my form. I can do this with HTML like this:
<input type="hidden" name="contacts[]" value="123" />
<input type="hidden" name="contacts[]" value="456" />
When the form gets submitted, the $_POST array will contain the hidden element values grouped as an array:
array(
'contacts' => array(
0 => '123'
1 => '456'
)
)
I can add a hidden element to my form, and specify array notation like this:
$form->addElement('hidden', 'contacts', array('isArray' => true));
Now if I populate that element with an array, I expect that it should store the values as an array, and render the elements as the HTML shown above:
$form->populate($_POST);
However, this does not work. There may be a bug in the version of Zend Framework that I am using. Am I doing this right? What should I do differently? How can I achieve the outcome above? I am willing to create a custom form element if I have to. Just let me know what I need to do.
You have to use subforms to get the result you seek. The documentation was quite a ride but you can find it here
Using what I found there I constructed the following formL
<?php
class Form_Test extends Zend_Form {
public function init() {
$this->setMethod('post');
$this->setIsArray(true);
$this->setSubFormDecorators(array(
'FormElements',
'Fieldset'
));
$subForm = new Zend_Form(array('disableLoadDefaultDecorators' => true));
$subForm->setDecorators(array(
'FormElements',
));
$subForm->addElement('hidden', 'contacts', array(
'isArray' => true,
'value' => '237',
'decorators' => Array(
'ViewHelper',
),
));
$subForm2 = new Zend_Form(array('disableLoadDefaultDecorators' => true));
$subForm2->setDecorators(array(
'FormElements',
));
$subForm2->addElement('hidden', 'contacts', array(
'isArray' => true,
'value' => '456', 'decorators' => Array(
'ViewHelper',
),
));
$this->addSubForm($subForm, 'subform');
$this->addSubForm($subForm2, 'subform2');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setValue('Submit');
$this->addElement('submit', 'submit');
}
}
Wich outputs this html:
<form enctype="application/x-www-form-urlencoded" method="post" action=""><dl class="zend_form">
<input type="hidden" name="contacts[]" value="237" id="contacts">
<input type="hidden" name="contacts[]" value="456" id="contacts">
<dt id="submit-label"> </dt><dd id="submit-element">
<input type="submit" name="submit" id="submit" value="submit"></dd></dl></form>
And when submited the post looks like:
array(2) {
["contacts"] => array(2) {
[0] => string(3) "237"
[1] => string(3) "456"
}
["submit"] => string(6) "submit"
}
So thats how you can create the kind of forms you seek. Hope this helps! if you have a question post a comment!
Its quite hackish if you ask me. You basically create subforms but disable there form decorators so just the element gets output. Since the identical contacts[] elements are in different form object zend does'nt overwrite them and it works. But yeah..
Edit: changed it a bit to remove labels and garbage arount the hidden inputs.
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'));
This indeed seems to be a bug in Zend Framework - the value attribute for an element is properly set to array, but it's ignored when the element renders - it just uses$this->view->escape($value) to output element's html.
I've solved this by implementing a custom helper for such elements:
class My_View_Helper_HiddenArray extends Zend_View_Helper_FormHidden
{
public function hiddenArray($name, $value = null, array $attribs = null)
{
if (is_array($value)) {
$elementXHTML = '';
// do not give element an id due to the possibility of multiple values
if (isset($attribs) && is_array($attribs) && array_key_exists('id', $attribs)) {
unset($attribs['id']);
}
foreach ($value as $item) {
$elementXHTML .= $this->_hidden($name, $item, $attribs);
}
return $elementXHTML;
} else {
return $this->formHidden($name, $value, $attribs);
}
}
}
Which, when used the next way:
$contacts = $form->createElement('hidden', 'contacts')
->setIsArray(true)
->setDecorators(array(
array('ViewHelper', array('helper' => 'HiddenArray')),
));
$form->addElement($contacts);
generates the needed output.
The reason to extend Zend_View_Helper_FormHidden here is just to be able to call the default behaviour if no array value is set ( return parent::formHidden($name, $value, $attribs) ).
Hope this helps someone :)
For the newer versions of ZF you should use https://framework.zend.com/manual/2.1/en/modules/zend.form.elements.html#multicheckbox