Clientside Validation works great, and I'm using FAPI Validation for some extra rules.

However, my form also uses an ajax callback to run some stuff and then output the results under the form. This callback is always run, even when validation fails. e.g.:

function example_form($form, &$form_state) {
 $form['zip'] = array(
    '#type' => 'textfield',
    '#title' => t('of this ZIP Code'),
    '#required' => TRUE,
    '#rules' => array(
      'numeric', 
    ),
  );
  
 $form['submit'] = array(
    '#type' => 'submit',
    '#value'=>t('Submit'),
    '#ajax' => array(
      // #ajax has two required keys: callback and wrapper.
      // 'callback' is a function that will be called when this element changes.
      //'callback' => 'ajax_example_simplest_callback',
      'callback' => 'example_form_submit',
      // 'wrapper' is the HTML id of the page element that will be replaced.
      'wrapper' => 'results',
      'method' => 'html',
     ),
  );
  return $form;
}

function example_form_submit($form, &$form_state) {
    $values = $form_state['values'];
    $html = "<p>zip: ". $values['zip'] . "<br>";
    return array("#markup" => $html);
 }

"zip: ", for example, always shows up, even when a valid value hasn't been passed. Is there anyway of preventing submission/working out in example_form_submit whether validation has been passed?

Comments

attiks’s picture

The problem is that your code is attached to the click event of the button, our code is attached to the submit event of the form, form api apparently does not support attaching to the submit event of the form (feel free to create an issue in http://drupal.org/project/issues/drupal).

Possible solutions:

  1. Add your callback to the form submit event.
  2. Add a custom javascript to the button click event that triggers form.validate.
  3. Validate the form on the server side and don't return anything if it fails.
  4. ...
attiks’s picture

Status: Active » Closed (works as designed)

Closing this, if you need more assistance, feel free to re-open.

vdsh’s picture

I had the same issue and I struggled a bit with it (my log-in form is using an ajax request), so here is what I did: I altered the #ajax element from the form in my hook form alter

$form['actions']['submit']['#ajax'] = array(
         'callback' => 'ajax_account_form_ajax_handler',
         'wrapper' => $unique_key,
         'effect' => 'fade',
         'event' => 'submitLogin');
      
      $form['#attached']['js'][] = drupal_get_path('module', 'ajax_account') . '/js/ajax_account.js';

And in the js:

(function ($) {
    
  Drupal.behaviors.ajaxAccount = {
    attach: function (context, settings) {
      // Cache the form object
      var $form = $("form#user-login-form", context);
      var $submitButton = $('input[type="submit"]', $form);

      // Use once so we dont attach submit multiple times
      // Use off to remove any existing submit handler
      $form
        .once('ajaxAccount')
        .off('submit')
        .on('submit', function(e){
        e.preventDefault();
        var $form = $(this);

        // Run validation on $form object.
        // If success, trigger event on button
        if($form.validate().form()) {
         $submitButton.trigger('submitLogin');
        }
      });
    }
  }
})(jQuery);

Hope it helps a bit!