4

I'm building pretty simple forms loaded with AJAX and displayed with Foundation Reveal. I can get the form submission to work with AJAX, and update the markup inside the reveal, but with the AJAX-powered submission button, the validation method is not executed.

Why? How can I get the form validated with AJAX?

I just want the normal form validation process, where I can add my own validation to ::validateForm and then pass control to my AJAX form submission handler.

$form['submit'] = [
  '#type' => 'submit',
  '#value' => 'Tallenna',
  '#ajax' => [
    'callback' => '::ajaxFormSubmitHandler'
  ]
];

I tried with $form['#validate'] = array('::validateForm');, but it doesn't work. I also tried calling Form::validateForm($form, $form_state) in the submission handler with the following code.

Form::validateForm($form, $form_state);
if ($form_state->hasAnyErrors()) {
  $form_state->setRebuild();
  $errors = $form_state->getErrors();
  return($form);
}
else {
  $form_state->setRebuild(FALSE);
}

I can set up the callback for a single element.

$form['field_asiakkaan_nimi'] = [
  '#type' => 'textfield',
  '#title' => $this->t('Asiakkaan nimi'),
  '#required' => TRUE,
  '#ajax' => [
    'callback' => array($this, 'validateNimiAjax'),
    'event' => 'change',
  ],
  '#suffix' => '<span class="nimi-valid-message"></span>'
];

I can use that callback for the field processing.

  public function validateNimiAjax(array &$form, FormStateInterface $form_state) {
    $response = new AjaxResponse();
    $message = 'Nimi validoitu!';
    $response->addCommand(new HtmlCommand('.nimi-valid-message', $message));
    return $response;
  }

This doesn't seem to be the proper way to go about this.

I am also getting this error:

The form has become outdated. Copy any unsaved work in the form below and then reload this page.

How can I get AJAX delivered forms validated and processed?

2 Answers 2

5

Here is a very basic example that will validate your data. It should give you an idea of how to handle it:

class myForm extends FormBase {
  public function getFormId() {
    return 'my_form';
  }

  public function buildForm(array &$form, FormStateInterface $form_state) {
    $form['#prefix'] = '<div id="my_form_wrapper">';
    $form['#suffix'] = '</div>';
    $form['some_text'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Enter a value'),
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
      '#ajax' => [
        'wrapper' => 'my_form_wrapper',
        'callback' => '::ajaxCallback',
      ],
    ];

    return parent::buildForm($form, $form_state);
  }

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

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

  public function submitForm(array &$form, FormStateInterface $form_state) {
    drupal_set_message($this->t('The form was submitted'));

    parent::submitForm($form, $form_state);
  }
}

With the above code, the form is built, and the ajax is set. Note that no validation needs to be set, as the validateForm() method will be called automatically if it exists. When the ajax is executed, it will always call the validate form method first. If validation is passed, then the submitForm() method will be called, but if validation is failed, it will not. Finally the ajax callback is called and the form is returned.

2
  • $form is an array and has no setValue method
    – Kevin
    Jan 17, 2018 at 18:32
  • Oops, typo. Fixed.
    – Jaypan
    Dec 29, 2021 at 20:25
0

This look like correct, just try to use an ID instead of a class

  '#ajax' => [
    'callback' => '::ajaxFormSubmitHandler'
  ]

and

//$response->addCommand(new HtmlCommand('.nimi-valid-message', $message));
$response->addCommand(new HtmlCommand('#nimi-valid-message', $message));

Example: http://www.drupal8.ovh/en/tutoriels/26/ajax-form

2
  • Just to return to this older topic.. (Oh, automatic submit) I'm still struggling with form validation in ajax submissions. I have pretty much the same form as previously, and everything apart from validation works as expected. My validateForm method is called, but I cannot raise an error and form submits no matter what. Dec 2, 2016 at 9:00
  • 1
    And again correcting myself for someone else struggling with this.. I had to check manually for the errors in my ajax submit and then return the whole form, like so: ` if ($form_state->hasAnyErrors()) { $form_state->setRebuild(); $errors = $form_state->getErrors(); return($form); } else { $form_state->setRebuild(FALSE); }` Dec 2, 2016 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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