14

I've created a webform using the Form API. I'm using the #AJAX field option to add AJAX validation to each field.

Is it possible to validate and submit the form using AJAX without reloading the page. If validation fails I want to show an error message and if validation is successful then I want to show a message (ideally in a lightbox) and reset the form fields.

My code so far:

$form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#default_value' => '',
    '#maxlength' => '128',
    '#required' => TRUE,
    '#ajax' => array(
        'callback' => '_validate_name',
        'wrapper' => 'name-error-icon-container',
        'method' => 'html',
        'effect' => 'none',
        'progress' => array(
            'message' => NULL,
        ),
    ),
);

$form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Submit',
    '#ajax' => array(
        'callback' => '_handle_form_submit',
        'effect' => 'fade',
    ),
);

callback functions look like this:

function _validate_name($form, $form_state) {

    if ($form_state['values']['name'] != '') {
    $output = 'OK';
    }
    else {
      $output = 'Enter a value';
    }

   return $output;

}

function _handle_form_submit($form, $form_state) {
}

But I'm not sure what should go in the _handle_form_submit function to validate and then either return a message or submit form and reset fields?

6 Answers 6

-2

The examples module has an ajax form that you can refer to as well as many others. Here is a link to the ajax form example in the code repository, but I suggest downloading to look at the implementation yourself anyway.

5
  • 1
    sorry - I cant find any examples of ajaxy validataion in the example module Oct 9, 2013 at 4:05
  • Yeah, that's a bloated answer right there. I actually don't see any validation there either. Each callback simply returns the form.
    – AlxVallejo
    Oct 20, 2014 at 14:09
  • 2
    How is this the accepted answer? It doesn't even say where to look in the link provided (and the link doesn't have validation example anyway).
    – robinmitra
    Jun 28, 2016 at 17:38
  • New link for the ajax form example: cgit.drupalcode.org/examples/tree/ajax_example/…
    – Brentg
    Jun 28, 2017 at 12:02
  • I made my answer a wiki, since it's accepted but poor quality Jun 30, 2017 at 3:25
13

I know this is question has been lying around for a couple of years by now, but I don't feel any of the other answers really get the point of Drupal 7 ajax form submission, so I'll try to explain it.

Since your form should work as well without the ajax as per good practice, your ajax submit handler should do nothing but return the form. Everything else should be in your validation and submit functions.

function ex_form($form, $form_state) {
  $form['name'] = array(
    '#type' => 'textfield',
     '#title' => t('Name'),
     '#default_value' => '',
     '#maxlength' => '128',
     '#required' => TRUE,
  );

  $form['submit'] = array(
   '#type' => 'submit',
   '#value' => 'Submit',
   '#ajax' => array(
     'callback' => 'ex_form_ajax_handler',
     'effect' => 'fade',
   ),
  );
}

function ex_form_submit(&$form, &$form_state) {
  // Submit logic - runs when validation is ok
  // You can alter the form here to be just a markup field if you want.
}

function ex_form_validate(&$form, &$form_state) {
  // Validation logic - invalidate using form_set_error() or form_error()
}

function ex_form_ajax_handler(&$form, &$form_state) {
  return $form;
}
2
  • probably Best answer Jan 4, 2018 at 14:36
  • Are you saying that the validate and submit methods will automatically be called for an AJAX callback on a submit button? In what order do the methods get called?
    – Jeff
    Nov 21, 2018 at 15:01
3

I think the post by maxtorete on October 17, 2011 seems to give a fuller example using both form_validate() and form_submit()

