title: Symfony Dynamic Forms with ajax
body: <p>I am trying to do a form in which I will be able to add as many product options as I want (so collection with prototype). For this I need two fields, one Option Definition and second with Option values.</p>
  
  <p>I have got entities like: Product, Options, Options Definitions and Product Options Join (I decided to use two ManyToOne instead of one ManyToMany, so in Product Definitions Join I got ManyToMany to Options and ManyToMany to Products).</p>
  
  <p>When I am adding option to product, I want first to choose Option Definition and then update select box with Options. This is everything working alright, but the problem is that when I want to edit product then it is showing me default option definitions. For example, when I was creating product I added product with option definition size and the value of size was 40. When I going to edit product I am getting option definition color and size 40.</p>
  
  <p>Here is on pictures what I mean:
  <img src="https://i.stack.imgur.com/ObR5P.jpg" alt="enter image description here"></p>
  
  <p>And in second row there should be a Size instead of Colour.</p>
  
  <p>Here you can also see how I got connected tables:
  <img src="https://i.stack.imgur.com/4ZhVe.jpg" alt="enter image description here"></p>
  
  <p><strong>ProductOptionsType Class</strong></p>
  
  <pre><code>public function buildForm(FormBuilderInterface $builder, array $options)
  {
  
      $factory = $builder-&gt;getFormFactory();
  
      $builder
          -&gt;add('optiondefinitions', 'entity', array(
                                  'mapped' =&gt; false,
                                  'class' =&gt; 'ePOS\ProductsBundle\Entity\OptionsDefinitions',
                                  'query_builder' =&gt; function ($repository) { return $repository-&gt;createQueryBuilder('p')-&gt;orderBy('p.name', 'ASC'); },
                                  'property' =&gt; 'name',
                                  'attr' =&gt; array('class' =&gt; 'option-definitions'))) 
          ;
  
      $refreshOptions = function ($form, $option) use ($factory) {
          $form-&gt;add($factory-&gt;createNamed('options', 'entity', null, array(
              'class'         =&gt; 'ePOS\ProductsBundle\Entity\Options',
              'property'      =&gt; 'value',
              'label'         =&gt; false,
              'auto_initialize' =&gt; false,
              'query_builder' =&gt; function ($repository) use ($option) {
                                     $qb = $repository-&gt;createQueryBuilder('options')
                                                      -&gt;innerJoin('options.optionDefinition', 'optionDefinitions');
  
                                     if($option instanceof OptionsDefinitions) {
                                         $qb = $qb-&gt;where('options.optionDefinition = :optiondefinitions')
                                                  -&gt;setParameter('optiondefinitions', $option);
                                     } elseif(is_numeric($option)) {
                                         $qb = $qb-&gt;where('options.id = :option_id')
                                                  -&gt;setParameter('option_id', $option);
                                     } else {
                                         $qb = $qb-&gt;where('options.optionDefinition = 1');
                                     }
                                     return $qb;
                                 }
               )));
      };
  
      $builder-&gt;addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($refreshOptions, $factory) {
          $data = $event-&gt;getData();
          $form = $event-&gt;getForm();
          if (null === $data) {
              return ;
          }
  
          $refreshOptions($form, $data-&gt;getOptions()-&gt;getOptionDefinition());
      });
  
      $builder-&gt;addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($refreshOptions) {
          $form = $event-&gt;getForm();
          $data = $event-&gt;getData();
  
          if($data == null)
             $refreshOptions($form, null); //As of beta2, when a form is created setData(null) is called first
  
          if($data instanceof Location) {
              $refreshOptions($form, $data-&gt;getOptions()-&gt;getOptionDefinition());
              }
      });
  
      $builder-&gt;addEventListener(FormEvents::PRE_BIND, function (DataEvent $event) use ($refreshOptions) {
          $form = $event-&gt;getForm();
          $data = $event-&gt;getData();
  
          if(array_key_exists('optiondefinitions', $data)) {
              $refreshOptions($form, $data['optiondefinitions']);
          }
      });
  }
  </code></pre>