Варианты обновления Symfony Form EntityType в зависимости от поиска

основная информация: Визуализация

В TrainingType.php, который создает форму:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('trainer', EntityType::class, [
            'class' => 'AppBundle:Trainer',
            'choices' => $training->trainer_list ?? null,
            'label' => 'seminar.trainer.form.trainer.label',
            'placeholder' => 'form.trainer.placeholder',
            'required' => false,
    ]);
    $builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData']); // update 'trainer'
    $builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']); // update 'trainer'
}

в ветке:

{% if field == 'trainer' %}
    {{ form_row(attribute(form, field), {'id': 'trainer'}) }}
{% endif %}

JavaScript (тест):

<script>
    $(document).ready(() => {
        function trainer_changed() {
            let trainer = $('#trainer');
            jQuery.ajax({
                url: '{{ path('trainer_select_ajax') }}',
                type: 'GET',
                data: {
                    //this is the id of the selected option, not the search term
                    search: trainer.val() 
                },
                success: function (html) {
                    let trainer = $('#trainer');
                    let newchoices = $(html).find('#trainer');
                    trainer.replaceWith(
                        newchoices  // works
                    );
                }
            });
        }
        // when a new option is selected, not what I want
        $('#trainer').change(trainer_changed);
        $('#trainer').on('input', trainer_changed);  // no effect
    });
</script>

Список выбора должен обновляться при вводе «foo». В настоящее время он не показывает выбираемых параметров, потому что не находит результатов для «foo» в предварительно загруженных данных, даже если ajax-вызов на сервер отправил «foo», он вернул бы для него результаты.

Итак, мой вопрос заключается в том, как поместить прослушиватель «oninput» или «onchange» в поле поиска, как показано на рисунке. Когда я начинаю печатать, он должен получить обновленный список выбора с сервера через вызов ajax и мгновенно заменить его в раскрывающемся списке.

Я еще не смог даже выбрать поле поиска. Документация Symfony на https://symfony.com/doc/3.4/form/dynamic_form_modification.html совсем не помогает, потому что все эти примеры событий запускаются только тогда, когда что-то действительно выбрано, а не при простом вводе поискового запроса.

Бонус, хотя я думаю, у меня есть идея, как это сделать, просто переформатировав записи с помощью javascript, я хотел бы иметь возможность отображать каждую опцию как «Фамилия, Имя - Должность - Цена» вместо «Фамилия, Имя». ' (метод __toString() объекта Trainer), который использует сам Symfony. Итак, я думаю, я бы хотел, чтобы Symfony использовал метод, отличный от __toString() для этой конкретной строки формы.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
1 103
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

«Решение» состояло в том, чтобы сначала дождаться открытия раскрывающегося списка, а затем прикрепить прослушиватель oninput к полю ввода.

<script>
    $(document).ready(() => {
        function trainer_changed() {
            let input = event.target;
            jQuery.ajax({
                url: '{{ path('trainer_select_ajax') }}',
                type: 'GET',
                data: {
                    search: input.value
                },
                success: function (trainers) {
                    let trainer = $('#trainer')[0];
                    trainer.options.length = 1;  // reset all options, except for the default
                    trainers.forEach((tr, idx) => {
                        trainer[idx+1] = new Option(tr.name, tr.id);
                    });
                }
            });
        }
        function select_opened() {
            let trainercontainer = $('select2-container select2-container--default select2-container--open');
            if (trainercontainer) {
                let trainerinput = trainercontainer.prevObject[0].activeElement;  // input field
                trainerinput.oninput = trainer_changed;
            }
        }
        $('#select2-trainer-container').click(select_opened);
    });
</script>

Чтобы мгновенно обновить отображаемый раскрывающийся список, используйте $('input.select2__field').trigger('change');

Другие вопросы по теме