我正在使用带有ajax的select2插件在我的表单上有一个动态字段,但是当我提交它时返回错误“此值无效”,这是正常原因我在创建ChoiceType
选项时使用array()
空choices
。根据symfony doc的this部分,form事件是我的救星,所以试图使用它,但它看起来像我的代码有问题,并且无法真正看到什么。
所以我的问题是:
如何将选择可能性传递给字段,以使表单有效。
我的表单类型
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
字段不依赖于doc示例等任何其他字段,因此我需要填充choices
事件上的PRE_SUBMIT
选项以提供可能的选择。
此image
实体中Article
也有一个ManyToOne关系
class Article implements HighlightableModelInterface
{
//some properties
/**
* @ORM\ManyToOne(targetEntity="Image\Entity\Path", cascade={"persist"})
* @Assert\Valid()
*/
private $image;
}
如果我的方式不好让我知道因为我现在已经不在乎了,我会尝试很多东西,比如
url : $form.attr('action')
的网址发出ajax请求,我认为它会加载choices
选项,其可能为<option>
但我的选择仍然返回时没有{ {1}}。以及更多(无法挽回)。
而且我正在使用框架的v3.1和select2插件的v4.0.3,如果需要更多信息,请询问和thx阅读并尝试帮助。
修改
只需添加一些信息即可更清晰
答案 0 :(得分:0)
你让事情变得太复杂了。在您的文档示例中,他们为已存在的表单字段('sport')添加了eventListener,并且您只将它添加到以后添加的不存在的字段(文档示例中的'image'字段和'position'字段)。
您应该使用EntityType,如果您需要(我确定不是),请使用query_builder选项过滤您的图片,以便验证添加constraints({{3} })。
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);
}
));
}
}
}