Аякс-проверка формы в drupal 8

Главные вкладки

Аватар пользователя remmor remmor 30 октября 2018 в 22:46

Есть форма, в которой функция валидации выглядит банально.

<?php  public function validateForm(array &$formFormStateInterface $form_state) {
    
parent::validateForm($form$form_state);
  }
?>

Задача навесить дополнительную проверку формы, но уже через аякс. И в случае её прохождения чтобы было все как обычно до доработок.
Добавляем в

<?php    $form['submit'] = [
      
'#type' => 'submit',
      
'#value' => $this->t('Submit'),
];
?>

код

<?php      '#ajax' => [
    
'callback' => '::validateFormAjax',
    
'event' => 'click',
  ]
?>

Все ок.
Делаем валидате новый.

<?php public function validateFormAjax(array &$formFormStateInterface $form_state) {
   
$good_form functionValidate_server();    
   if (
$good_form) {   
     
$response = new AjaxResponse();
     
$content['#markup'] = 'not, wrong';
     
$response->addCommand(new OpenModalDialogCommand(''$content, ['width' => '100''height' => '100']));   
    return 
$response;
  }
  else {
//Проблема тут, форма теперь не отправляется, что тут писать?
    
parent::validateForm($form$form_state);
  }
}
?>

Когда условие срабатывает, все ок - окно открывается, предупреждаем. Но если условие не срабатывает - то форма теперь перестает отправляться и проверяться на остальные условия.
То есть кусок

<?php  else {
    
parent::validateForm($form$form_state);
  }
?>

видимо неверен, так нельзя, тут надо что-то другое.
Как после аякс-проверки формы заставить её отправиться без аякса, как раньше было?

Лучший ответ

Аватар пользователя gun_dose gun_dose 31 октября 2018 в 12:35
1

Кнопка не может быть аяксовой и неаяксовой одновременно. Поэтому если событие висит на кнопке отправки, то форма всегда будет отправляться аяксом и без аяксового редиректа обойтись нельзя. Опишу в двух словах правильную последовательность:
1. Делаем обычный аякс сабмит.
2. Делаем обычную валидацию, нигде её не вызываем принудительно, т.к. она вызовется сама при сабмите.
3. После отправки формы возвращаем не форму, а AjaxRespond с вот такой командой

Комментарии

Аватар пользователя remmor remmor 31 октября 2018 в 10:04

Нет, проверка на стороне сервера. Запрос должен идти туда, данные там.
Иными словами, нужно по нажатию Submit проверит форму через аякс и если проверка пройдена - отправить форму нормальным образом.
Я видимо изначально не то прописываю в для submit, видимо не обработчик в свойстве "#ajax" нужно прописывать, а что?

Аватар пользователя remmor remmor 31 октября 2018 в 11:26

Посмотрел все, аналогов не нашел. Собственно в итоге проблема сводится к вопросу - как программного "выполнить форму", чтобы произошел прописанный в ней редирект.
Несмотря на то, что первоначально проверка у нас идёт по ajax - а форма считай мульстистеп-форма, данные переносятся

Аватар пользователя gun_dose gun_dose 31 октября 2018 в 11:47
1

Не пытайтесь делать валидация в кастомном коллбэке. Коллбэк должен вызывать сабмит, а свои валидации вы должны описать в стандартном методе validateForm. Вопрос только, зачем отправлять форму без аякса?

Аватар пользователя Orion76 Orion76 31 октября 2018 в 12:15

gun_dose wrote:
Вопрос только, зачем отправлять форму без аякса?

Вероятно, чтобы не заморачиваться с аякс-редиректом при успешной валидации и сабмите.

Хотя, по-моему лучше все-таки заморочиться аякс-редиректом, а все остальное реализовать стандартно аякс-формой.

Аватар пользователя remmor remmor 31 октября 2018 в 12:16

Результат формы на второй странице подставляются во Views. На нужно выполнить форму и отправить редирект на views а она не отправляется.
А как тогда валидацию аяксовую делать.
Ещё раз - нажали на кнопку submit, пошел запрос за сервер, если ответ положительный - отправляем форму, если отрицательный - выводим диалоговое окно и ниче не происходит.
Как такое делать, если не через валидацию?

Аватар пользователя sas@drupal.org sas@drupal.org 31 октября 2018 в 12:15

remmor wrote:

"выполнить форму", чтобы произошел прописанный в ней редирект.

За программное "выполнение формы" в данном случае отвечает #ajax параметры в т.ч. event к нему см. https://www.drupal.org/docs/8/api/javascript-api/ajax-forms

Аватар пользователя remmor remmor 31 октября 2018 в 12:19

event у нас клик на кнопке, то есть просто 'click'. Не очень понимаю.
У нас есть работающая форма. К ней просто нужно провесить проверку при нажатии на сабмит и елси проверка прошла - то чтобы все отправилось как раньше, без аяксов.
А не выходит, страница не перезагружается, редирект, прописанный в форме не происходит.
Выше вон пишут, что вообще кэллбэки тут нельзя юзать

Аватар пользователя remmor remmor 31 октября 2018 в 12:33

Так как делать то? Через JS вообще гемор, а через Form API не выходит - или аякс, или отправка.
Не пойму, как по результатам запроса Аякс просто отправить форму, ну что такого то...

Аватар пользователя gun_dose gun_dose 31 октября 2018 в 12:35
1

Кнопка не может быть аяксовой и неаяксовой одновременно. Поэтому если событие висит на кнопке отправки, то форма всегда будет отправляться аяксом и без аяксового редиректа обойтись нельзя. Опишу в двух словах правильную последовательность:
1. Делаем обычный аякс сабмит.
2. Делаем обычную валидацию, нигде её не вызываем принудительно, т.к. она вызовется сама при сабмите.
3. После отправки формы возвращаем не форму, а AjaxRespond с вот такой командой

Аватар пользователя remmor remmor 31 октября 2018 в 14:33

gun_dose wrote:

1. Делаем обычный аякс сабмит.

То есть то что в посте описано, так?

<?php    $form['submit'] = [
      
'#type' => 'submit',
      
'#value' => $this->t('Submit'),
      
'#ajax' => [
       
'callback' => '::validateFormAjax',
        
'event' => 'click',
  ];
?>

gun_dose wrote:

2. Делаем обычную валидацию, нигде её не вызываем принудительно, т.к. она вызовется сама при сабмите.

То есть в validateFormAjax никаких else - просто проверка, см пост?
gun_dose wrote:

3. После отправки формы возвращаем не форму, а AjaxRespond с вот такой командой

Блин!! Я два часа назад это нашел, попробовал, не помогло, начал ещё всякие

<?php \Drupal::formBuilder()->processForm($form_id$form$form_state);
\
Drupal::formBuilder()->submitForm($form_id,  $form_state);?>

отправлять вместе с редиректом. А оказалось работает!!