Symfony - 在提交时设置validation_groups会跳过该类型的validation_groups回调

时间:2015-07-03 10:37:15

标签: symfony symfony-forms

在symfony中,我有一个嵌入其他形式的多阶段表单。其中一些嵌入表单具有动态验证组,通过该validation_groups(以前为setDefaultOptions)方法的configureOptions回调设置。

当通过未设置其validation_groups选项的提交提交表单时,将运行这些回调并使用正确的验证组。但是当我将submit的validation_groups选项设置为具有此回调的类型时,则不会运行回调,并且不会根据需要设置组。

是否需要设置任何选项才能使其正常工作?

控制器

$form = $this->createForm(new RegistrationType());
$form->add('Submit1', 'submit', array(
           'validation_groups' => array('Person'),
    ))
    ->add('Submit2', 'submit', array(
           'validation_groups' => array('Contact', 'Address'),
    ))
;

...

注册类型

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RegistrationType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('person', new PersonType())
            ->add('maritalStatus', 'entity', array(
                  'class' => 'AppBundle:MaritalStatus',
                  'choice_label' => 'status',
              ))
            ->add('spouse', new SpouseType())
            ->add('homeAddress', new AddressType())
            ->add('postalAddress', new AddressType())
            ->add('contact', new ContactType())
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Registration',
            'cascade_validation' => true,
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'appbundle_registration';
    }
}

PersonType

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PersonType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text')
            ->add('name', 'text')
            ->add('surname', 'text')
            ->add('fullName', 'text', array('required' => false))
            ->add('southAfrican', 'checkbox', array(
                  'required' => false,
                  'data' => true,
              ))
            ->add('identification', 'text')
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Person',

            // Setting some groups dynamically based on input data
            'validation_groups' => function (FormInterface $form) {
                $data = $form->getData();
                $groups = array('Person');

                // Add southAfrican validation group if is a southAfrican
                if ($data->isSouthAfrican() === true) {
                    $groups[] = 'southAfrican';
                }

                // Add Married validation group is this is spouse and Married is selected
                if ($form->getParent()->getConfig()->getName() === 'spouse') {
                    if ($form->getParent()->getParent()->getData()->getMaritalStatus()->getStatus() === 'Married') {
                        $groups[] = 'married';
                    } elseif (($key = array_search('southAfrican', $groups)) !== false) {
                        unset($groups[$key]);
                    }
                // If this is not spouse then this is applicant so add its validation group
                } else {
                    $groups[] = 'applicant';
                }

                return $groups;
            },
            'cascade_validation' => true,
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'appbundle_person';
    }
}

1 个答案:

答案 0 :(得分:1)

提交按钮验证组优先于Type的验证组。 Form::getClickedButton返回一个绑定到当前表单或其父项的单击按钮。

您描述的案例可以通过将回调而不是普通组传递到提交按钮来解决。 E.g:

$form->add('Submit1', 'submit', array(
       'validation_groups' => function (FormInterface $form) {
           if ($form->isRoot()) {
                return array('Person');
           } else {
                return ($form->getConfig()->getOptions('validation_groups'))();
           }
       },
))