Форма Symfony3 Ajax Добавить дополнительное поле

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 работает бесперебойно. Но при отправке формы появляется код ошибки "Эта форма не должна содержать лишних полей"


person Ramazan APAYDIN    schedule 11.08.2016    source источник


Ответы (1)


Чтобы иметь возможность принимать дополнительные отправленные варианты, вы должны добавить их в свою форму на странице Событие PRE_SUBMIT :

 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 ' > также поместите его в $form 'tag'

person Alsatian    schedule 11.08.2016