11

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?

-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.

  • 1
    sorry - I cant find any examples of ajaxy validataion in the example module – ErichBSchulz Oct 9 '13 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 '14 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 '16 at 17:38
  • New link for the ajax form example: cgit.drupalcode.org/examples/tree/ajax_example/… – Brentg Jun 28 '17 at 12:02
  • I made my answer a wiki, since it's accepted but poor quality – rocketeerbkw Jun 30 '17 at 3:25
10

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.

Sinve 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;
}
  • probably Best answer – Andrew Kozoriz Jan 4 '18 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 '18 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.

  • when that link invalidates it's a sign the question is no longer relevant! – ErichBSchulz Oct 9 '13 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. – ErichBSchulz Oct 9 '13 at 7:00
  • thanks @mbomb007 - fixed now – ErichBSchulz Apr 25 at 0:30
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.

  • 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 '12 at 1:11
  • 7
    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 '12 at 1:53
  • 1
    @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 '12 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 '15 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

  • 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. – Pierre.Vriens Dec 11 '15 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. – kiamlaluno Dec 11 '15 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 '17 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, privacy policy and cookie policy

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