0

Here is a simple form:

  public function buildForm(array $form, FormStateInterface $form_state)
  {
    $form['some_text'] = [
      '#type'  => 'textfield',
      '#title' => $this->t('TextValue'),
    ];
    $form['submit'] = [
      '#type'  => 'submit',
      '#value' => $this->t('Submit'),
    ];
    return $form;
  }

  public function validateForm(array &$form, FormStateInterface $form_state)
  {
    if ($form_state->getValue('some_text') != 'Awesome') {
      $form_state->setErrorByName('some_text', $this->t('Please enter "Awesome"'));
    }
  }

  public function submitForm(array &$form, FormStateInterface $form_state)
  {
    drupal_set_message($this->t('The form was submitted'));
    $form_state->setRedirectUrl(Url::fromRoute('<front>'));
  }

And it works as expected:
Case 1A: Submit with no entry gives this (error message in default message location): enter image description here Case 1B: Submit with "Awesome" in TextValue gives this (completion message in default message location and back to the front page of the site): enter image description here Now, I add some ajax on the submit button:

$form['submit'] = [
  '#type'  => 'submit',
  '#value' => $this->t('Submit'),
  '#ajax'  => [
    'wrapper'  => 'default_form_wrapper',
    'callback' => '::ajaxCallback',
    'progress' => [
      'type'    => 'throbber',
      'message' => $this->t('Be patient'),
    ],
  ],
];
$form['#prefix'] = '<div id="default_form_wrapper">';
$form['#suffix'] = '</div>';

and the corresponding callback:

  public function ajaxCallback(array &$form, FormStateInterface $form_state)
  {
    if ($form_state->hasAnyErrors()) {
      return $form;
    }
  }

And it works more or less as expected:
Case 2A: Submit with no entry gives this (almost OK, wrong location of the message): enter image description here Case 2B: Submit with "Awesome" in TextValue gives nothing (KO, no message and form is still displayed instead of front page).
And if I refresh the page in the browser, I get this: enter image description here As you can see, the location of the message area in case 2A is above form in default_form_wrapper (to be compared to the default message area location, a div with class="region region-highlighted"): enter image description here enter image description here

How can I make it work as I expect?

  1. Have the message in the "default" area?
  2. Have my submitForm work after all?
2
  • Does the issue still occur when using the default Bartik theme? – No Sssweat Feb 3 at 9:07
  • Exactly same behavior with Bartik. – gbmapo Feb 3 at 9:33
0

Finally, after hours digging Drupal Answers, I made it work this way.
My ajaxCallback:

$response = new AjaxResponse();
if ($form_state->hasAnyErrors()) {
  $messages = \Drupal::messenger()->deleteAll();
  $messages = [
    '#theme'        => 'status_messages',
    '#message_list' => $messages,
  ];
  $response->addCommand(new ReplaceCommand('#messages', ''));
  $response->addCommand(new AppendCommand('.region-highlighted', $messages));
}
else {
  $response->addCommand(new \Drupal\Core\Ajax\RedirectCommand(Url::fromRoute('<front>')->toString()));
  }
}
return $response;

and my submitForm is now empty!

Nota: $response->addCommand(new ReplaceCommand('#messages', '')); is here to have a new error message replacing a previous one (without this command, all the messages are displayed one after the other...).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.