(I haven't tested it yet.)

Also Joshua Stewardson's answer over at stack overflow has a nice working example:

function dr_search_test_form($form, &$fstate) {

  $form['wrapper'] = [
    '#markup' => '<div id="test-ajax"></div>',
  ];

  $form['name'] = [
    '#type'     => 'textfield',
    '#required' => TRUE,
    '#title'    => 'Name',
  ];

  $form['submit'] = [
    '#type'  => 'submit',
    '#value' => 'Send',
    '#ajax'  => [
      'callback' => 'dr_search_test_form_callback',
      'wrapper'  => 'test-ajax',
      'effect'   => 'fade',
    ],
  ];

  return $form;
}

function dr_search_test_form_callback($form, &$fstate) {

  return '<div id="test-ajax">Wrapper Div</div>';
}

function dr_search_test_form_validate($form, &$fstate) {

  form_set_error('name', 'Some error to display.');
}

Joshua makes the point that validation error messages replace the #ajax['wrapper'] element completely so your callback needs to resupply this element again as you replace it.

2
  • when that link invalidates it's a sign the question is no longer relevant! Oct 9, 2013 at 6:04
  • 2
    down vote is a bit harsh - even if it was only a link - it was a link to the answer - not just a link to a module that doesn't have the answer - unlike the accepted answer!! anyway I provided some working code while I was being downvoted. Oct 9, 2013 at 7:00
2

In general, validation and form submission handling should happen in the usual _validate() and _submit() callbacks. The idea is that forms should still work without ajax.

Pretty much the only thing the #ajax callbacks should do is return the part of the form that should be replaced, according to the defined wrapper.

4
  • 2
    Be careful with your wording. The callback should return THE WHOLE FORM, rebuilt from the form_state. Returning PART of the form is the biggest Drupal/AHAH misconception. See katbailey.net/blog/ahah-drupal-may-it-one-day-live-its-acronym.
    – user6092
    Mar 10, 2012 at 1:11
  • 8
    This question is about Drupal 7...AHAH no longer exists in Drupal. In an #ajax callback function in Drupal 7 you only return the part of the form that you want to replace.
    – Clive
    Mar 10, 2012 at 1:53
  • 2
    @ChrisD. As Clive mentioned, This is Drupal 7 and we have quite a nice ajax framework now that allows to do all kinds of fancy stuff like returning multiple separate form parts and so on.
    – Berdir
    Mar 10, 2012 at 13:04
  • @Clive I came across another ajax related issue drupal.stackexchange.com/a/142316/19205 where author mentioned "form needs to be build again after items_count is changed" which is also for d7. I am got confused with, which statement is right(without arguing who is right:-) ). Could you please share some info on this?
    – kiranking
    Apr 18, 2015 at 13:33
0

There are two ways

1)

function abc_form_validate(&$form, &$form_state) {
  // Validation logic - invalidate using form_set_error() or form_error()
}

function abc_form_ajax_handler(&$form, &$form_state) {
  return $form;
}

2) Example module http://cgit.drupalcode.org/examples/tree/ajax_example/ajax_example.module?id=refs/heads;id2=7.x-1.x#l402

3
  • I don't now how accurate your answer is, but the formatting of it definitely needs improvement (if you don't want it to be deleted by moderators). Check the help page if needed, or just use some of the wysiwyg editor buttons to at least mark your code as ... code. Dec 11, 2015 at 11:16
  • Non correctly formatted code is not a reason to delete an answer. It just requires a user with edit privilege to fix it.
    – apaderno
    Dec 11, 2015 at 21:28
  • Here I come, desperate, looking for a solution, merely 2 years after this answer, clicked a link which leads me to a non-existing tree/branch. Please don't use links on the answers, or if you do paste the content at the time of writing.
    – MacK
    Sep 25, 2017 at 9:48
0

In my case, using a submit type caused the form to always submit, so I changed it to a button with #ajax specified. Then, I had to do my validation in the ajax callback.

I was making a ctools pane; I don't know if that plays into it.

function mymodule_form($form, &$form_state) {
  ...
  $form['button'] = array(
    '#type' => 'button',
    '#value' => t('Subscribe'),
    '#ajax' => array(
      'callback' => '_mymodule_ajax',
    ),
  );
  return $form;
}

function _mymodule_ajax($form, &$form_state) {
  if ( ! valid_email_address($form_state['values']['email']) ) {
    form_set_error($form, t('Please enter a valid email address.'));
  } else {
    $form = array(
      '#markup' => t('You have subscribed.'),
    );
  }
  return $form;
}

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.