6

I have a form containing a checkbox and a "value field". The value field could be anything, a text box, a compound field, a collection - anything.

The form could look like this, for example:

field_1_label    enabled    [x]
                 value      [________]

field_2_label    enabled    [x]
                 value      sub_field_1    [________]
                            sub_field_2    [________]

field_3_label    enabled    [x]
                 value      [________]

When the "enabled" field contains true, everything works fine already. When the "enabled" field contains false, I would like to disable validation on the value field and it's child fields.

So when "enabled" is un-checked, I will effectively ignore the field. I will still display it in the form, but I won't store the data and I certainly don't want it validated.

Does anybody have suggestions for how I might do this? Specifically, I'm having problems getting the validation system to ignore the value field and any potential child fields.

ledneb
  • 1,371
  • 1
  • 13
  • 25

2 Answers2

9

In Symfony 2.3 you can use false in validation_groups to have no constraints applied:

https://symfony.com/doc/current/form/button_based_validation.html

So for example, on the field containing the checkbox and value field:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver
        ->setDefaults([
            'validation_groups' => function(FormInterface $form) {
                // If the form is disabled, don't use any constraints
                if ($form->get('enabled_checkbox')->getData() == false) {
                    return false;
                }
                
                // Otherwise, use the default validation group
                return 'Default';
            }
        ]);
}
jake stayman
  • 1,687
  • 13
  • 22
vseager
  • 316
  • 1
  • 2
  • 5
  • Does this still work for 2.4? I'm having trouble with it; returning `false` does not appear to disable validation for the form. – Brian Apr 28 '14 at 17:47
  • Ok, I was able to get it to work by instead returning an empty array, instead of `false` – Brian Apr 28 '14 at 17:57
2

Just remove the child fields prior to validation if the parent's checkbox is set to false.

Read more in the cookbook article How to Dynamically Modify Forms Using Form Events.

Subscribe to form events FormEvents::POST_SET_DATA and remove the field in your subscriber.

The section Adding an Event Subscriber to a Fom class covers this topic.


You can aswell introduce different validation groups for your form.

Just apply another validation group ( not containing the chield fields ) if the parent's checkbox is set to false.

Nicolai Fröhlich
  • 51,330
  • 11
  • 126
  • 130
  • 1
    The issue with removing them is that the fields will be unavailable when the form is redisplayed - there'll be an 'enabled' checkbox but no value field if there are validation errors elsewhere on the form. It kind of leaves the form in a broken state, unless I add the fields back after validation. Although from SUBMIT / POST_SUBMIT onwards it's no longer possible to remove (or add) fields since the call to ->setParent(null) on the child will throw the exception 'You cannot remove children from a submitted form'. – ledneb Jun 14 '13 at 09:10
  • using POST_SET_DATA instead of POST_BIND does not help ? i added another possibility in the answer - just use validation groups. please review. – Nicolai Fröhlich Jun 14 '13 at 09:20
  • Validation happens POST_BIND so if I was going to skip the fields by removing pre-validation, I would need to add them again on POST_BIND, which isn't possible. Regarding validation groups, it seems it could be useful, but I don't see how I could specify the groups to validate? If I build various validation groups, it looks to me like the form system is hard-coded to only ever validate the "Default" group? (line 55 of Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener) – ledneb Jun 14 '13 at 10:17
  • 1
    just don't introduce any asserts using the default group and change the one's used by your form prior to validating. – Nicolai Fröhlich Jun 14 '13 at 10:21
  • 1
    you can set validation groups on your form dynamically and provide defaults with the validation_groups option -> see http://stackoverflow.com/a/8820022/1832745 – Nicolai Fröhlich Jun 14 '13 at 10:35