Search code examples
validationzend-framework2zend-form2

ZF2 Only make a form element required based on another element?


So I have a list of elements in my form, one of which is a select box with a simple yes/no option. When the field is 'no' I want to make the next input field required.

At the moment my input filter looks like:

return [
    [
        'name' => 'condition',
        'required' => true,
    ],
    [
        'name' => 'additional',
        'required' => false,
        'validators' => [
            [
                'name' => 'callback',
                'options' => [
                    'callback' => function($value, $context) {
                        //If condition is "NO", mark required
                        if($context['condition'] === '0' && strlen($value) === 0) {
                            return false;
                        }
                        return true;
                    },
                    'messages' => [
                        'callbackValue' => 'Additional details are required',
                    ],
                ],
            ],
            [
                'name' => 'string_length',
                'options' => [
                    'max' => 255,
                    'messages' => [
                        'stringLengthTooLong' => 'The input must be less than or equal to %max% characters long',
                    ],
                ],
            ],
        ],
    ],
];

What I am finding is because I have 'required' => false, for the additional field, none of the validators run.

How do I make additional required ONLY when condition is 'no' (value '0')?


Solution

  • It is possible to retrieve the elements from within the getInputFilterSpecification function. As such, it is possible to mark an element as required or not based on the value of another element in the same form or fieldset:

    'required' => $this->get('condition')->getValue() === '0',
    

    With this, I can also get rid of the massive callback validator too.

    return [
        [
            'name' => 'condition',
            'required' => true,
        ],
        [
            'name' => 'additional',
            'required' => $this->get('condition')->getValue() === '0',
            'validators' => [
                [
                    'name' => 'string_length',
                    'options' => [
                        'max' => 255,
                        'messages' => [
                            'stringLengthTooLong' => 'The input must be less than or equal to %max% characters long',
                        ],
                    ],
                ],
            ],
        ],
    ];