Reputation: 271
A car machine oil is applicable to several car models, but in my case, there are hundreds of car models in our system, I don't want to load them all to a page, then , let a user to choose specific car models, it would be better to use ajax call to get car model by car brand , car series. the user choose a sub collection of items , post these selected to server.
In the form type ,I add a form field like this below, as we know, if I don't set its option choices as empty array, the entity field will get all car models , which will result in huge performance penalty.
->add('applicableModels', 'entity', array(
'class' => 'VMSP\CarBundle\Entity\CarModel',
'choices'=>array(),
'multiple'=>true,
'property_path' => "modelName",
'label' => 'vmsp_product.product.form.applicable_model',
)
)
So, how do you add a sub set of items from a big collection , and assign these selected items to entity type?
Upvotes: 0
Views: 1074
Reputation: 4265
The simple answer is that you can define a custom query builder for each element, you add to the form, i.e.
$data = $builder->getData();
\\...
->add('applicableModels', 'entity', array(
'class' => 'VMSP\CarBundle\Entity\CarModel',
'multiple' => true,
'property_path' => "modelName",
'label' => 'vmsp_product.product.form.applicable_model',
'query_builder' => function (EntityRepository $er) use ($data) {
$qb = $er->createQueryBuilder('e')
->where('e.manufacturer IN (:manufacturer)')
->setParameter('manufacturer', $data['manufacturer']);
return $qb->orderBy('e.name');
},
))
So you may have a sort of a "wizard" where user select a manufacturer, the page reloads, and the cars shown are only a subset.
In a very similar situation I ended up doing things a little differently, though. In the form, the choices are set to an empty array. On frontend, the options are filled via Ajax calling a separate API. Then on the form "pre-submit" event, I fill the field with the selected option.
$builder->addEventListener(
FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
if (!empty($data['applicable_model'])) {
$form->add('applicable_model', 'entity', array(
'class' => 'VMSP\CarBundle\Entity\CarModel',
'query_builder' => function (EntityRepository $er) use ($data) {
$qb = $er->createQueryBuilder('e')
->where('e.id IN (:applicable_model)')
->setParameter('applicable_model', $data['applicable_model']);
return $qb;
},
));
}
Update: I learned that the addEventListener part can probably be replaced by a DataTransforme instead, see https://stackoverflow.com/a/31938905/410761
Upvotes: 2