Allow all value on choice field type in Symfony2 form builder
Asked Answered
D

2

9

I have a problem for a while and I have read a lot on this topic with similar problem but cant implement the answers in my case.

I have a select field that I populate with Ajax. so in my form builder I have this code :

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';
    }

}

But my form never validates because their is no value in this choice field. But I can't add the value inside cause I don't know in advance what user will enter as a value.

So my question is how to disable verification on this field from Symfony. Or allow it to accept all value.

Thanks

EDIT

Here, I tried a new approach. I use The event Listener to modify my field with the value than the user submitted.

   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;
}

}

But still its not working, I have following error:

You cannot add children to a simple form. Maybe you should set the option "compound" to true?

So if someone know how to use this way with Event Listener it would be great.

Thanks

Deckard answered 25/2, 2015 at 13:19 Comment(2)
please provide us with more details about nomComplet entity field: field type / ORM settings for that field in your entity / values of that field (entity, text / integer)Meta
Sorry for reply time , you can look at my edit. Thx :)Deckard
M
13

This should work

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

Entire project demonstrating this case: https://github.com/LPodolski/choiceAjaxLoad

Code in case file is removed/altered:

/**
 * @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');
}
Meta answered 5/3, 2015 at 18:35 Comment(2)
I dont have the time to test that now but it look like what i need so i make your answer as accepted and will give a feedback later :) ThanksDeckard
Works fine but now you can add manually more options, and they will be valid choices, is there any way to prevent this ?Pampuch
A
1

So my question is how to disable verification on this field from Symfony.

According to the Documentation you can suppress form validation by using the POST_SUBMIT event and prevent the ValidationListener from being called.

$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
    $event->stopPropagation();
}, 900); // Always set a higher priority than ValidationListener
Acrilan answered 5/4, 2015 at 8:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.