Define valid form parameter values ​​depending on another parameter value in FormType

In Symfony 2.8, in a custom form type, is it possible to make setAllowedValues ​​return a result that depends on the value of another parameter? As far as I can see, there is no obvious way to access the Options object in closure.

 public function configureOptions(OptionsResolver $resolver) { $resolver->setRequired('option1'); $resolver->setRequired('option2'); $resolver->setAllowedValues('option2', function ($value) { return $based_on_set_restricted_by_option1; // <-- option2 values are allowed or denied depending on what option1 says } } 

The closest idea to the solution I have is to have an option, which is a dictionary that encapsulates both option1 and option2, and sets setAllowedValues ​​instead, but it’s not easy to restructure the parameters right now.

+2
source share
1 answer

The configureOptions() method of the symfony form type can do many things, since it provides an OptionResolver object (relying on its own component see ) to configure its configuration.

In this case, you need to call $resolver->setNormalizer() ( see ), which does exactly what you want, it has the ability to determine once the others are installed and can be called.

When the converter normalizes your variant, it executes the called one, passing an array of all parameters as the first argument, and the set parameter value is normalized as the second argument:

 // class CustomFormType extends \Symfony\Component\Form\Extension\Core\Type\AbstractType use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; public function configureOptions(OptionsResolver $resolver) { $resolver->setDefault('some_option', 'default value'); // or many at once $resolver->setDefaults(array( 'some_option' => 0, 'range_condition' => null, ); // what you need $someOptionNormalizer = function (Options $options, $someOption) { $rangeCondition = $options['range_condition']; if (in_array($rangeCondition, range(2, 5))) { if (in_array($someOption, range(6, 9))) { return $someOption; } throw new InvalidOptionsException(sprintf('When "range_condition" is inferior or equal to 5, "some_option" should be between 6 and 9, but "%d" given.', $someOption)); } if (in_array($rangeCondition, range(10, 13))) { if (in_array($someOption, range(1000, 1005))) { return $someOption; } throw new InvalidOptionsException(sprintf('When "range_condition" is between 10 and 13, "some_option" should be between 1000 and 1005, but "%d" given.', $someOption)); } }; $resolver->setNormalizer('some_option', $someOptionNormalizer); // you can also do $resolver->setRequired('some_option'); $resolver->setAllowedTypes('some_option', array('integer')); $resolver->setAllowedTypes('range_condition', array('null', 'integer')); $resolver->setAllowedValues('some_option', array_merge(range(6, 9), range(1000, 1005))); $resolver->setAllowedValues('range_condition', array_merge(range(2, 5), range(10, 13))); // ... } 
+3
source

Source: https://habr.com/ru/post/1257404/


All Articles