Symfony,如何使用表单事件来验证动态客户端表单 [英] Symfony, how to use form event to validate dynamic client-side form
问题描述
我使用带有ajax的select2插件在我的表单上有一个动态字段,但是当我提交时,它返回一个错误该值无效,这是正常的原因我在选项$ c $中使用了
ChoiceType
和一个空的 array()
c>创建选项。根据此部分的symfony文档,表单事件是我的救星,所以试图使用它,但它看起来像我的代码有问题,并不能真正看到。
问题是:
如何将选择可能性传递给该字段,以使表单有效。
我的表单类型
class ArticleType extends AbstractType
{
/ **
* {@inheritdoc}
* /
public function buildForm(FormBuilderInterface $ builder,array $ options)
{
$ builder
//我的其他领域
//我的函数添加可能的选择字段
$ formModifier = function(FormInterface $ form,$ imageValue)use($ options){
if($ imageValue!== null){
$ listImages = $ this-> getChoiceValue($ imageValue,$ options);
if(!$ listImages){
$ form-> get('image') - > addError(new FormError(
'Nous n \''vons pas pu trouver l'''mage,veuiller choisir une autre'
));
}
} else {
$ listImages = array();
}
// die(var_dump($ listImages)); //数组
$ form-> add('image',ChoiceType :: class,array($ b $'attr'=> array(
'id' =>'image'),
'expanded'=> false,
'multiple'=> false,
'choices'=> $ listImages));
};
$ b $ formModifierSubmit = Form(FormInterface $ form,$ imageValue)use($ options){
if($ imageValue!== null){
$ listImages = $ this- > getChoiceValue($ imageValue,$ options);
if(!$ listImages){
$ form-> get('image') - > addError(new FormError(
'Nous n \''vons pas pu trouver l'''mage,veuiller choisir une autre'
));
}
} else {
$ form-> get('image') - > addError(new FormError(
'Veuillez choisir une image svp'
));
}
// die(var_dump($ listImages)); // Image对象数组
$ config = $ form-> get('image') - > getConfig();
$ opts = $ config-> getOptions();
$ chcs = array('choices'=> $ listImages);
// die(var_dump($ chcs)); //输出一个带有'options'键的数组
array_replace($ opts,$ chcs); //不工作
// array_merge($ opts,$ chcs); //不工作
// die(var_dump($ opts)); //替换/合并不成立
};
$ builder-> addEventListener(
FormEvents :: PRE_SET_DATA,
function(FormEvent $ event)use($ formModifier){
// this will be the实体Article
$ data = $ event-> getData();
$ formModifier($ event-> getForm(),$ data-> getImage());
}
);
$ b $ // builder-> get('image') - > addEventListener(//提供错误导致字段图像不存在
$ builder-> addEventListener(
FormEvents :: PRE_SUBMIT,
function(FormEvent $ event)use($ formModifierSubmit){
$ imageVal = $ event-> getData();
// die(var_dump( $ imageVal)); //返回数组中的所有提交的数据字段
//但是,当将此事件更改为Submit时,将返回由提交的数据填充的Article模型,除了值为$的null图像字段b
$ b $ formModifierSubmit($ event-> getForm(),$ imageVal ['image']);
}
);
}
public function getChoiceValue($ imageValue,$ options)
{
$ listImages = $ options ['em'] - > getRepository('AlmotivAppBundle:Image') - > findBy(array(
'id'=> $ imageValue
));
return $ listImages; // Image对象数组
}
[...]
}
信息
我的图片
字段不依赖于任何其他因为我需要在 PRE_SUBMIT
事件上填充选项
选项以给出可能的选择。 / p>
并且 image
在我的 Article中有一个ManyToOne关系
实体
class Article实现HighlightableModelInterface
{
//一些属性
/ **
* @ ORM \ManyToOne(targetEntity =Image \Entity\Path,cascade = {persist})
* @ Assert \Valid()
* /
private $ image;
}
如果我处于不良状态,请告诉我因为我离开的想法现在,我尝试了很多东西,比如
url:$ form.attr('action')
的url发送ajax请求,我认为它会加载选项
选项可能包含< option>
但我的选择依然返回无< option>
。
以及更多(不能remmenber)。
此外,我还在使用select2插件的v4.0.3框架的v3.1,如果需要更多的信息,只需要询问和thx阅读和尝试帮助。 p>
编辑
只需添加一些信息即可更清楚
$ b你让事情太复杂。在您的文档示例中,他们为已经存在的表单字段('sport')添加eventListener,并将其添加到稍后添加的不存在的字段(文档示例中的'image'字段和'position'字段) p>
您应该使用 EntityType ,如果你需要(我不确定你是谁)用 query_builder 选项,用于验证添加约束条件( I'm using the select2 plugin with ajax to have a dynamic field on my form, but when i submit the it return me an error "This value is not valid", which is normal cause i use the So My Question Is : HOW to pass the choices possibility to the field, for the form to be valid. My form Type For Info My And also If i'm in the bad way let me know cause i'm out of idea now, i try much thing, like and much more (can't remmenber). And also i'm using the v3.1 of the framework with the v4.0.3 of the select2 plugin, if need more info just ask and thx for reading and trying help. Edit Just add some info to be more clear You making things way too complicated. In your documentation example they add eventListener for already existing form field ('sport') and you are adding it to only later added field which does not exist (your 'image' field and 'position' field from the documentation example). You should use EntityType and if you need (which I'm not if sure you are) filter your images using query_builder option, for validation add constraints (example with controller).
这篇关于Symfony,如何使用表单事件来验证动态客户端表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
class ArticleType extends AbstractType {
/ **
* {@inheri tdoc}
* /
public function buildForm(FormBuilderInterface $ builder,array $ options)
{
// $ builder
// My other field
$ imageFieldFunction = $ this-> getImageFieldFunction();
$ builder-> addEventListener(FormEvents :: PRE_SET_DATA,$ imageFieldFunction);
$ builder-> addEventListener(FormEvents :: PRE_SUBMIT,$ imageFieldFunction);
$ b private function getImageFieldFunction()
{
return function(FormEvent $ event){
$ form = $ event-> getForm() ;
$ data = $ event-> getData();
//当你的data_class是Article
$ image = $ data-> getImage(); //取决于你的Article类
/ *如果你正在使用data_class => null
$ image = $ data ['image'];
* /
$ imageId = $ image? $ image-> getId():0;
uilder-> add('image',EntityType :: class,array(
'class'=>'AlmotivAppBundle:Image',
'attr'= > array(
'id'=>'image'
),
'expanded'=> false,
'multiple'=> false,
'constraints'=> new NotBlank(),
'query_builder'=> function(EntityRepository $ er)use($ imageId){
return $ er-> createQueryBuilder('i')
- > where('i.id =:image_id')
- > setParameter('image_id',$ imageId);
}
)) ;
}
}
}
ChoiceType
with an empty array()
in the choices
options on creation. According to this part of the symfony doc, the form event is my savior, so trying to use it but it look like something wrong with my code and can't really see what.class ArticleType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//My other field
//My functions to add the field with the possible choices
$formModifier = function (FormInterface $form, $imageValue) use ($options) {
if ($imageValue !== null) {
$listImages = $this->getChoiceValue($imageValue, $options);
if (!$listImages) {
$form->get('image')->addError(new FormError(
'Nous n\'avons pas pu trouver l\'image, veuiller choisir une autre'
));
}
} else {
$listImages = array();
}
//die(var_dump($listImages)); //Array of Image
$form->add('image', ChoiceType::class, array(
'attr' => array(
'id' => 'image'),
'expanded' => false,
'multiple' => false,
'choices' => $listImages));
};
$formModifierSubmit = function (FormInterface $form, $imageValue) use ($options) {
if ($imageValue !== null) {
$listImages = $this->getChoiceValue($imageValue, $options);
if (!$listImages) {
$form->get('image')->addError(new FormError(
'Nous n\'avons pas pu trouver l\'image, veuiller choisir une autre'
));
}
} else {
$form->get('image')->addError(new FormError(
'Veuillez choisir une image s.v.p.'
));
}
//die(var_dump($listImages)); //Array of Image object
$config = $form->get('image')->getConfig();
$opts = $config->getOptions();
$chcs = array('choices' => $listImages);
//die(var_dump($chcs)); //output an array with a 'choices' keys with array value
array_replace($opts, $chcs); //not work
//array_merge($opts, $chcs); //not work
//die(var_dump($opts)); //replacements/merge are not made
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
// this would be the entity Article
$data = $event->getData();
$formModifier($event->getForm(), $data->getImage());
}
);
//$builder->get('image')->addEventListener( //give error cause the field image don't exist
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($formModifierSubmit) {
$imageVal = $event->getData();
//die(var_dump($imageVal)); //return all the submitted data field in an array
//But when change this event to Submit it return the Article model populated by the submitted data, EXCEPT the image field which have null as value
$formModifierSubmit($event->getForm(), $imageVal['image']);
}
);
}
public function getChoiceValue($imageValue, $options)
{
$listImages = $options['em']->getRepository('AlmotivAppBundle:Image')->findBy(array(
'id' => $imageValue
));
return $listImages; //array of Image object
}
[...]
}
image
field is not depending on any other field like the doc example, so i need to populate the choices
options on PRE_SUBMIT
event to give the possible choice.image
have a ManyToOne relation in my Article
entityclass Article implements HighlightableModelInterface
{
//some properties
/**
* @ORM\ManyToOne(targetEntity="Image\Entity\Path", cascade={"persist"})
* @Assert\Valid()
*/
private $image;
}
url : $form.attr('action')
, i think it will load the choices
option with the possible of <option>
but my select is still returned with none <option>
.class ArticleType extends AbstractType {
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// $builder
// My other field
$imageFieldFunction = $this->getImageFieldFunction();
$builder->addEventListener(FormEvents::PRE_SET_DATA, $imageFieldFunction);
$builder->addEventListener(FormEvents::PRE_SUBMIT, $imageFieldFunction);
}
private function getImageFieldFunction()
{
return function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
//when your data_class is Article
$image = $data->getImage();//depending on your Article class
/*if you are using data_class => null
$image = $data['image'];
*/
$imageId = $image ? $image->getId() : 0;
$builder->add('image', EntityType::class , array(
'class' => 'AlmotivAppBundle:Image',
'attr' => array(
'id' => 'image'
) ,
'expanded' => false,
'multiple' => false,
'constraints' => new NotBlank(),
'query_builder' => function (EntityRepository $er) use ($imageId) {
return $er->createQueryBuilder('i')
->where('i.id = :image_id')
->setParameter('image_id', $imageId);
}
));
}
}
}