在Zend Framework 2中两次渲染和处理相同的表单?

时间:2013-10-14 08:16:15

标签: php forms zend-framework zend-framework2

如果用户选中了一个选择框,我需要再次渲染和处理相同的表单。我查看了表单集合,但它并没有完全访问我的问题,因为我不需要渲染一组字段,而是我的要求是再次渲染完整的表单。所以我添加了另一个函数getClone($ prefix)来获取表单的克隆,它在表单名称中添加前缀后返回表单对象的克隆。喜欢这个

<?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;
    }

}

而且在我的行动中我做了这个

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;

}

这正如我所期望的那样工作,表格正确渲染和验证,我想知道它是正确的方式还是黑客攻击?

1 个答案:

答案 0 :(得分:0)

如果两个表单完全相同,那么您不需要在控制器操作中声明和验证两个表单。

原因:

如果有两个表单呈现您的HTML页面。用户一次只能发布其中一个表单,您需要一次只验证一个表单。您现在正在做的是再次使用相同的发布数据验证相同的表单。所以$ isFormOneValid,$ isFormTwoValid都是true或者都是false。

相反,只声明一个表单,在视图中呈现两次,然后在发布后,使用发布数据对其进行验证。如果两个表单在属性,过滤器,验证器等方面有所不同,那么您可以创建两个方法,如$ form-&gt; applyForm1Validarots()和$ form-&gt; applyForm2Validarots,检查select元素的值,并调用相应的方法在调用isValid()之前应用validaorts / filters。

希望我帮助

相关问题