0

I have a form that adds a product to the cart.

The form uses AJAX to open a modal when the form is submitted.

I want to show form errors (if any) before the modal opens and avoid opening it if there are errors.

Here's my form submit element:

$form['submit'] = [
  '#type' => 'submit',
  '#value' => $this->t('Submit'),
  '#ajax' => [
    'callback' => '::submitAjaxForm'
  ],
  '#attached' => [
    'library' => ['core/drupal.dialog.ajax'],
  ],
];

My submitAjaxForm:

public function submitAjaxForm(array $form, FormStateInterface $form_state) {
  $response = new AjaxResponse();
  $response->addCommand(new OpenModalDialogCommand(
    $this->t('Product added to cart!'),
    [
      '#theme' => 'some_theme',
    ]
  ));

  return $response;
}

And my submitForm:

public function submitForm(array &$form, FormStateInterface $form_state) {
  // Add product to cart.
}

I have tried by adding this code to the AjaxSubmit but it only shows the error messages once the page has been reloaded.

if ($form_state::hasAnyErrors()) {
  foreach ($form_state->getErrors() as $error) {
    $this->messenger()->addError($error);

    $message = [
      '#theme' => 'status_messages',
      '#message_list' => $this->messenger()->messagesByType(MessengerInterface::TYPE_ERROR),
    ];

    $messages = $this->renderer->render($message);

    $response = new AjaxResponse();
    $response->addCommand(new HtmlCommand('#result-message', $messages));
    $form_state->setRebuild(TRUE);

    return $response;
  }
}

How can I show the errors without having to reload the page?

0

I see two things that stand out to me:

1) Setting the '#name' attribute on the submit button. You should never do that. I've learned over the days that there is always a better way to do whatever you're trying to do when setting the #name attribute, and setting it causes some wonkiness. This may be why your form is not rebuilding.

2) You are rendering your status messages in a D7 way. Use this instead:

$messages = ['#type' => 'status_messages']; $response->addCommand(new PrependCommand('#target-div', \Drupal::service('renderer')->renderRoot($messages))); It looks weird, because the messages aren't being retrieved, but by setting the #type to status messages, Drupal will handle the retrieval in the background. This is probably why you are seeing some funkiness with the messages.

  • I don't set #name on the submit button. – Jdrupal Sep 3 at 10:10

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.