laminas / laminas-form

Validate and display simple and complex forms, casting forms to business objects and vice versa
https://docs.laminas.dev/laminas-form/
BSD 3-Clause "New" or "Revised" License
80 stars 52 forks source link

MultiCheckbox: default input filter prevents submitting with no options checked #24

Open weierophinney opened 4 years ago

weierophinney commented 4 years ago

See zendframework/zendframework#4694, zendframework/zendframework#2395, https://framework.zend.com/issues/browse/ZF2-571.

The issue remains the same now as it was in 2012: MultiCheckbox extends Checkbox. Checkbox's input filter defaults to required, a more or less sensible setup for an element that by default includes a hidden input so something should always be submitted. MultiCheckbox, sensibly, changes the default to not include the hidden input as it doesn't really make sense for a normal multi-checkbox setup. But, it doesn't override the input filter specification.

The result is that by default, a MultiCheckbox will throw a validation error when submitted with nothing checked.


Originally posted by @zerocrates at https://github.com/zendframework/zend-form/issues/123

weierophinney commented 4 years ago

Confirmed. Failing test case:

    public function testDefaultInputFilterAllowsSubmittingWithNoCheckedOptions()
    {
        $element = new MultiCheckboxElement();
        $element->setName('foo');
        $element->setValueOptions([
            'Option 1' => 'option1',
            'Option 2' => 'option2',
            'Option 3' => 'option3',
        ]);

        $form = new \Zend\Form\Form();
        $form->add($element);

        $form->setData([]);
        $this->assertTrue($form->isValid());
    }

Originally posted by @adamlundrigan at https://github.com/zendframework/zend-form/issues/123#issuecomment-250928155

weierophinney commented 4 years ago

Adding this to MultiCheckboxElement will fix the issue:

    public function getInputSpecification()
    {
        $spec = parent::getInputSpecification();
        $spec['required'] = false;

        return $spec;
    }

However we're changing the default behaviour of the element (form will now validate successfully when the checkbox name is not present in the form data, whereas previously it would not). There are likely form implementations that rely on the default behaviour being to require at least one selection so this is a BC break IMO.

My suggestion is we consider this a documentation issue rather than a bug. The default behaviour is fine as long as it's known and expected, and overriding it is straightforward (pull the form element's corresponding Input from the InputFilter and call setRequired(false)). Perhaps we just add a section to the MultiCheckbox documentation page with that information?


Originally posted by @adamlundrigan at https://github.com/zendframework/zend-form/issues/123#issuecomment-250928755