2

I have a simple Drupal 7 form, with 3 dropdown select lists and a submission button. I want to add another button to the form which does some function (but not submitting the form). I want to bypass the validation part for the form and directly run the submission handler of that button.

The button I am using is the following one.

$form['my_fieldset']['click'] = array(
  '#type' => 'button',
  '#value' => 'click me',
  '#limit_validation_errors' => array(),
  '#executes_submit_callback' => FALSE,
  '#submit' => array('my_module_click_submit'),
);

FYI, all the select lists have #required=>TRUE, and #type=>'submit' for the button also doesn't work.

When I click it, it shows the error about the fields being required. How can I avoid that error, avoid validation handlers are run, and just run the code in my_module_click_submit()?

Also, I dont know why, but even if I fill the entire form and then click this button, the page just gets refreshed and my_module_click_submit() does NOT run. What's wrong?

I haven't put anything fancy inside my_module_click_submit(); I just wanted to see if it works. The submission handler I am trying is the following one.

function my_module_click_submit($form,&$form_state) {
  drupal_set_message('Click me button is clicked');
}
1
  • have you tried '#type' => '#submit', ?
    – Jimajamma
    Commented Apr 14, 2012 at 15:22

2 Answers 2

3

Jaypan gave me the answer.

  1. Required checks happen irregardless of validation - they happen before any other validation even occurs.
  2. You cannot skip the default _validation() function, it is always executed
  3. When you choose limit_validation_errors(), anything that is not part of that array is not submitted.

As such, you will want to explicitly declare your submit and validate functions for the original submit button, and leave the second button as-is, using the default submit and validate functions:

function some_form($form, &$form_state) {
  // Form definition not shown.
  $form['submit1'] = array(
    '#type' => 'submit',
    '#value' => t('Submit 1'),
    '#validate' => array('my_explicit_validate'),
    '#submit' => array('my_explicit_submit'),
  );

  $form['submit2'] = array(
    '#type' => 'submit',
    '#value' => t('Submit 2'),
  );

  return $form;
}

// my_form_validate is not created, since we don't want to validate the second submit button, but we do want the submit function.
function my_form_submit($form, &$form_state) {
  // You need to check which submit button was pushed, as this function
  // will be run for both buttons, but you only want do something if it was the 
  // secondbutton.
  if($form_state['values']['op'] == $form_state['values']['submit2']) {
    // Second submit button's submit function.
  }
}

function my_explicit_validate($form, &$form_state) {
  // Validation for the first submit button.
}

function my_explicit_submit($form, &$form_state) {
  // First submit button's submit function.
}

To deal with your required issue, you will need to not set #required => TRUE for the elements, and check them manually in your validation function (the function explicitly declared for the first button). If you want to have the required marks, I think you can manually add them to the element title, or you can override the theme function for those elements and manually add them there.

2

You are correctly using the #limit_validation_errors property; the documentation clearly states that setting it to an empty array avoids any validation being done. Even reading what reported for form_set_error(), I cannot find anything that would explain the behavior you are observing.

The standard form_set_error() behavior can be changed if a button provides the #limit_validation_errors property. Multistep forms not wanting to validate the whole form can set #limit_validation_errors on buttons to limit validation errors to only certain elements. For example, pressing the "Previous" button in a multistep form should not fire validation errors just because the current step has invalid values. If #limit_validation_errors is set on a clicked button, the button must also define a #submit property (may be set to an empty array). Any #submit handlers will be executed even if there is invalid input, so extreme care should be taken with respect to any actions taken by them. This is typically not a problem with buttons like "Previous" or "Add more" that do not invoke persistent storage of the submitted form values. Do not use the #limit_validation_errors property on buttons that trigger saving of form values to the database.

The #limit_validation_errors property is a list of "sections" within $form_state['values'] that must contain valid values. Each "section" is an array with the ordered set of keys needed to reach that part of $form_state['values'] (i.e., the #parents property of the element).

I can only think of a collateral effect of setting the #limit_validation_errors, and the #executes_submit_callback properties. The latter is causing the submission handler not to be called for your button; when you set it to FALSE, the button doesn't submit the form, which means the submission handler for that button is not being called.

Your Answer

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

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