1

如果用户选中一个选择框,我需要再次呈现和处理相同的表单。我查看了表单集合,但它并没有完全解决我的问题,因为我不需要呈现一组字段,而是我的要求是再次呈现完整的表单。所以我添加了另一个函数 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;

}

这正如我预期的那样工作,表单正在正确呈现和验证,我想知道它是正确的方式还是黑客?

4

1 回答 1

0

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

原因:

如果有两个表单呈现您的 HTML 页面。用户一次只能发布一个表单,您一次只需要验证一个表单。您现在正在做的是再次验证具有相同帖子数据的相同表单。所以 $isFormOneValid 和 $isFormTwoValid 都为真或都为假。

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

希望我有所帮助

于 2013-10-14T08:34:07.353 回答