основная информация: Визуализация
В 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() для этой конкретной строки формы.






«Решение» состояло в том, чтобы сначала дождаться открытия раскрывающегося списка, а затем прикрепить прослушиватель 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');