首页 > 解决方案 > Symfony 表单提交后提交填充实体类型

问题描述

我想用这种结构制作一个“两级”动态 symfony 表单:

  1. 技能卡:实体类型
  2. 会话:实体类型
  3. 转:ChoiceType

当我选择技能卡时,我填充会话字段,选择会话后我填充回合字段。

此刻我做了这个

$builder->add('skillCard', EntityType::class, [
        'class' => SkillCard::class,
        'choices' => $student->getSkillCards()->filter(function (SkillCard $skillCard) {
            return $skillCard->getStatus() != EnumSkillCard::EXPIRED &&
                count($skillCard->getSkillCardModulesNotPassed()) > 0;
        }),
        'placeholder' => ''
    ]);
$builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function (FormEvent $formEvent) {
            /** @var Booking */
            $data = $formEvent->getData();
            $this->addSessionField($formEvent->getForm(), $data->getSkillCard());
            $this->formModifierBySession($formEvent->getForm(), $data->getSession());
        }
    );
$builder->get('skillCard')->addEventListener(
        FormEvents::POST_SUBMIT,
        function (FormEvent $formEvent) {
            $skillCard = $formEvent->getForm()->getData();
            $this->addSessionField($formEvent->getForm()->getParent(), $skillCard);
        }
    );

protected function addSessionField(FormInterface $form, SkillCard $skillCard = null)
{
    $builder = $form->getConfig()->getFormFactory()->createNamedBuilder('session', EntityType::class, null, [
        'auto_initialize' => false,
        'class' => Session::class,
        'placeholder' => '',
        'query_builder' => function (EntityRepository $er) use ($skillCard) {
            $qb = $er->createQueryBuilder('s');
            if (is_null($skillCard)) {
                $qb->where('s = 0');
            } else {
                $qb->where('s.certification = :id')
                    ->andWhere('s.subscribeExpireDate > :date')
                    ->setParameter('id', $skillCard->getCertification())
                    ->setParameter('date', new DateTime());
            }
            return $qb;
        },
    ]);

    $builder->addEventListener(
        FormEvents::POST_SUBMIT,
        function (FormEvent $formEvent) {
            $session = $formEvent->getForm()->getData();
            $this->formModifierBySession($formEvent->getForm()->getParent(), $session);
        }
    );
    $form->add($builder->getForm());
}

protected function formModifierBySession(FormInterface $form, Session $session = null)
{
    $form->add('turn', ChoiceType::class, [
        'choices' => is_null($session) ? [] : range(0, $session->getRounds()),
    ]);
}

这是 javascript 代码(用于 ajax 调用):

$(document).ready(function () {
    const $skillCard = $('#booking_skillCard');
    const $form = $('form[name = "booking"]');

    $skillCard.change(function () {
        sendAjax($skillCard, $form, function (html) {
            replaceFormField('#booking_module', html);
            replaceFormField('#booking_session', html);
            sessionField($form);
        });
    });
});

function sessionField($form) {
    const $session = $('#booking_session');
    $session.change(function () {
        sendAjax($session, $form, function (html) {
            replaceFormField('#booking_turn', html);
        });
    });
}

function sendAjax($jObj, $form, successCallBack) {
    let data = {};
    data[$jObj.attr('name')] = $jObj.val();
    console.log($form);
    $.ajax({
        url: $form.prop('action'),
        type: $form.prop('method'),
        data: data,
        success: successCallBack
    })
}

function replaceFormField(selector, html) {
    $(selector).replaceWith(
        $(html).find(selector)
    );
}

当我选择技能卡时,没有问题,但是当我选择会话时,我得到一个 TrasformationFailedException:“无法反转属性路径“会话”的值:选择“x”不存在或不唯一”,所以转场未填充,因为$session = $formEvent->getForm()->getData();为空。

任何建议都值得赞赏。

标签: phpformssymfony

解决方案


推荐阅读