Note that there are some explanatory texts on larger screens.

plurals
  1. POsymfony2 chained selectors
    text
    copied!<p>I have three entities: Country, State and City with the following relationships:</p> <p><a href="http://i39.tinypic.com/15gc85u.png">Image http://i39.tinypic.com/15gc85u.png</a></p> <p>When creating a City, I want two selectors, one for the Country and one for the State where the city belongs. These two selectors need to be chained so changing the Country will "filter" the States shown in the other selector.</p> <p>I found a <a href="http://aulatic.16mb.com/wordpress/2011/08/symfony2-dynamic-forms-an-event-driven-approach/">tutorial</a> showing how to do this using Form Events but their example it's not quite my case. My entity City it's not directly related to the Country entity (they are indirectly related through State) so, when setting the country field in the City form (inside the class CityType), I'm forced to declare that field as <code>'property_path'=&gt;false</code> as you can see in the code below:</p> <pre class="lang-php prettyprint-override"><code>class CityType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder-&gt;add('country', 'entity', array( 'class'=&gt;'TestBundle:Country', 'property'=&gt;'name', 'property_path'=&gt;false //Country is not directly related to City )); $builder-&gt;add('name'); $factory = $builder-&gt;getFormFactory(); $refreshStates = function ($form, $country) use ($factory) { $form-&gt;add($factory-&gt;createNamed('entity', 'state', null, array( 'class' =&gt; 'Test\TestBundle\Entity\State', 'property' =&gt; 'name', 'query_builder' =&gt; function (EntityRepository $repository) use ($country) { $qb = $repository-&gt;createQueryBuilder('state') -&gt;innerJoin('state.country', 'country'); if($country instanceof Country) { $qb-&gt;where('state.country = :country') -&gt;setParameter('country', $country); } elseif(is_numeric($country)) { $qb-&gt;where('country.id = :country') -&gt;setParameter('country', $country); } else { $qb-&gt;where('country.name = :country') -&gt;setParameter('country', "Venezuela");; } return $qb; } ))); }; $builder-&gt;addEventListener(FormEvents::PRE_SET_DATA, function (DataEvent $event) use ($refreshStates) { $form = $event-&gt;getForm(); $data = $event-&gt;getData(); if($data == null) return; if($data instanceof City){ if($data-&gt;getId()) { //An existing City $refreshStates($form, $data-&gt;getState()-&gt;getCountry()); }else{ //A new City $refreshStates($form, null); } } }); $builder-&gt;addEventListener(FormEvents::PRE_BIND, function (DataEvent $event) use ($refreshStates) { $form = $event-&gt;getForm(); $data = $event-&gt;getData(); if(array_key_exists('country', $data)) { $refreshStates($form, $data['country']); } }); } public function getName() { return 'city'; } public function getDefaultOptions(array $options) { return array('data_class' =&gt; 'Test\TestBundle\Entity\City'); } } </code></pre> <p>The problem is that when I try to edit an existing City, the related Country is not selected by default in the form. If I remove the line <code>'property_path'=&gt;false</code> I get (not surprisingly) the error message:</p> <p><strong>Neither property "country" nor method "getCountry()" nor method "isCountry()" exists in class "Test\TestBundle\Entity\City"</strong></p> <p>Any ideas?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload