Symfony3 Ajax 表单添加额外字段

Symfony3 Ajax Form Add Extra Field

AdminBundle\Form\CoreForm.php:

class CoreForm extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        /**
        Ajax Call : onSubmitAdd
        */
        $builder->add('set_core_doctrine_metadata_type', ChoiceType::class, array(
            'label' => 'Doctrine Metadata Cache Driver',
            'choices' => $this->getDoctrineAccelerator(),
            'empty_data' => 'array',
            'choice_translation_domain' => false,
            'attr' => array(
                'onSubmitAdd' => 'set_core_doctrine_metadata_host|set_core_doctrine_metadata_port'
            )
        ))

        /**
        Ajax Response : onSubmitAdd
        */
        $doctrineModify = function (FormInterface $form){
            $metaDataDriver = $form->get('set_core_doctrine_metadata_type')->getData();

            if (!$form->isValid()) {
                if ($metaDataDriver == 'memcache' || $metaDataDriver == 'memcached'){
                    $form->add('set_core_doctrine_metadata_host', TextType::class, array(
                        'label' => 'Doctrine Metadata Cache Host',
                    ))
                    ->add('set_core_doctrine_metadata_port', IntegerType::class, array(
                        'label' => 'Doctrine Metadata Cache Port',
                    ));
                }
            }
        };

        $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) use ($doctrineModify){
            $form = $event->getForm();
            $doctrineModify($form);
        });
    }
}

表单类型: 表格工作顺利。但是它不允许新字段。

jQuery Ajax 代码:

$(document).on('change', '[onSubmitAdd]', function () {
    // Get Form
    form = $(this).closest('form');

    // Send Data
    var data = {};
    data[$(this).attr('name')] = $(this).val();

    // Html Block
    formGroup = $(this).closest('.form-group');
    getFormGroup = $(this).attr('onSubmitAdd');
    getFormGroup = getFormGroup.split('|');

    $.ajax({
        url: form.attr('action'),
        type: form.attr('method'),
        data: data,
        success: function (data) {
            addContent = "";

            // Get Items
            $.each(getFormGroup, function (index, item) {
                dt = $(data.content.body).find('.' + item).html();
                if (typeof dt != 'undefined'){
                    addContent = addContent + '<div class="form-group">'+ dt +'</div>';
                }
            });

            // Replace or Add
            if (formGroup.next().hasClass('onSubmitAdded')){
                formGroup.next().html(addContent);
            } else {
                formGroup.after('<div class="onSubmitAdded">'+ addContent +'</div>');
            }
        }
    });
});

问题: Ajax 系统运行顺利。 但是提交表单时,错误代码"This form should not contain extra fields"

为了能够接受额外提交的选项,您必须将它们添加到 PRE_SUBMIT Event 的表单中:

 class FooType extends AbstractType
 {
     public function buildForm(FormBuilderInterface $builder, array $options)
     {
         $builder
             ->add('tag', ChoiceType::class, array('choices'=>array()))
         ;

         $builder->addEventListener(
             FormEvents::PRE_SUBMIT,
             function(FormEvent $event){
                 // Get the parent form
                 $form = $event->getForm();

                 // Get the data for the choice field
                 $data = $event->getData()['tag'];

                 // Collect the new choices
                 $choices = array();

                 if(is_array($data)){
                     foreach($data as $choice){
                         $choices[$choice] = $choice;
                     }
                 }
                 else{
                     $choices[$data] = $data;
                 }

                 // Add the field again, with the new choices :
                 $form->add('tag', ChoiceType::class, array('choices'=>$choices));
             }
         );
     }
 }

为了避免出现“Notice: Array to string conversion”,考虑将所有字段数组参数复制到 $form 的新字段中,例如,如果你有 'multiple' => true$builder 'tag' 中也把它放在 $form 'tag'