Symfony2 - adding a selection from the database

I want to populate a select box in symfony2 with values ​​from a user request. I tried to simplify as much as possible.

controller

class PageController extends Controller { public function indexAction() { $fields = $this->get('fields'); $countries = $fields->getCountries(); // returns a array of countries eg array('UK', 'France', 'etc') $routeSetup = new RouteSetup(); // this is the entity $routeSetup->setCountries($countries); // sets the array of countries $chooseRouteForm = $this->createForm(new ChooseRouteForm(), $routeSetup); return $this->render('ExampleBundle:Page:index.html.twig', array( 'form' => $chooseRouteForm->createView() )); } } 

ChooseRouteForm

 class ChooseRouteForm extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { // errors... ideally I want this to fetch the items from the $routeSetup object $builder->add('countries', 'choice', array( 'choices' => $this->routeSetup->getCountries() )); } public function getName() { return 'choose_route'; } } 
+6
source share
2 answers

You can pass the selection to your form using ..

 $chooseRouteForm = $this->createForm(new ChooseRouteForm($routeSetup), $routeSetup); 

Then in your form ..

 private $countries; public function __construct(RouteSetup $routeSetup) { $this->countries = $routeSetup->getCountries(); } public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('countries', 'choice', array( 'choices' => $this->countries, )); } 

Updated (and improved) for 2.8+

Firstly, you do not need to go through countries as part of the route object if they are not stored in the database.

If you save the available countries in the database, you can use the event listener. If not (or if you do not want to use a listener), you can add countries to the options area.

Using options

In the controller ..

 $chooseRouteForm = $this->createForm( ChooseRouteForm::class, // Or the full class name if using < php 5.5 $routeSetup, array('countries' => $fields->getCountries()) ); 

And in your form ..

 public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('countries', 'choice', array( 'choices' => $options['countries'], )); } public function configureOptions(OptionsResolver $resolver) { $resolver ->setDefault('countries', null) ->setRequired('countries') ->setAllowedTypes('countries', array('array')) ; } 

Using a listener (If an array of models is available in the model)

In the controller ..

 $chooseRouteForm = $this->createForm( ChooseRouteForm::class, // Or the full class name if using < php 5.5 $routeSetup ); 

And in your form ..

 public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) { $form = $event->getForm(); /** @var RouteSetup $routeSetup */ $routeSetup = $event->getData(); if (null === $routeSetup) { throw new \Exception('RouteSetup must be injected into form'); } $form ->add('countries', 'choice', array( 'choices' => $routeSetup->getCountries(), )) ; }) ; } 
+19
source

I cannot comment or downgrade yet, so I will simply answer the Qoop answer: What you suggested will work if you do not start using a form type class as a service. Normally, you should avoid adding data to the form type object through the constructor.

Think of a form type class as Class is a kind of description of your form. When you create an instance of the form (by creating it), you get an Object of the form, which is created according to the description in the form type, and then filled with data.

Take a look at this: http://www.youtube.com/watch?v=JAX13g5orwo - this situation is described after about 31 minutes of submission.

You must use the FormEvents :: PRE_SET_DATA event of the form and manipulate the fields when the form is entered with data. See: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#customizing-your-form-based-on-the-underlying-data

+10
source

All Articles