Symfony表单-根据选择动态添加/删除字段

时间:2019-04-17 17:07:52

标签: javascript php html forms symfony

我正在尝试创建一个映射到“参与者”类型的实体的表单。参与者与“人”一对一关系。添加一个参与者,我首先要提供选择数据库中已经存在的人的选项,如果不存在合适的人,请使用参与者表单创建该人。

如果我用两个页面/表格来完成此操作。第一个尝试选择一个现有的人,否则用不同的形式打开一个新页面。 第一页:

$form->add('person', AjaxEntityType, [ // EntityType but with select2 ajax
    'class' => Person::class,
    'remote_route' => 'person_ajax_list'
]);

第二页:

$participant->setPerson(new Person());
$form->add('person', PersonType::class);
// adds PersonType fields to the Participant form

那很好,但是非常缓慢而且没有必要。我更希望同时显示两个字段,如果选择了PersonType表单字段(名字,姓氏,职务,公司,地址等),则这些字段将自动填充有persons数据。否则,如果未选择任何人员,并且使用输入的数据提交表单,则应创建一个新的人员并保存在数据库中。

可悲的是,不可能两次渲染“人物”,一次是下拉菜单,一次是PersonType表单。那么,如何在没有大量JavaScript的情况下实现自己想要的目标?

我当前的解决方案是使用JavaScript手动创建所有必填字段,并在人员下拉列表中的onchange事件上使用我通过另一个Ajax请求获得的人员数据填充它们,然后在表单的PRE_SUBMIT事件中,删除“人员”字段,然后再次将其添加为“人员类型”字段,检查输入的数据是对应于现有人员还是新人员,然后采取相应措施。必须有更好的解决方案,对吧?

不幸的是,事实证明表单事件基本上是没有意义的,因为不可能将事件侦听器附加到其中一个字段上的“更改”事件。

谢谢。

1 个答案:

答案 0 :(得分:0)

最终使用一个未映射的人员选择字段和javascript(使用ajax)自动更新数据来解决该问题。

参与者/add.twig:

{ width: 800px, height: 300px}

ParticipantController添加:

{% block javascripts %}

    <script type="text/javascript">

        $(document).ready(function () {
            function onTrainerChange() {
                let trainerId = $('#participant_person_choose').val();
                $.get(Routing.generate('person_data_ajax', { id: trainerId }), function (data) {
                    $('#participant_person_gender').val(data.gender);
                    $('#participant_person_title').val(data.title);
                    $('#participant_person_firstName').val(data.firstName);
                    $('#participant_person_lastName').val(data.lastName);
                    $('#participant_person_email').val(data.email);
                    $('#participant_person_telephone').val(data.telephone);
                    if (data.company) {
                        let company = $('#participant_person_company');
                        company.empty();
                        company.append(new Option(data.company.text, data.company.id));
                        company.val(data.company.id);
                        company.trigger('change');
                        // manipulate dom directly because of .select('data') bug with select2 >=4.0
                    }
                });
            };

            let trainer = $('#participant_person_choose');
            trainer.change(onTrainerChange);
        });

    </script>

{% endblock %}

PersonController Ajax:

    $participant = new Participant($seminar);
    $person = $participant->getPerson() ?? new Person();
    $participant->setPerson($person);
    $form = $this->createParticipantForm($participant)
        ->add('person_choose', AjaxEntityType::class, [
            'mapped' => false,
            'class' => Person::class,
            'remote_route' => 'person_select_ajax',
            'placeholder' => 'form.personCreate',
            'label' => 'form.person'
        ])
        ->add('person', PersonType::class);

    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {

        if ($form->get('reservation')->getData()) {
            $participant->setInterested();
        }

        $personEntered = $form->get('person')->getData();
        $personChosen = $form->get('person_choose')->getData();
        if ($personChosen) {
            $person = $personChosen;
            $person->setGender($personEntered->getGender());
            $person->setTitle($personEntered->getTitle());
            $person->setFirstName($personEntered->getFirstName());
            $person->setFirstName($personEntered->getLastName());
            $person->setCompany($personEntered->getCompany());
            $person->setEmail($personEntered->getEmail());
            $person->setTelephone($personEntered->getTelephone());
            $participant->setPerson($person);
        }

        $this->getDoctrine()->getManager()->persist($person);

        $this->getDoctrine()->getManager()->persist($participant);
    }

希望这可以帮助其他人。真的对Symfonys表格的数量感到失望。