在Symfony2表单构建器中允许选择字段类型的所有值

9

我有一个问题已经有一段时间了,我在这个话题上读了很多类似问题的文章,但是无法在我的情况下实现答案。

我有一个使用Ajax填充的选择字段。因此,在我的表单构建器中,我有以下代码:

VilleType.php

/**
 * @ORM\Entity(repositoryClass="MDB\AnnonceBundle\Entity\RegisterRepository")
 */
class VilleType extends AbstractType {

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
                ->add('nomComplet', 'choice'
        );
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'MDB\AdresseBundle\Entity\Ville'
        ));
    }

    /**
     * @return string
     */
    public function getName() {
        return 'mdb_adressebundle_ville';
    }

}

但是我的表格从来没有通过验证,因为这个选择字段里没有值。但我不能提前添加值,因为我不知道用户会输入什么值。
所以我的问题是如何从Symfony中禁用此字段的验证,或允许它接受所有值。
谢谢
编辑: 在这里,我尝试了一种新方法。我使用事件监听器来修改用户提交的字段值。
   public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder
                ->add('nomComplet', 'choice');


        $builder->get('nomComplet')->addEventListener(
                FormEvents::PRE_SUBMIT, function(FormEvent $event) /* use ($formModifier) */ {

                    $ville = $event->getData();
                    $event->getForm()->add('nomComplet', 'choice', array('choices' => $ville));
                    // $formModifier($event->getForm()->getParent(), $ville);
                }
        );
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'MDB\AdresseBundle\Entity\Ville'
        ));
    }

    /**
     * @return string
     */
    public function getName() {
        return 'mdb_adressebundle_ville';
    }

}

MDB\AdresseBundle\Entity\Ville.php

<?php

namespace MDB\AdresseBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Ville
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="MDB\AdresseBundle\Entity\VilleRepository");
 */
class Ville
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="nomComplet", type="string", length=255)
     */
    private $nomComplet;

    /**
     * @var string
     *
     * @ORM\Column(name="nomClean", type="string", length=255)
     */
    private $nomClean;


    /**
     * @var array
     *
     * @ORM\Column(name="cp", type="simple_array")
     */
    private $cp;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set nomComplet
     *
     * @param string $nomComplet
     * @return Ville
     */
    public function setNomComplet($nomComplet)
    {
        $this->nomComplet = $nomComplet;

        return $this;
    }

    /**
     * Get nomComplet
     *
     * @return string 
     */
    public function getNomComplet()
    {
        return $this->nomComplet;
    }

    /**
     * Set nomClean
     *
     * @param string $nomClean
     * @return Ville
     */
    public function setNomClean($nomClean)
    {
        $this->nomClean = $nomClean;

        return $this;
    }

    /**
     * Get nomClean
     *
     * @return string 
     */
    public function getNomClean()
    {
        return $this->nomClean;
    }


    /**
     * Set cp
     *
     * @param array $cp
     * @return Ville
     */
    public function setCp($cp)
    {
        $this->cp = $cp;

        return $this;
    }

    /**
     * Get cp
     *
     * @return array 
     */
    public function getCp()
    {
        return $this->cp;
    }

    public function __toString()
{
    return $this->nomComplet;
}

}

但是它仍然不能正常工作,我遇到了以下错误:

您无法向简单表单添加子级。也许您应该将选项“compound”设置为true?

如果有人知道如何使用事件监听器来解决这个问题,那就太好了。

谢谢


请提供有关nomComplet实体字段的更多详细信息:该字段在您的实体中的字段类型/ ORM设置/该字段的值(实体、文本/整数)。 - LPodolski
抱歉回复时间晚了,你可以看一下我的编辑。谢谢 :) - LedZelkin
2个回答

13

这应该可以工作

https://github.com/LPodolski/choiceAjaxLoad/blob/master/src/AppBundle/Form/ItemType.php

整个项目演示了这种情况: https://github.com/LPodolski/choiceAjaxLoad

如果文件中的代码已被删除/更改:

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('choiceField', 'choice', array(
            'attr' => array(
                'class' => 'choiceField'
            )
        ))
    ;

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
        $form = $event->getForm();
        $data = $event->getData();
        $form->remove('choiceField');
        $form->add('choiceField', 'choice', array(
            'attr' => array(
                'class' => 'choiceField',
            ),
            'choices' => array(
                $data['choiceField'] => $data['choiceField'],
            )
        ));
    });

    $builder->add('save', 'submit');
}

我现在没有时间测试,但看起来是我需要的,所以我将接受您的答案,并稍后给出反馈 :) 谢谢 - LedZelkin
好的,我尝试了一下,结果非常完美,真的非常感谢 ;) - LedZelkin
工作正常,但现在您可以手动添加更多选项,并且它们将成为有效的选择,有没有办法防止这种情况发生? - Manuel Garcia

1
所以我的问题是如何从Symfony上禁用此字段的验证。根据文档,您可以使用POST_SUBMIT事件抑制表单验证并防止调用ValidationListener。
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
    $event->stopPropagation();
}, 900); // Always set a higher priority than ValidationListener

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接