没有实体的Symfony2表单验证器组 [英] Symfony2 form validator groups without entities
问题描述
我正在使用Symfony2表单组件来构建和验证表单.现在,我需要基于单个字段值设置验证器组,不幸的是,似乎那里的每个示例都是基于实体的-出于多种原因,我没有使用它.
I'm using Symfony2 form component to build and validate forms. Now I need to setup validator groups based on a single field value, and unfortunately it seems that every example out there is based on entities - which im not using for several reasons.
示例:如果task为空,则应删除所有约束验证器,但如果不为空,则应使用默认的验证器集(或验证器组).
Example: If task is empty, all constraint validators should be removed, but if not, it should use the default set of validators (or a validator group).
换句话说,我要实现的目的是使子表单成为可选表单,但是如果填充了关键字段,仍然可以得到验证.
In other words, what I'm trying to achieve is making subforms optional, but still be validated if a key field is populated.
有人可以给我一个如何配置它的例子吗?
Can someone possible give me an example how to configure it?
<?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;
}
},
));
}
}
推荐答案
如果您使用的是2.1,则可能需要查看.
If you are using 2.1 you may want to have a look at "Groups based on submitted data".
更新
在Symfony Standard Edition随附的默认 AcmeDemoBundle
中使用演示联系人页面/demo/contact
的示例:
Example using the demo contact page /demo/contact
in the default AcmeDemoBundle
provided with Symfony Standard Edition :
带有条件验证组的表单类型:
The form type 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';
}
}
别忘了以表单类型注入 validator
服务:
Don't forget to inject 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')));
// ...
}
}
如您所见,只有填写 email
字段时,才会触发对 message
字段的验证.
As you can see validation of the message
field will be triggered only if the email
field is filled.
使用差异工具来捕捉差异.
Use a diff tool to catch the differences.
这篇关于没有实体的Symfony2表单验证器组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!