diff options
-rw-r--r-- | includes/form.inc | 126 |
1 files changed, 78 insertions, 48 deletions
diff --git a/includes/form.inc b/includes/form.inc index a53aab224..c1ba70bf4 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -1070,6 +1070,83 @@ function form_execute_handlers($type, &$form, &$form_state) { /** * Files an error against a form element. * + * When a validation error is detected, the validator calls form_set_error() to + * indicate which element needs to be changed and provide an error message. This + * causes the Form API to not execute the form submit handlers, and instead to + * re-display the form to the user with the corresponding elements rendered with + * an 'error' CSS class (shown as red by default). + * + * 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). + * + * Example 1: Allow the "Previous" button to function, regardless of whether any + * user input is valid. + * + * @code + * $form['actions']['previous'] = array( + * '#type' => 'submit', + * '#value' => t('Previous'), + * '#limit_validation_errors' => array(), // No validation. + * '#submit' => array('some_submit_function'), // #submit required. + * ); + * @endcode + * + * Example 2: Require some, but not all, user input to be valid to process the + * submission of a "Previous" button. + * + * @code + * $form['actions']['previous'] = array( + * '#type' => 'submit', + * '#value' => t('Previous'), + * '#limit_validation_errors' => array( + * array('step1'), // Validate $form_state['values']['step1']. + * array('foo', 'bar'), // Validate $form_state['values']['foo']['bar']. + * ), + * '#submit' => array('some_submit_function'), // #submit required. + * ); + * @endcode + * + * This will require $form_state['values']['step1'] and everything within it + * (for example, $form_state['values']['step1']['choice']) to be valid, so + * calls to form_set_error('step1', $message) or + * form_set_error('step1][choice', $message) will prevent the submit handlers + * from running, and result in the error message being displayed to the user. + * However, calls to form_set_error('step2', $message) and + * form_set_error('step2][groupX][choiceY', $message) will be suppressed, + * resulting in the message not being displayed to the user, and the submit + * handlers will run despite $form_state['values']['step2'] and + * $form_state['values']['step2']['groupX']['choiceY'] containing invalid + * values. Errors for an invalid $form_state['values']['foo'] will be + * suppressed, but errors flagging invalid values for + * $form_state['values']['foo']['bar'] and everything within it will be + * flagged and submission prevented. + * + * Partial form validation is implemented by suppressing errors rather than by + * skipping the input processing and validation steps entirely, because some + * forms have button-level submit handlers that call Drupal API functions that + * assume that certain data exists within $form_state['values'], and while not + * doing anything with that data that requires it to be valid, PHP errors + * would be triggered if the input processing and validation steps were fully + * skipped. + * @see http://drupal.org/node/370537 + * @see http://drupal.org/node/763376 + * * @param $name * The name of the form element. If the #parents property of your form * element is array('foo', 'bar', 'baz') then you may set an error on 'foo' @@ -1079,54 +1156,7 @@ function form_execute_handlers($type, &$form, &$form_state) { * The error message to present to the user. * @param $limit_validation_errors * Internal use only. The #limit_validation_errors property of the clicked - * button if it exists. Multistep forms not wanting to validate the whole form - * can set the #limit_validation_errors property on buttons to avoid - * validation errors of some elements preventing the button's submit handlers - * from running. For example, pressing the "Previous" button should not fire - * validation errors just because the current step has invalid values. AJAX is - * another typical example. - * If this property is set on the clicked button, the button must also define - * its #submit property and those handlers will be executed even if there is - * invalid input, so extreme care should be taken with respect to what is - * performed 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). - * For example: - * @code - * $form['actions']['previous']['#limit_validation_errors'] = array( - * array('step1'), - * array('foo', 'bar'), - * ); - * @endcode - * This will require $form_state['values']['step1'] and everything within it - * (for example, $form_state['values']['step1']['choice']) to be valid, so - * calls to form_set_error('step1', $message) or - * form_set_error('step1][choice', $message) will prevent the submit handlers - * from running, and result in the error message being displayed to the user. - * However, calls to form_set_error('step2', $message) and - * form_set_error('step2][groupX][choiceY', $message) will be suppressed, - * resulting in the message not being displayed to the user, and the submit - * handlers will run despite $form_state['values']['step2'] and - * $form_state['values']['step2']['groupX']['choiceY'] containing invalid - * values. Errors for an invalid $form_state['values']['foo'] will be - * suppressed, but errors for invalid values for - * $form_state['values']['foo']['bar'] and everything within it will be - * recorded. If the button doesn't need any user input to be valid, then the - * #limit_validation_errors can be set to an empty array, in which case, all - * calls to form_set_error() will be suppressed. - * Partial form validation is implemented by suppressing errors rather than by - * skipping the input processing and validation steps entirely, because some - * forms have button-level submit handlers that call Drupal API functions that - * assume that certain data exists within $form_state['values'], and while not - * doing anything with that data that requires it to be valid, PHP errors - * would be triggered if the input processing and validation steps were fully - * skipped. See http://drupal.org/node/370537. + * button, if it exists. * * @return * Return value is for internal use only. To get a list of errors, use |