Symfony Forms - динамически добавлять / удалять поля в зависимости от выбора - PullRequest
0 голосов
/ 17 апреля 2019

Я пытаюсь создать форму, которая сопоставляется с сущностью типа «Участник».Участник находится в личных отношениях с «человеком».Добавляя участника, я хочу сначала дать возможность выбрать человека, уже находящегося в базе данных, и, если нужного не существует, создать этого человека с помощью формы участника.

Это работает, если я делаю это сдве страницы / формы.Первый пытается выбрать существующего человека, в противном случае откройте новую страницу с другой формой.Первая страница:

$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 (имя, фамилия, название, компания, адрес и т. Д.) Автоматически заполняются данными о людях, если они выбраны.В противном случае, если не выбрано ни одного сотрудника, а форма отправлена ​​с введенными данными, необходимо создать и сохранить нового сотрудника в базе данных.

К сожалению, невозможно дважды отобразить «лицо», один раз в виде раскрывающегося списка.и один раз как форма PersonType.Итак, как мне добиться того, чего я хочу, без сюрреалистического количества JavaScript?

Моим текущим решением было бы вручную создать все необходимые поля с помощью JavaScript и заполнить их данными о персонале, которые я получу с помощью другогоAjax-запрос на событие onchange раскрывающегося лица, затем в событии PRE_SUBMIT формы удалите поле person и добавьте его снова в качестве поля PersonType, проверьте, соответствуют ли введенные данные существующему человеку или новому, итогда действуй соответственно.Должно быть лучшее решение, верно?

События форм, к сожалению, оказались в большинстве случаев бессмысленными, поскольку невозможно прикрепить прослушиватель событий к событию 'change' в одном из полей.

Спасибо.

1 Ответ

0 голосов
/ 20 апреля 2019

Закончилось решение проблемы с помощью поля выбора лица без отображения и javascript для автоматического обновления данных (с использованием ajax).

участник / add.twig:

{% 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 %}

УчастникКонтроллер добавляет:

    $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);
    }

PersonController Ajax:

    /**
     * @Route("/{id}/data", name="person_data_ajax", methods={"GET"}, options={"expose": true})
     */
    public function dataAjax(Person $person, PhoneNumberHelper $phonenumberHelper)
    {
        $arr = [
            'id' => $person->id,
            'gender' => $person->getGender(),
            'title' => $person->getTitle(),
            'firstName' => $person->getFirstName(),
            'lastName' => $person->getLastName(),
            'email' => $person->getEMail(),
            'telephone' => $person->getTelephone() ? $phonenumberHelper->format($person->getTelephone(), PhoneNumberFormat::NATIONAL) : null,
            'company' => $person->getCompany() ? [
                'id' => $person->getCompany()->id,
                'text' => $person->getCompany()->__toString()
            ] : null
        ];

        return new JsonResponse($arr);
    }

Надеюсь, это может помочь кому-то еще. Действительно разочарован тем, насколько ограничены формы Symfonys.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...