1

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?

4

1 に答える 1