Php Symfony,如何使用表单事件验证动态客户端表单
我使用带有ajax的select2插件在表单上有一个动态字段,但当我提交该插件时,它返回一个错误“此值无效”,这是正常的,因为我在创建时在Php Symfony,如何使用表单事件验证动态客户端表单,php,forms,symfony,symfony-forms,Php,Forms,Symfony,Symfony Forms,我使用带有ajax的select2插件在表单上有一个动态字段,但当我提交该插件时,它返回一个错误“此值无效”,这是正常的,因为我在创建时在选项中使用带有空数组()的ChoiceType。根据symfony文档的一部分,表单事件是我的救世主,因此尝试使用它,但我的代码似乎有问题,无法真正看到问题所在 所以我的问题是: 如何将选项可能性传递给字段,以使表单有效 我的表单类型 class ArticleType extends AbstractType { /** * {@inher
选项中使用带有空数组()的ChoiceType
。根据symfony文档的一部分,表单事件是我的救世主,因此尝试使用它,但我的代码似乎有问题,无法真正看到问题所在
所以我的问题是:
如何将选项可能性传递给字段,以使表单有效
我的表单类型
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
}
[...]
}
获取信息
我的图像
字段不依赖于任何其他字段,如doc示例,因此我需要填充提交前
事件上的选项
以提供可能的选择
而且,图像
在我的文章
实体中也有多个关系
class Article implements HighlightableModelInterface
{
//some properties
/**
* @ORM\ManyToOne(targetEntity="Image\Entity\Path", cascade={"persist"})
* @Assert\Valid()
*/
private $image;
}
如果我的情况不好,让我知道,因为我现在不知道,我会尝试很多事情,比如
- 数组\u替换为字段配置中的选项,但没有错误
- 对表单action的url发出ajax请求
url:$form.attr('action')
,我想它会加载选项,可能是
,但是我的选择仍然返回,没有
还有更多(记不得了)
另外,我正在使用框架的v3.1和select2插件的v4.0.3,如果需要更多信息,请询问和thx以获取阅读和尝试帮助
编辑
只需添加一些信息就可以更清楚地了解你把事情弄得太复杂了。在您的文档示例中,他们为已经存在的表单字段(“sport”)添加eventListener,而您只将其添加到以后添加的不存在的字段(文档示例中的“image”字段和“position”字段)
您应该使用和(如果您需要)(我不确定您是否需要)使用选项过滤您的图像,用于验证添加()
我不认为使用EntityType
是最好的方法。我的表单上有一个字段图像,它与我的文章实体有多个关系,但是图像表可能有数千个条目,因此我使用ajax(带有select2插件)在客户端传递选择可能性,并且由于我在字段的选择选项中使用空数组,然后我想将选择传递给字段,以便表单有效。您也可以使用EntityType进行ajax加载。实际上,我自己也遇到过这个问题,我的做法是将eventListener添加到生成器中,用于预设置数据和预提交事件。我已经更新了我的答案。它对我有用,我肯定我是这样做的,但不管怎样,它工作得很好。所以问题是要和EntityType一起工作,我想我已经在路上了。我用我的最终代码发布了一个答案。谢谢你的帮助,我的错,我似乎无法给出答案,我做了一个回答
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);
}
));
}
}
}