Symfony2 Formless Form Validation Groups

I use the Symfony2 form component to create and validate forms. Now I need to configure the validator groups based on a single field value, and, unfortunately, it seems that each example there is based on objects that are not used for several reasons.

Example: If the task is empty, all constraint checking tools should be removed, but otherwise, it should use the default validator set (or validator group).

In other words, what I'm trying to achieve makes subforms optional, but still check if the key field is populated.

Can someone give me an example how to set it up?

<?php namespace CoreBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\Validator\Constraints as Assert; use CoreBundle\Form\Type\ItemGroupOption; class ItemGroup extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('title', 'text', array( 'label' => 'Titel', 'attr' => array('class' => 'span10 option_rename'), 'required' => false )); $builder->add('max_selections', 'integer', array( 'label' => 'Max tilvalg', 'constraints' => array(new Assert\Type('int', array('groups' => array('TitleProvided')))), 'attr' => array('data-default' => 0) )); $builder->add('allow_multiple', 'choice', array( 'label' => 'Tillad flere valg', 'constraints' => array(new Assert\Choice(array(0,1))), 'choices' => array(0 => 'Nej', 1 => 'Ja') )); $builder->add('enable_price', 'choice', array( 'label' => 'Benyt pris', 'constraints' => array(new Assert\Choice(array(0,1))), 'choices' => array(0 => 'Nej', 1 => 'Ja'), 'attr' => array('class' => 'option_price') )); $builder->add('required', 'choice', array( 'label' => 'Valg påkrævet', 'constraints' => array(new Assert\Choice(array(0,1))), 'choices' => array(0 => 'Nej', 1 => 'Ja') )); $builder->add('options', 'collection', array( 'type' => new ItemGroupOption(), 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false ) ); $builder->add('sort', 'hidden'); } public function getName() { return 'item_group'; } public function setDefaultOptions(OptionsResolverInterface $resolver) { global $app; $resolver->setDefaults(array( 'validation_groups' => function(FormInterface $form) use ($app) { // Get submitted data $data = $form->getData(); if (count($app['validator']->validateValue($data['title'], new Assert\NotBlank())) == 0) { return array('TitleProvided'); } else { return false; } }, )); } } 
+4
source share
1 answer

If you are using 2.1, you can see “Groups Based on Submitted Data” .

Update

Example of using the default /demo/contact contact page /demo/contact AcmeDemoBundle supplied with Symfony Standard Edition:

Type of form with conditional validation groups:

 namespace Acme\DemoBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\Validator\Constraints as Assert; class ContactType extends AbstractType { // Inject the validator so we can use it in the closure /** * @var Validator */ private $validator; /** * @param Validator $validator */ public function __construct(Validator $validator) { $this->validator = $validator; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('email', 'email'); $builder->add('message', 'textarea', array( // Added a constraint that will be applied if an email is provided 'constraints' => new Assert\NotBlank(array('groups' => array('EmailProvided'))), )); } public function setDefaultOptions(OptionsResolverInterface $resolver) { // This is needed as the closure doesn't have access to $this $validator = $this->validator; $resolver->setDefaults(array( 'validation_groups' => function(FormInterface $form) use ($validator) { // Get submitted data $data = $form->getData(); $email = $data['email']; // If email field is filled it will not be blank // Then we add a validation group so we can also check message field if (count($validator->validateValue($email, new Assert\NotBlank())) == 0) { return array('EmailProvided'); } }, )); } public function getName() { return 'contact'; } } 

Remember to enter the validator service in the form type:

 <?php namespace Acme\DemoBundle\Controller; //... class DemoController extends Controller { // ... public function contactAction() { $form = $this->get('form.factory')->create(new ContactType($this->get('validator'))); // ... } } 

As you can see, checking the message field will only work when the email field is filled.

Use the diff tool to recognize the differences.

+5
source

All Articles