我正在使用Symfony2表单组件来构建和验证表单。现在我需要根据单个字段值设置验证器组,不幸的是,似乎每个示例都基于实体 - 由于多种原因我暂不使用。
实施例: 如果task为空,则应删除所有约束验证器,但如果不是,则应使用默认的验证器集(或验证器组)。
换句话说,我想要实现的是使子表格可选,但如果填充了一个关键字段,仍然可以验证。
有人可以举个例子来说明如何配置吗?
<?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;
}
},
));
}
}
答案 0 :(得分:7)
如果您使用的是2.1,可能需要查看"Groups based on submitted data"。
<强>更新强>
使用Symfony标准版提供的默认/demo/contact
中的演示联系页面AcmeDemoBundle
的示例:
带有条件验证组的表单类型:
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';
}
}
不要忘记在表单类型中注入validator
服务:
<?php
namespace Acme\DemoBundle\Controller;
//...
class DemoController extends Controller
{
// ...
public function contactAction()
{
$form = $this->get('form.factory')->create(new ContactType($this->get('validator')));
// ...
}
}
正如您所看到的,message
字段的验证仅在email
字段填充时才会被触发。
使用差异工具来捕捉差异。