How to validate a checkbox in ZF2

2019-03-29 09:40发布

I've read numerous workarounds for Zend Framework's lack of default checkbox validation.

I have recently started using ZF2 and the documentation is a bit lacking out there.

Can someone please demonstrate how I can validate a checkbox to ensure it was ticked, using the Zend Form and Validation mechanism? I'm using the array configuration for my Forms (using the default set-up found in the example app on the ZF website).

5条回答
Explosion°爆炸
2楼-- · 2019-03-29 09:51

Try this

Form element :

$this->add(array(
            'type' => 'Zend\Form\Element\Checkbox',
            'name' => 'agreeterms',
            'options' => array(
                'label' => 'I agree to all terms and conditions',
                'use_hidden_element' => true,
                'checked_value' => 1,
                'unchecked_value' => 'no'
            ),
        ));

In filters, add digit validation

use Zend\Validator\Digits; // at top

$inputFilter->add($factory->createInput(array(
                        'name' => 'agreeterms',
                        'validators' => array(
                            array(
                                'name' => 'Digits',
                                'break_chain_on_failure' => true,
                                'options' => array(
                                    'messages' => array(
                                        Digits::NOT_DIGITS => 'You must agree to the terms of use.',
                                    ),
                                ),
                            ),
                        ),
                    )));
查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-03-29 09:52

Very old question, but figured it might still be used/referenced by people, like me, still using Zend Framework 2. (Using ZF 2.5.3 in my case)

Jeff's answer above helped me out getting the right config here for what I'm using. In my use case I require the Checkbox, though leaving it empty will count as a 'false' value, which is allowed. His answer helped me allow the false values, especially his:

DO NOT try to filter the value to a boolean. For some reason, when the boolean value comes out to be false

The use case is to enable/disable certain entities, such as Countries or Languages so they won't show up in a getEnabled[...]() Repository function.

Form element

$this->add([
    'name' => 'enabled',
    'required' => true,
    'type' => Checkbox::class,
    'options' => [
        'label' => _('Enabled'),
        'label_attributes' => [
            'class' => '',
        ],
        'use_hidden_element' => true,
        'checked_value' => 1,
        'unchecked_value' => 0,
    ],
    'attributes' => [
        'id' => '',
        'class' => '',
    ],
]);

Input filter

$this->add([
    'name' => 'enabled',
    'required' => true,
    'validators' => [
        [
            'name' => InArray::class,
            'options' => [
                'haystack' => [true, false],
            ],
        ],
    ],
])
查看更多
欢心
4楼-- · 2019-03-29 09:59

This isn't directly related to the question, but here's some zf2 checkbox tips if you're looking to store a user's response in the database...

  1. DO use '1' and '0' strings, don't bother trying to get anything else to work. Plus, you can use those values directly as SQL values for a bit/boolean column.
  2. DO use hidden elements. If you don't, no value will get posted with the form and no one wants that.
  3. DO NOT try to filter the value to a boolean. For some reason, when the boolean value comes out to be false, the form doesn't validate despite having 'required' => false;

Example element creation in form:

$this->add([
    'name' => 'cellPhoneHasWhatsApp',
    'type' => 'Checkbox',
    'options' => [
        'label' => 'Cell phone has WhatsApp?',
        'checked_value' => '1',
        'unchecked_value' => '0',
        'use_hidden_element' => true,
    ],
]);

Example input filter spec:

[
    'cellPhoneHasWhatsApp' => [
         'required' => false,
     ],
]

And here's an example if you want to hide some other form fields using bootstrap:

$this->add([
    'name' => 'automaticTitle',
    'type' => 'Checkbox',
    'options' => [
        'label' => 'Automatically generate title',
        'checked_value' => '1',
        'unchecked_value' => '0',
        'use_hidden_element' => true,
    ],
    'attributes' => [
        'data-toggle'     => 'collapse',
        'data-target'     => '#titleGroup',
        'aria-expanded'   => 'false',
        'aria-controls'   => 'titleGroup'
    ],
]);

I'm a ZF2 fan, but at the end of the day, you just have to find out what works with it and what doesn't (especially with Forms). Hope this helps somebody!

查看更多
小情绪 Triste *
5楼-- · 2019-03-29 10:01

I had the same problem and did something similar to Optimus Crew's suggestion but used the Identical Validator.

If you don't set the checked_value option of the checkbox and leave it as the default it should pass in a '1' when the data is POSTed. You can set it if you require, but make sure you're checking for the same value in the token option of the validator.

$this->filter->add(array(
        'name' => 'agreeterms',
        'validators' => array(
            array(
                'name' => 'Identical',
                'options' => array(
                    'token' => '1',
                    'messages' => array(
                        Identical::NOT_SAME => 'You must agree to the terms of use.',
                    ),
                ),
            ),
        ),
    ));

This won't work if you use the option 'use_hidden_element' => false for the checkbox for the form. If you do this, you'll end up displaying the default NotEmpty message Value is required and can't be empty

查看更多
够拽才男人
6楼-- · 2019-03-29 10:07

You could also just drop the hidden form field (which I find a bit weird from a purist HTML point of view) from the options instead of setting its value to 'no' like this:

$this->add(array(
        'type' => 'Zend\Form\Element\Checkbox',
        'name' => 'agreeterms',
        'options' => array(
            'label' => 'I agree to all terms and conditions',
            'use_hidden_element' => false
        ),
    ));
查看更多
登录 后发表回答