25

if i show a field of type "entity" in my form, and i want to filter this entity type based on a argument I pass from the controller, how do i do that.. ?

//PlumeOptionsType.php
public function buildForm(FormBuilder $builder, array $options)
{
    $builder->add('framePlume', 'entity', array(
        'class' => 'DessinPlumeBundle:PhysicalPlume',
        'query_builder' => function(EntityRepository $er) {
                                return $er->createQueryBuilder('pp')
                                    ->where("pp.profile = :profile")
                                    ->orderBy('pp.index', 'ASC')
                                    ->setParameter('profile', ????)
                                ;
                            },

    ));
}

public function getName()
{
    return 'plumeOptions';
}

public function getDefaultOptions(array $options)
{
    return array(
            'data_class'      => 'Dessin\PlumeBundle\Entity\PlumeOptions',
            'csrf_protection' => true,
            'csrf_field_name' => '_token',
            // a unique key to help generate the secret token
            'intention'       => 'plumeOptions_item',
    );
}
}

and inside the controller, i create the form :

i have that argument that i need to pass in my action code:
$profile_id = $this->getRequest()->getSession()->get('profile_id');
...
and then i create my form like this
$form = $this->createForm(new PlumeOptionsType(), $plumeOptions);

the $plumeOptions is just a class to persist. But it has a one-to-one relationship with another class called PhysicalPlume. Now, when i want to display the 'framePlume' in my code, i want to show a filtered PhysicalPlume entity.

xeon
  • 829
  • 2
  • 12
  • 21
  • answered already... check http://stackoverflow.com/questions/6716776/symfony-2-how-to-pass-data-to-formbuilder – xeon Oct 19 '11 at 14:35

2 Answers2

40

You can pass parameters to the form class as follows:

//PlumeOptionsType.php
protected $profile;

public function __construct (Profile $profile)
{
    $this->profile = $profile;
}

Then use it in the query_builder of your buildForm:

$profile = $this->profile;

$builder->add('framePlume', 'entity', array(
    'class' => 'DessinPlumeBundle:PhysicalPlume',
    'query_builder' => function(EntityRepository $er) use ($profile) {
                            return $er->createQueryBuilder('pp')
                                ->where("pp.profile = :profile")
                                ->orderBy('pp.index', 'ASC')
                                ->setParameter('profile', $profile)
                            ;
                        },

));

And finally in your controller:

// fetch $profile from DB
$form = $this->createForm(new PlumeOptionsType($profile), $plumeOptions);
Marcel Burkhard
  • 3,453
  • 1
  • 29
  • 35
  • thx for answering, I think you got exactly what i mean... Still, i got an error doing exactly what you suggested. Using $this when not in object context in PlumeBundle\Form\Type\PlumeOptionsType.php – xeon Oct 19 '11 at 10:10
  • http://pastebin.com/RVLFCxL4 http://pastebin.com/778ygFgR http://pastebin.com/q81k8w9A I think my problem is related to callback function. i can read the profile from inside PlumeOptionsType, but not from inside 'query_builder' => function(EntityRepository $er) – xeon Oct 19 '11 at 13:43
  • :please post that answer again with the "use" statement so we can set this question as answered !! – xeon Oct 19 '11 at 14:50
  • 6
    Passing a form type is now deprecated: http://stackoverflow.com/questions/34027711/passing-data-to-buildform-in-symfony-2-8-3-0 – Jonathan Dec 01 '15 at 18:42
4

You can use $plumeOptions to pass everything your argument, but you'll need to add a getDefaultOptions() in PlumeOptionsType to specify the default value for your option. See for instance https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/CheckboxType.php to see what this method should look like.

greg0ire
  • 22,714
  • 16
  • 72
  • 101
  • 1
    Can you elaborate more.. ? can you be more specific ?? – xeon Oct 18 '11 at 14:06
  • I edited my message to add more precisions on the `getDefaultOptions()` method – greg0ire Oct 18 '11 at 14:22
  • Ok, let's say i added a default profile_id in the returned array of getDefaultOptions() of PlumeOptionsType. and i used ->setParameter('profile', $options['profile_id'])... but how to pass profile_id to the $plumeOptions at the first place?? Thank you for your help !! – xeon Oct 18 '11 at 16:55
  • ?!? Just do this : `$plumeOptions['profile_id'] = 42`... I think I don't get the real problem. – greg0ire Oct 18 '11 at 17:21
  • i got this now: public function editPlumeOptionsAction(Request $request, $user_ou) { //get session and get profile_id from session $repository = $this->getDoctrine()->getRepository('DessinProfileBundle:Profile'); $profile = $repository->findOneById($profile_id); $plumeOptions = $profile->getPlumeOptions(); if(!$plumeOptions instanceof PlumeOptions) $plumeOptions = new PlumeOptions(); $plumeOptions['profile_id'] = $profile_id; $form = $this->createForm(new PlumeOptionsType(), $plumeOptions); i got an error "Cannot use object of type ..." – xeon Oct 18 '11 at 17:31
  • i have a table profile 1<->1 relationship with table plumeOptions. and table PlumeOptions 1<->1 relationship with table PhysicalPlume. and table Profile has a relationship of 1to200 PhysicalPlume. so in the table PhysicalPlume, there is a FK profile id. that's what i want my form to display: not all PhysicalPlumes, but only the ones related to that profile. Hope this helps a bit clarifying the picture.. – xeon Oct 18 '11 at 17:41
  • Please update your answer instead of putting code in comments. – greg0ire Oct 18 '11 at 18:35
  • You get this error because `$plumeOptions` is supposed to be an array. Instead, you provide a `PlumeOptions` object. Too achieve your goald : should use a `CollectionType` type like this : http://sf.khepin.com/2011/08/inconsistent-behavior-of-symfony2s-form-framework/ . Have a look to the `newAction()` method to see how objects are added to the collection. – greg0ire Oct 18 '11 at 18:42