1

I have a multistep form created with msnf for an content type. I set multiple submit buttons that each one has its own submit callback, and also i want every single button with its validation callback :

function MYMODULE_form_alter(&$form, &$form_state, $form_id){
  switch ($form_id){
        case "my_form_id" :
          $form['actions']['submit_2'] = array(
                '#type' => 'submit',
                '#name' => 'button_name',
                '#value' => t('Name'),
                '#weight' => 6,
                '#submit' => array('node_form_submit'),
                '#validate' => 'MYMODULE_validate_2'

            );
            // Add submit callback (works fine!)
            array_unshift($form['actions']['submit_2']['#submit'], 'MYMODULE_form_submit_2');
            // rest of code ...
  }
} 

inside the validation callback i put this test code :

function MYMODULE_validate_2($form, &$form_state){    
  dpr('test');
  exit; 
}

Here i have two problems :

1) this validation callback didn't triggered i don't know why ? (the system must show me a dump 'test' and then exit but nothing happen!)

2) I want to disable all the required fields only when i click on this submit_2 button.

I found sth in this post, but like i said the validation callback is not handled so i can't test the code inside that post.

Thanks in advance.

EDIT I was blind :p I must put the callback function inside an array() like this

'#validate' => array('MYMODULE_validate_2')

sometime i made stupid error :)

Now my problem is only the second one :

  • I want to disable all the required fields only when i click on this submit_2 button.
1

You can set the #limit_validation_errors property on your submit button to an empty array to bypass validation on all required elements.

  • This is not safe!! Do not use the #limit_validation_errors property on buttons that trigger saving of form values to the database. – Boussetta moez Mar 18 '15 at 15:16
  • mainly used in multistep form : read this documentation for more info of using #limit_validation_errors : api.drupal.org/api/drupal/includes%21form.inc/function/… – Boussetta moez Mar 18 '15 at 15:19
  • What makes you think it's unsafe? If it's a multi step form, you ignore submit buttons that do NOT save any data. Even if it does, you don't get any form values and you can't simply save anything to the database. Try setting this property and inspect $form_state['values']. Clearing form errors is equally insecure. – AyeshK Mar 18 '15 at 15:21
  • because I tried this solution, and the whole site is broken and get this error inside dblog : EntityMalformedException: Fehlende Paketeigenschaft auf einem Element des Types node. in entity_extract_ids()... So I searched why i get this error then i found the link above that says do not use it when you want to save to database – Boussetta moez Mar 18 '15 at 15:24
1

the solution inside this post works perfectly!

worked for me like this :

function MYMODULE_validate_2($form, &$form_state){    
    $errors = form_get_errors();
    if ($errors) {
      form_clear_error();

      foreach ($errors as $name => $error_message) {
         unset($errors[$name]); 
      }
    }
}
  • The 2nd part doesn't make sense, since you cannot easily unset $errors the variable which was passed from the function. The part which works is form_clear_error();, but it clears errors for all fields which is more like workaround which may or may not work in all cases. – kenorb Sep 16 '16 at 9:15
0

Normally you should use #limit_validation_errors.

Although for more sophisticated requirements, you can add a custom validation handle by adding into #element_validate element for every field which you need, e.g. (Entityforms example):

/**
 * Implements hook_field_attach_form().
 */
function FOO_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {

  // Attach these validation handlers only to elements belonging to entityforms.
  if ($type == 'entityform') {
    // Ignore the following fields for validation.
    $ignore = array('fieldset');
    // Attach validation handlers to simple fields.
    _attach_validation_handler_recursive($form, $ignore);
  }

}

/**
 * Recursively attaches a validation handler.
 *
 * @param array $element
 *   Form element to attach a validation hanlder to.
 */
function _attach_validation_handler_recursive(&$element, $ignore = array()) {
  if (!empty($element['#field_name'])
    && !empty($element['#bundle'])
    && !empty($element['#entity_type'])) {
    // Ignore fields that we don't want to process for required validation.
    $field_info = field_info_field($element['#field_name']);
    $instance_info = field_info_instance($element['#entity_type'],
      $element['#field_name'], $element['#bundle']);

      if (!empty($element['#type']) && !in_array($element['#type'], $ignore)) {
        // Required validate handler.
        if ($element['#required'] && !isset($element['address_container'])) {
          if (!empty($element['#element_validate']) && is_array($element['#element_validate']) && !in_array('FOO_validate_required_field', $element['#element_validate'])) {
            $element['#element_validate'][] = 'FOO_validate_required_field';
          }
          else {
            $element['#element_validate'] = array('FOO_validate_required_field');
          }
          $element['#check_empty'] = TRUE;
        }
      }
  }

  $children = element_children($element);
  foreach ($children as $child) {
    $child_element = &$element[$child];
    _attach_validation_handler_recursive($child_element, $ignore);
  }
}

and in that callback you can disable #required flag for specific fields with certain conditions (like specific triggering element or when field is hidden), e.g.

/**
 * Implements callback for #element_validate Form API.
 *
 * Validates required fields for entity form.
 */
function FOO_validate_required_field(&$element, &$form_state, $form
  if (isset($element['#access']) && !$element['#access']) {
    // Ignore hidden elements.
    $element['#required'] = FALSE;
    // Clear previous validation errors for not active elements.
    $errors = &drupal_static('form_set_error', array());
    $err_key = $element['#field_name'] . '][' . LANGUAGE_NONE;
    if (array_key_exists($err_key, $errors)) {
      unset($errors[$err_key]);
    }
    return;
  }

  if (empty($element['#required'])) {
    // Ignore elements that are not required.
    return;
  }
}

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.