узнайте, перестраиваете ли вы всю форму или только ее часть, и оберните форму соответствующим образом элементом 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. Никогда не возвращайте измененную форму (т.е. не изменяйте массив форм в этом обратном вызове).