\form_get_errors
function
Returns an associative array of all errors.

Returns an associative array of all errors.

Comments

texas-bronius’s picture

If you are stacking validation functions, even just applying a custom validation atop the FAPI default validation (like required fields), you can choose to *not* fire off your validation code until all previous validation has succeeded with a if (form_get_errors()) return; as in:

/**
 * Custom Form Validation
 */
function my_module_form_validate($form, &$form_state) {
  // Don't custom-validate if previous validation errors (still) exist
  if (form_get_errors()) return;
  // .. Otherwise, process custom form validation goes here
}

This would prevent some custom validation functionality to occur until all the "xyz form field required" have been resolved. And no, merely calling form_get_errors() does not pop the stack and prevent their display.

peterpoe’s picture

Not in a very clean way, but can be done:
(I'm planning to use something similar to this in the Conditional Fields module)

/**
 * Custom Form Validation.
 * Removes all form validation errors caused by a 'foo][bar' form element.
 */
function my_module_form_validate($form, &$form_state) {
  $errors = form_get_errors();
  if ($errors) {
    // Clear errors.
    form_clear_error();
    // Clear error messages.
    $error_messages = drupal_get_messages('error');
    // Initialize an array where removed error messages are stored.
    $removed_messages = array();

    // Remove all errors originated by the 'foo][bar' element.
    foreach ($errors as $name => $error_message) {
      if ($name == 'foo][bar') {
        $removed_messages[] = $error_message;
        unset($errors[$name]);
      }
    }

    // Reinstate remaining errors.
    foreach ($errors as $name => $error) {
      form_set_error($name, $error);
      // form_set_error() calls drupal_set_message(), so we have to filter out
      // these from the error messages as well.
      $removed_messages[] = $error;
    }

    // Reinstate remaining error messages (which, at this point, are messages that
    // were originated outside of the validation process).
    foreach (array_diff($error_messages['error'], $removed_messages) as $message) {
      drupal_set_message($message, 'error');      
    }
  }
}
Leglaw’s picture

Thank you for your contribution -- you saved me quite a bit of time.

mchaplin’s picture

This is possibly the only way to conditional validation with field collections in D7.

MegaChriz’s picture

This is a shorter piece of code for removing error messages of one form element. Works only for Drupal 7.
This basically accesses the stored messages directly and bypasses the form API functions:

/**
 * Clears an error against one form element.
 *
 * @param $name
 *   The name of the form element.
 */
function form_unset_error($name) {
  $errors = &drupal_static('form_set_error', array());
  $removed_messages = array();
  if (isset($errors[$name])) {
    $removed_messages[] = $errors[$name];
    unset($errors[$name]);
  }
  $_SESSION['messages']['error'] = array_diff($_SESSION['messages']['error'], $removed_messages);
}

Example usage:

/**
 * Removes all form validation errors caused by a 'foo][bar' form element.
 */
function my_module_form_validate() {
  form_unset_error('foo][bar');
}
colemanw’s picture

That function is much simpler, thank you.
One more piece needed - in order to avoid the display of an empty error message, add this to the end:

    if (empty($_SESSION['messages']['error'])) {
      unset ($_SESSION['messages']['error']);
    }
fauv’s picture

--removed

MsNingrum’s picture

This is what I need! Thanks!

keopx’s picture

Practical example to remove error using form_unset_error('foo][bar');

/**
* Removes all form validation errors caused by a 'foo][bar' form element.
*/
function my_module_form_validate() {
  form_unset_error('field_freetext][und][0][value');
}
karenann’s picture

Thanks for the code to MegaChriz and colemanw!

I used it in a patch submission for user_role_field 7.x-1.1.

https://www.drupal.org/node/2364941#comment-11389923

DrupalGideon’s picture

This function is still as useful today as it was a few years ago. I would love to see this in core or some form api extension module.

scott.allison’s picture

Here's a method that I used to simply replace the text of the error message.

function hook_form_alter(&$form, &$form_state) {
  $form['field_terms_agree']['#element_validate'][] = '_mymodule_field_validate';
}

function _mymodule_field_validate($element, &$form_state, $form) {
  if($element['#value'] == 0) {
    $errors = &$_SESSION['messages']['error'];
    foreach($errors as $item => $message) {
      if(strpos($element['#title'] . ' field is required') !== FALSE) {
        $errors[$item] = t('You must agree to the terms and conditions');
      }
    }
  }
}

One could also create a single element_validate callback to handle all forms by storing the replacement error message in $form_state

vomitHatSteve’s picture

This function appears to be removed in D8.
Instead, use $form_state->getErrors();
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21Fo...