I have a requirement of rendering and processing the same form again if user check a select box. I looked into form collections but it didn't exactly access my problem because I don't need to render a set of fields instead my requirement is to render the complete form again. So what I added another function getClone($prefix) to get the clone of form which returns me the clone of form object after adding a prefix in the name of form. Like this
<?php
namespace Company\Form;
use Zend\Form\Form;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class CompanyAddress extends Form implements InputFilterAwareInterface {
protected $inputFilter;
public function __construct($countries, $name = 'null') {
parent::__construct('company_address');
$this->setAttribute('method', 'post');
$this->setAttribute('id', 'company_address');
$this->add(array(
'name' => 'street_1',
'attributes' => array(
'id' => 'street_1',
'type' => 'text',
),
'options' => array(
'label' => 'Street *',
)
));
$this->add(array(
'name' => 'street_2',
'attributes' => array(
'id' => 'street_2',
'type' => 'text',
),
'options' => array(
'label' => 'Street 2',
)
));
$this->add(array(
'name' => 'country_id',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'country_id',
),
'options' => array(
'label' => 'Country',
'value_options' => $countries
)
));
$this->add(array(
'name' => 'city_id',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'city_id',
),
'options' => array(
'label' => 'City ',
'value_options' => array()
)
));
$this->add(array(
'name' => 'zip',
'attributes' => array(
'id' => 'zip',
'type' => 'text',
),
'options' => array(
'label' => 'ZIP',
'value_options' => array()
)
));
$this->add(array(
'name' => 'address_type',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'zip',
),
'options' => array(
'label' => 'Type',
'value_options' => array(
'' => 'Select Type',
'default' => 'Default',
'invoice' => 'Invoice',
'both' => 'Both',
)
)
));
}
public function getClone($prefix){
$form = clone $this;
foreach($form->getElements() as $element){
$name = $element->getName();
$element->setName("$prefix[$name]");
}
return $form;
}
public function getInputFilter() {
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'street_1',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'Street cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'street_2',
'required' => false,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'city_id',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'City cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'country_id',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'Country cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'zip',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'ZIP cannot be empty'),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'address_type',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array('message' => 'Address Type cannot be empty'),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
and than in my action I did this
public function testAction() {
$countries = $this->getServiceLocator()->get('Country')->getSelect();
$companyAddressForm = new CompanyAddressForm($countries);
$clone = $companyAddressForm->getClone('address2');
if($this->request->isPost()){
$data = $this->request->getPost();
$companyAddressForm->setData($data);
$clone->setData($data['address2']);
$isFormOneValid = $companyAddressForm->isValid();
//$isFormTwoValid = $clone->isValid();
}
$view = new ViewModel();
$view->companyAddressForm = $companyAddressForm;
$view->clone = $clone;
return $view;
}
This is working as I expected it to work, forms are rendering and validating correctly, I want to know whether it is a correct way or a hack?