Reputation: 1812
For some unknown reason, the EntityType form field will not display the selected option on submit, even though the name of the column matches and data passes.
I've created a form that I'm using to select some values that will filter a list of products.
<?php namespace AppBundle\Filter;
use AppBundle\Entity\ProductCategory;
use AppBundle\Repository\ProductCategoryRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ProductFilterType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', null, [
'required' => false,
'label' => 'SKU'
])
->add('productCategory', EntityType::class,
array(
'class' => ProductCategory::class,
'choice_label' => 'name',
'choice_value' => 'id',
'placeholder' => '',
'label_attr' => array('title' => 'Category for this product'),
'query_builder' => function (ProductCategoryRepository $v) {
return $v->createQueryBuilder('v')
->orderBy('v.name',' ASC');
}
))
->add('name', null, [
'required' => false,
])
->add('description', null, [
'required' => false,
])
;
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'app_bundle_product_filter_type';
} }
The form renders as expected, and it submits a post to the same URL, which filters based on the value received from the request.
That works ok.
However, when the form is re-rendered, the option that was selected before the form filter submission is no longer selected. All other inputs are repopulating.
I did notice that when I'm working with a form that is bound to an Entity (ie: Editting and saving the entity) and using the ConfigureOptions method to set the data class, that the EntityType form field works as expected. However, I need it to work in this case where the overall form is not bound to an Entity.
EDIT: Doing these steps worked for me...but it seems a bit odd.
Injected entity manager into the form constructor:
public $em;
public function __construct(EntityManager $em) {
$this->em = $em;
}
Then updated the EntityType form field to get the object based on the array value:
->add('productCategory', EntityType::class,
array(
'class' => ProductCategory::class,
'choice_label' => 'name',
'choice_value' => 'id',
'placeholder' => '',
'label_attr' => array('title' => 'Category for this product'),
'data' => $this->em->getReference("AppBundle:ProductCategory",
isset($options['data']['productCategory']) ? $options['data']['productCategory'] : 0),
'query_builder' => function (ProductCategoryRepository $v) {
return $v->createQueryBuilder('v')
->orderBy('v.name',' ASC');
}
))
...
Upvotes: 3
Views: 3703
Reputation: 107
Another solution is using a Data Transformer.
Remove the data
attribute from the productCategory
type, and add a data transformer to the end of the build
method:
$builder->get('productCategory')
->addModelTransformer(new CallbackTransformer(
function ($id) {
if (!$id) {
return;
}
return $this->em->getRepository('AppBundle:ProductCategory')->find($id);
},
function($category) {
return $category->getId();
}
));
If you use the same transformer in multiple places, you can extract it into its own class.
Upvotes: 2
Reputation: 1630
My workaround was like this ... pass data and entity manager to formType.
$form = $this->createForm(new xxxType($this->get('doctrine.orm.entity_manager')), xxxEntity, array(
'method' => 'POST',
'action' => $this->generateUrl('xxxurl', array('id' => $id)),
'selectedId' => xxxId,
));
setDefaultOptions in form Type initialize as an empty array for selectedId
$resolver->setDefaults(array(
'data_class' => 'xxx',
'selectedId' => array()
));
and in builder
->add('productCategory', EntityType::class,
array(
'class' => ProductCategory::class,
'choice_label' => 'name',
'choice_value' => 'id',
'placeholder' => '',
'label_attr' => array('title' => 'Category for this product'),
'query_builder' => function (ProductCategoryRepository $v) {
return $v->createQueryBuilder('v')
->orderBy('v.name',' ASC');
},
'data'=>$this->em->getReference("xxx",$options['selectedId'])
))
for more details, you can see this answer Symfony2 Setting a default choice field selection
Upvotes: 0