2
votes

I followed symfony document http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms to do dynamic generation for dependent forms.

The type class:

class EtlType extends AbstractType
{

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('outTable', EntityType::class, array(
                'class'=>'TableBundle:TableList',
                'placeholder' => '',
                'choice_label'=>'tableName',
                'attr' => array('class' => 'form-control', 'style' => 'margin-bottom:10px; width:180px')));

        $formModifier = function (FormInterface $form, TableList $tableList = null) {
            $fields = null === $tableList ? array() : $tableList->getFields();
            $form->add('outField', EntityType::class, array(
                'class'       => 'TableBundle:TableDesc',
                'placeholder' => '',
                'choices'     => $fields,
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                $data = $event->getData();
                $formModifier($event->getForm(), $data->getOutTable());
            }
        );

        $builder->get('outTable')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                $outTable = $event->getForm()->getData();
                $formModifier($event->getForm()->getParent(), $outTable);
            }
        );
    }
}

The twig template:

                    {{ form_start(form) }}
                    {{ form_row(form.outTable) }}
                    {{ form_row(form.outField) }}
                    {{ form_widget(form) }}
                    <input class="button button1 right" type="submit" value="Create" onclick="return confirm('Confirm Creation?')"/>
                    {{ form_end(form) }}
                    <script>
                        var $outTable = $('#etl_outTable');
                        $outTable.change(function() {
                            // ... retrieve the corresponding form.
                            var $form = $(this).closest('form');
                            // Simulate form data, but only include the selected outTable value.
                            var data = {};
                            data[$outTable.attr('tableName')] = $outTable.val();
                            // Submit data via AJAX to the form's action path.
                            $.ajax({
                                url : $form.attr('action'),
                                type: $form.attr('method'),
                                data : data,
                                success: function(html) {
                                    // Replace current position field ...
                                    $('#etl_outField').replaceWith(
                                            // ... with the returned one from the AJAX response.
                                            $(html).find('#etl_outField')
                                    );
                                }
                            });
                        });
                    </script>

I think I follow the steps in the document. But for the outField, it always has nothing to select. Can someone point out what's going wrong? Thanks so much.

1
maybe I suppose JavaScript isn't working? I'm new to this, hope some help thanks. - Kai Huang
Have yo figured out the issue? I'm having another issue. Catchable Fatal Error: Argument 1 passed to AcmeBundle\Form\ScheduleType::PIE10Bundle\Form\{closure}() must be an instance of AcmeBundle\Form\Symfony\Component\Form\Form, instance of Symfony\Component\Form\Form given, called in /var/www/Acme/api/src/AcmeBundle/Form/ScheduleType.php on line 61 and defined have any idea? - inckka

1 Answers

0
votes

You dont submit your whole form. try this:

$outTable.change(function() {
   // ... retrieve the corresponding form.
   var $form = $(this).closest('form');
   // Simulate form data, and include the whole form.
   var data = new FormData($form);
   // Submit data via AJAX to the form's action path.
   $.ajax({
      url : $form.attr('action'),
      type: $form.attr('method'),
      data : data,
      success: function(html) {
         // I'd rather replace the whole form
         $('#etl_outField').replaceWith(
         // ... with the returned one from the AJAX response.
         $(html).find('#etl_outField')
      );
      }
   });
});