How to validate a checkbox in ZF2

11,436

Solution 1

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.',
                                    ),
                                ),
                            ),
                        ),
                    )));

Solution 2

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
        ),
    ));

Solution 3

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!

Solution 4

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

Solution 5

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],
            ],
        ],
    ],
])
Share:
11,436
Alex
Author by

Alex

Always learning.

Updated on July 15, 2022

Comments

  • Alex
    Alex almost 2 years

    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).

  • Alex
    Alex about 11 years
    cool thanks a lot. Was just about to start a new project, look forward to trying it out.
  • dKen
    dKen almost 10 years
    A nice, elegant solution given that ZF2 is continually and intentionally making common, everyday tasks as difficult and cumbersome as possible to implement.