Reputation: 4207
I've a Form with 1 EntityType field that must contain choices depending of a second EntityType field that is not mapped in the first entity, like this :
ServicePlaceType.php :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('placetype', EntityType::class, array(
"class" => "AppBundle:PlaceType",
"choice_label" => "place",
"mapped" => false
))
->add('idplace', EntityType::class, array(
"class" => "AppBundle:Place",
"choice_label" => "place"
))
->add('...');
The tables
+---------+--------------+---------------+-----------+
| Service | ServicePlace | Place | PlaceType |
+---------+--------------+---------------+-----------+
| | id | | |
+---------+--------------+---------------+-----------+
| | idplace > | < id | |
+---------+--------------+---------------+-----------+
| id > | < idservice | idPlaceType > | < id |
+---------+--------------+---------------+-----------+
| service | | place | placetype |
+---------+--------------+---------------+-----------+
So, when i select a PlaceType i want that the Place select shows only the places where idplacetype match the PlaceType id.
I tried in javascript, with an onChange event on the PlaceType select, that filter the Place options according to the PlaceType actual value, but i don't know how to fetch the PlaceType property of the Place in the formType. I tried that kind of things, but it doesn't work
->add('idplace', EntityType::class, array(
"class" => "AppBundle:Place",
"choice_label" => "place",
"attr" => array("placeType" => $this->getPlaceType()), // nor like that
))
->add('idplace', EntityType::class, array(
"class" => "AppBundle:Place",
"choice_label" => "place",
"attr" => array("placeType" => function ($place) {
return $place->getPlaceType();
}), // neither like that
))
Does someone know how to fetch these datas ? Or how to dynamically filter options by another way ?
Thanks for the help !
Upvotes: 3
Views: 2156
Reputation: 9585
You can do it with jquery library a little more simpler:
First, we change the builder a bit for render the place type id into <option data-type="...">
using the choice_attr
option:
$builder
->add('placetype', EntityType::class, array(
"class" => "AppBundle:PlaceType",
"mapped" => false
))
->add('idplace', EntityType::class, array(
"class" => "AppBundle:Place",
'choice_attr' => function ($place) {
// output: <option data-type="...">...</option>
return array('data-type' => $place->getPlaceType()->getId());
},
))
Next, in you template:
{# ... #}
{{ form(form) }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script>
// when the 1st <select> was changed, then update the 2nd
// from current value and data-type option attribute.
$(document).on('change', '#form_placetype', function () {
var $idplace = $('#form_idplace'),
// current value
placetype = $(this).val(),
// select available options from current value
$available = $idplace.find('option[data-type="' + placetype + '"]');
// deselect when the 1st <select> has changed.
$idplace.val('');
// hide no available options from current value
$idplace.find('option').not($available).hide();
// show available options from current value
$available.show();
});
// Update 2nd <select> on page load.
$('#form_placetype').trigger('change');
</script>
Upvotes: 2