Моя задача - отправить контактную форму через AJAX, а затем показать «Спасибо за отправку!» сообщение, загруженное в том месте, где была форма. Поэтому мне нужно изменить существующую контактную форму.
Я нашел несколько примеров, как проверять поля формы с помощью AJAX в D8, но я не могу найти ни одного примера, как реализовать отправку формы ajax и загрузить некоторое содержимое через AJAX.
Как я могу реализовать свою задачу? Как мне изменить форму контакта, чтобы добавить необходимые функции?
Ответы:
При работе с ajax в формах вы должны иметь в виду следующее:
узнайте, перестраиваете ли вы всю форму или только ее часть, и оберните форму соответствующим образом элементом div с атрибутом ID, который вы будете использовать в определении #ajax для запускающего элемента как «обертка». Используйте атрибуты #prefix и #suffix для этого (
$form['#prefix'] = '<div id="myform-ajax-wrapper">'; $form['#suffix'] = '</div>';
). Также имейте в виду, что если у вас есть пользовательский шаблон для вашей формы, чтобы НЕ отображать префикс и суффикс в этом случае ({{ form|without('#prefix', '#suffix') }}
), в противном случае они будут отображаться дважды - вашим шаблоном, а также оболочкой темы формы. Вы не можете предотвратить это, установив #theme_wrappers в пустой массив, поскольку шаблон формы содержит фактический HTML-элемент формы.в вашем обработчике отправки ajax верните всю форму или ее часть, которую вы завернули и хотите восстановить (
return $form
илиreturn $form['myelement']
). Вы можете дополнительно использовать команды ajax вместо простого возврата структуры формы, но это более сложный процесс.хранить каждое значение в хранилище состояния формы, пока вы не отправите форму. Сделайте это в обработчике отправки (
$form_state->set('somevalue', $form_state->getValue('somevalue'))
) и всегда вызывайте,$form_state->setRebuild()
если вы не выполняете окончательную отправку формы. Я предпочитаю иметь собственные обработчики отправки, но с большей логикой в основном обработчике отправки тоже все в порядке.Всегда используйте
#name
атрибут на кнопке, которая выполняет отправку, и если у вас есть только один обработчик отправки формы, используйте,$for_state->getTriggeringElement()['#name']
чтобы определить, какой элемент отправил форму.если вы используете 'trigger_as' в определении #ajax, если вы хотите отправить форму с элементом select, например, всегда используйте такое же определение #ajax, как и для кнопки. По моему опыту это требуется - хотя и не указано в документации.
Использование
#limit_validation_errors
может иногда быть очень сложным, и выяснение того, почему форма не работает, может занять довольно много времени, поэтому используйте его осторожно (это хорошо для изоляции ошибок формы только на элементе (элементах), которые вы фактически перестраиваете, чтобы ваш код не влияет на другие части формы).всегда используйте кнопки для отправки формы, и если вы хотите, чтобы что-то необычное, например select было инициирующим элементом, используйте опцию 'trigger_as' в конфигурации #ajax и скрывайте реальную кнопку с классом 'js-hide' для хорошего пользовательского интерфейса.
в определении формы получите значения по умолчанию из хранилища состояния формы, если они существуют, или назначьте их в хранилище, если их нет. В противном случае форма не будет работать должным образом.
не используйте $ this или что-либо еще, к чему у вас нет внешнего доступа, иначе это сломает Ajax. всегда используйте статические обработчики ajax.
при окончательной отправке формы, в зависимости от того, что у вас (не) есть собственный обработчик отправки формы для ajax, отключите перестройку формы с помощью вызова
$form_state->setRebuild(FALSE)
.Вы можете использовать сокращенные вызовы :: в элементе отправки ajax (
$element['#ajax']['callback'] = '::ajaxFormRebuild';
и$element['#submit'] = [['::ajaxFormSubmitHandler'];
).обратный вызов ajax предназначен только для возврата перестроенной формы или команд ajax. Никогда не возвращайте измененную форму (т.е. не изменяйте массив форм в этом обратном вызове).
источник
Чтобы добавить к этому контрольному списку, если вы отображаете форму в модальном окне, есть вероятность, что сообщения об ошибках не будут отображаться. Как сказал Иван Ярош, вы должны убедиться, что форма имеет обертку:
Вам также необходимо добавить следующее к элементу, который отправляет форму. В большинстве случаев это будет ваша кнопка отправки:
источник
Я использую модуль Contact ajax . Еще несколько подробностей об этом (со страницы проекта):
источник