Symfony 4 Form - Ajax 选择人群

kir*_*net 2 php forms ajax symfony

有没有办法使用ajax异步填充表单ChoiceType(下拉列表)?

基本上我想做的是:

简短描述:简单的预订系统。

详细描述:

当用户在“preferredDate”中使用日期选择器(或其他)选择日期时,ajax 调用将检查所选日期是否有可用时间段,并用时间填充“availableTimes”ChoiceType(下拉列表)(例如:10:00) 、10:30、11:00、11:30 等)。

可用时间不在数据库中。

我的表格:

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('preferredDate', DateType::class, [
                'widget' => 'single_text',
                'input' => 'datetime',
                'format' => 'dd.MM.yyyy',
            ])
            ->add('availableTimes', ChoiceType::class, ['required' => false]);
    }
Run Code Online (Sandbox Code Playgroud)

我的JS:

$(".reservation-date").change(function () {
        $.ajax({
            type: "GET",
            dataType: "json",
            url: "{{URL}}",
            data: {},
            success: function (data) {
                $(".reservation-times").empty();
                $.each(data, function (key, value) {
                    //populate availabletimes dropdown
                    let disabled = (value.disabled === true ? "disabled" : '');
                    $(".reservation-times").append('<option ' + disabled + ' value=' + value.time + '>' + value.time + '</option>');
                })
            }
            ,
            error: function (error) {
                console.log(error);
            }
        });
    })
Run Code Online (Sandbox Code Playgroud)

当我发送选定的时间时它起作用它会抛出错误“此值无效”

我做错了什么?

你会怎样做?

编辑:没有验证集,但由于某种原因,它仍然想验证 ChoiceType ... 编辑2:阅读所有旧的 SF2 答案,但所有这些都是关于使用事件发送表单 2+ 次。

EDIT3:来自 _profiler 的错误:

在此输入图像描述

在此输入图像描述

kir*_*net 5

我终于成功了。添加了EventListener,其他基本一样。

我的表格:

public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('preferredDate', DateType::class, [
                'widget' => 'single_text',
                'input' => 'datetime',
                'format' => 'dd.MM.yyyy',
            ])
            ->add('availableTimes', ChoiceType::class)
            ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {

                // get the form from the event
                $form = $event->getForm();
                $formOptions = $form->getConfig()->getOptions();

                //helpers
                $availableTimeHandler = $formOptions['availableTimeHelper'];

                // get the form data, that got submitted by the user with this request / event
                $data = $event->getData();

                //get date
                $preferredDate = $data['preferredDate'];

                // get the availableTimes element and its options
                $fieldConfig = $form->get('availableTimes')->getConfig();
                $fieldOptions = $fieldConfig->getOptions();


                /**
                 * Getting available times logic is here, 
                 * not showing because it's irrelevant to the issue.
                 *
                 * $times array example: 
                 * [
                 *      ['time' => '10:00', 'disabled' => false],
                 *      ['time' => '11:00', 'disabled' => true],
                 *      ['time' => '12:00', 'disabled' => true],
                 * ]
                 */

                $choices = [];
                foreach ($times as $time) {
                    $choices[] = [$time['time'] => $time['time']];
                }

                //update choices
                $form->add('availableTimes', ChoiceType::class,
                    array_replace(
                        $fieldOptions, [
                            'choices' => $choices
                        ]
                    )
                );
            });


    }
Run Code Online (Sandbox Code Playgroud)

我的JS:

$(".reservation-date").change(function () {
        $.ajax({
            type: "GET",
            dataType: "json",
            url: "{{URL}}",
            data: {},
            success: function (data) {
                $(".reservation-times").empty();
                $.each(data, function (key, value) {
                    //populate availabletimes dropdown
                    let disabled = (value.disabled === true ? "disabled" : '');
                    $(".reservation-times").append('<option ' + disabled + ' value=' + value.time + '>' + value.time + '</option>');
                })
            }
            ,
            error: function (error) {
                console.log(error);
            }
        });
    })
Run Code Online (Sandbox Code Playgroud)

建议或提示将不胜感激。