Symfony向Fork EventListener添加新字段

问题描述 投票:0回答:1

我正在尝试创建以下内容:我有一个带有下拉列表的表单(立即,滚动,输出,超时)。我希望当我的用户选择'timeout'=>时,我可以立即向他/她显示上面的新文件(使用父字段的一些设置)。

我试着做以下事情:

我的表格:

$formBuilder = $this->createFormBuilder($formSettings)
        ->add('trigger', ChoiceType::class, [
            'expanded' => false,
            'multiple' => false,
            'choices' => array_flip(FormSettings::TRIGGERS),
        ])
        ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            /** @var FormSettings $data */
            $data = $event->getData();
            /** @var FormInterface $form1 */
            $formInterface = $event->getForm();

            if ($data->getTrigger() === 400) {
                $formInterface->add('triggerSetting', TextType::class);
            }
        });

但是当我尝试选择“超时”时,没有任何反应。怎么了?

非常感谢!

forms symfony addeventlistener
1个回答
1
投票

使用AJAX示例进行动态表单修改

https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms

SRC /表/类型/ SportMeetupType.php

namespace App\Form\Type;

use App\Entity\Sport;
use Symfony\Component\Form\FormInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
// ...

class SportMeetupType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('sport', EntityType::class, array(
                'class'       => 'App\Entity\Sport',
                'placeholder' => '',
            ));
        ;

        $formModifier = function (FormInterface $form, Sport $sport = null) {
            $positions = null === $sport ? array() : $sport->getAvailablePositions();

            $form->add('position', EntityType::class, array(
                'class' => 'App\Entity\Position',
                'placeholder' => '',
                'choices' => $positions,
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. SportMeetup
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getSport());
            }
        );

        $builder->get('sport')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                // It's important here to fetch $event->getForm()->getData(), as
                // $event->getData() will get you the client data (that is, the ID)
                $sport = $event->getForm()->getData();

                // since we've added the listener to the child, we'll have to pass on
                // the parent to the callback functions!
                $formModifier($event->getForm()->getParent(), $sport);
            }
        );
    }

    // ...
}

SRC /控制器/ MeetupController.php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\SportMeetup;
use App\Form\Type\SportMeetupType;
// ...

class MeetupController extends Controller
{
    public function create(Request $request)
    {
        $meetup = new SportMeetup();
        $form = $this->createForm(SportMeetupType::class, $meetup);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            // ... save the meetup, redirect etc.
        }

        return $this->render(
            'meetup/create.html.twig',
            array('form' => $form->createView())
        );
    }

    // ...
}

模板/聚会/ create.html.twig

{{ form_start(form) }}
{{ form_row(form.sport) }}    {# <select id="meetup_sport" ... #}
{{ form_row(form.position) }} {# <select id="meetup_position" ... #}
{# ... #}
{{ form_end(form) }}

<script>
var $sport = $('#meetup_sport');
// When sport gets selected ...
$sport.change(function() {
  // ... retrieve the corresponding form.
  var $form = $(this).closest('form');
  // Simulate form data, but only include the selected sport value.
  var data = {};
  data[$sport.attr('name')] = $sport.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 ...
      $('#meetup_position').replaceWith(
        // ... with the returned one from the AJAX response.
        $(html).find('#meetup_position')
      );
      // Position field now displays the appropriate positions.
    }
  });
});
</script>
© www.soinside.com 2019 - 2024. All rights reserved.