简体   繁体   English

ZF2 FieldSet中至少需要一个元素

[英]Require at least one element in ZF2 FieldSet

The problem 问题

I have a Form and a FieldSet . 我有一个Form和一个FieldSet I would like to validate that the FieldSet is not empty. 我想验证FieldSet是否为空。 Also, I want to validate each field in the FieldSet . 另外,我想验证FieldSet每个字段。

So far, whatever I have tried is validating one or the other, but not both. 到目前为止,我所尝试的是验证一个或另一个,而不是两个。 If elements is present in the Form's input filter specification, then it validates that elements is not empty, but does not validate the bar and baz fields of FieldSet . 如果elements存在于所述表格的输入滤波器说明书中,然后它验证elements不是空的,但不验证barbaz领域FieldSet And, of course, the other way around. 当然,反之亦然。 Any clue as to how to approach this issue would be much appreciated. 任何有关如何解决此问题的线索将不胜感激。

The Form 表格

class FooForm extends Form implements InputFilterProviderInterface
{
    public function init()
    {
        $this->add([
            'name'     => 'elements',
            'type'     => Collection::class,
            'required' => true,
            'options'  => [
                'target_element' => [
                    'type' => SomeElementFieldSet::class
                ]
            ]
        ]);
    }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'        => 'elements',
                'required'    => true,
                'validators'  => [
                    ['name' => 'NotEmpty']
                ]
            ]
        ];
    }
}

The FieldSet FieldSet

class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
    public function init()
    {
        $this->add(['name' => 'bar']);
        $this->add(['name' => 'baz']);
    }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'       => 'bar',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ],
            [
                'name'       => 'baz',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ]
        ];
    }
}

Edit : Added full validation spec. 编辑 :添加了完整的验证规范。

After getting some hints on Google and digging through the source code, I found a solution. 在获得关于Google的一些提示并仔细研究了源代码之后,我找到了解决方案。 Unfortunately the zend-inputfilter implementation is a little buggy and won't work nicely with getInputFilterSpecification() , but we can just construct our own InputFilter and return that directly: 不幸的是, zend-inputfilter实现有点错误,不能与getInputFilterSpecification()很好地配合,但是我们可以构造自己的InputFilter并直接返回它:

The Form 表格

class FooForm extends BaseForm
{
    public function init()
    {
        $this->add([
            'name'    => 'elements',
            'type'    => Collection::class,
            'options' => [
                'target_element' => [
                    'type' => SomeElementFieldSet::class
                ]
            ]
        ]);
    }

    public function getInputFilter()
    {
        if (!$this->filter) {
            $this->filter = new InputFilter();

            /** @var Collection $elementsCollection */
            $elementsCollection = $this->fieldsets['elements'];

            /** @var SomeElementFieldSet $elementsFieldSet */
            $elementsFieldSet = $elementsCollection->getTargetElement();

            $collectionFilter = new CollectionInputFilter();
            $collectionFilter->setIsRequired(true);
            $collectionFilter->setInputFilter(
                $elementsFieldSet->getInputFilterSpecification()
            );

            $this->filter->add($collectionFilter, 'elements');
        }

        return $this->filter;
    }
}

This will validate that there is at least one element in the collection. 这将验证集合中至少有一个元素。 And will validate all the elements one by one by the FieldSet's specification. 并将按照FieldSet的规范逐一验证所有元素。

One problem persists, though. 但是,仍然存在一个问题。 Whenever the collection is empty, the validation will return false , but will not return any messages. 每当集合为空时,验证将返回false ,但不会返回任何消息。 This is due to a bug in the zend-inputfilter component. 这是由于zend-inputfilter组件中的错误所致。 Issues reported here and here . 这里这里报道的问题。 But that is another problem altogether. 但这完全是另一个问题。

Use setValidationGroup() method in the Form object by specifying an array of input fields you want to validate. 通过指定要验证的输入字段数组,在Form对象中使用setValidationGroup()方法。 Please refer to the Doc ! 请参考文档

You may give a try this way . 您可以这样尝试 Though I have added some extra fields to the form for testing purpose only. 尽管我在表单中添加了一些额外的字段,仅用于测试目的。

class FooForm extends Form implements InputFilterProviderInterface
{
     public function __construct($name = null, $options = array())
     {

        parent::__construct($name, $options);

        $this->add(['name' => 'title']);

        $this->add([
            'name'     => 'elements',
            'type'     => Collection::class,
            'required' => true,
            'options'  => [
                'target_element' => [
                    'type' => SomeElementFieldSet::class,
                ],
            ],
        ]);

        $this->add([
            'type' => 'submit',
            'name' => 'submit',
            'attributes' => [
                 'value' => 'Post'
            ],
        ]);

        // I pointed this. Here you can specify fields to be validated
        $this->setValidationGroup([
            'title',
            'elements' => [
                'bar',
            ],
        ]);         
     }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'       => 'title',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ],
        ];
    }     
}

And your fieldset class should be 您的fieldset类应该是

class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
    public function init()
    {
        $this->add(['name' => 'bar']);
        $this->add(['name' => 'baz']);
    }

    public function getInputFilterSpecification()
    {
        return [
            [
                'name'       => 'bar',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ],
            [
                'name'       => 'baz',
                'required'   => true,
                'validators' => [
                    ['name' => 'NotEmpty']
                ]
            ]
        ];
    }
} 

Hope this would help! 希望这会有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM