1

I'm using Symfony2 form component to create and modify forms. I'm currently loading all model entities as choices, but I need to get only the Models related to the selected (posted) value from manufacturer.

How can I achieve this?

class VehicleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('manufacturer', 'entity', array(
            'label' => 'Brand',
            'attr' => array('class' => 'input-block-level'),
            'class' => 'BalslevCarBundle:Manufacturers',
            'property' => 'short_name',
            'empty_value' => 'All',
            'required' => false
        ));
        $builder->add('model', 'entity', array(
            'label' => 'Model',
            'class' => 'BalslevCarBundle:Models',
            'property' => 'model',
            'empty_value' => 'All',
            'required' => false
        ));
    }

    public function getName()
    {
        return 'search';
    }
}
Kristian
  • 1,343
  • 4
  • 29
  • 47
  • Are you asking your question when you need to create a new form inside the view (on manufacturer change, you need to update the model ?) or when validating the submitted form ? – Sybio Mar 07 '13 at 23:28
  • 1
    Kristian, have a look at http://symfony.com/doc/current/reference/forms/types/entity.html#using-a-custom-query-for-the-entities and http://stackoverflow.com/questions/6716776/symfony-2-how-to-pass-data-to-formbuilder . However, the models for a manufacturer are loaded when the form is created. If you want to update the list when the page is loaded you have to do that with jQuery and an AJAX call to a controller action which returns all models to a selected manufacturer (return as json so you can use it to fill the model form field). – hacfi Mar 08 '13 at 04:31
  • 1
    Or create a form listener: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#inside-the-event-subscriber-class – hacfi Mar 08 '13 at 04:34
  • @Sybio On manufacturer change, I'm updating the model options using AJAX. What I need is to set the options based on the submitted value of manufacturer. – Kristian Mar 08 '13 at 08:51
  • @hacfi Thanks for your links, they are very useful, though I'm still missing a way to fetch the default option for manufacturer. – Kristian Mar 08 '13 at 08:53

1 Answers1

0

First of all, you have to create "dynamically" your choices based onto user selection.
There are two ways, strictly coupled with your application behaviour, that leads (in both cases) at the same "core" code; the difference is only the way you call it.

So, let's explain the two possibilities:

  1. Select manufacturer "statically" and don't change it over the time of request: use data retrieved from your business logic
  2. Select manufacturer "dinamically" and can change them over the time of request: replace your form at every request; new form will be provided by business logic

So, the HEART of your question is: how can I retrieve only associated entities?

Answer

Into your VehicleType.php (where entity, in this case, is VehicleType ?)

private $manufacturerId;

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

public function BuildForm(FormBuilderInterface $builder)
{
    $manufacturerId = $this->manufacturerId;

    $manufacturerQuery = function(EntityRepository $repo) use ($manufacturerId ){
                              return $repo->createQueryBuilder('m')
                                          ->where('m.id = :id')
                                          ->setParameter('id',$manufacturerId );};

    $builder->add('manufacturer', 'entity', array(
        'label' => 'Brand',
        'attr' => array('class' => 'input-block-level'),
        'class' => 'BalslevCarBundle:Manufacturers',
        'property' => 'short_name',
        'empty_value' => 'All',
        'required' => false,
        'query_builder' => $manufacturerQuery;
    ));

    $builder->add('model', 'entity', array(
        'label' => 'Brand',
        'attr' => array('class' => 'input-block-level'),
        'class' => 'BalslevCarBundle:Manufacturers',
        'property' => 'short_name',
        'empty_value' => 'All',
        'required' => false,
        'query_builder' => $modelQuery;
    ));
}

As you can see, in this way we use a custom repository to get only entities that are suitable for our needs. Obviously I am writing my DQL query without knowing your DB structure: it's your task and responsibility to adapt it to your real situation.

Moreover, you have to create another query for model (called $modelQuery in my answer) to retrieve correct models based on selected $id

Community
  • 1
  • 1
DonCallisto
  • 29,419
  • 9
  • 72
  • 100