3

Problem

I'm using #element_validate to validate an input on a custom form which creates a node. I'm using element_validate_integer_positive as the function to validate. It works perfectly.

It partly works when I try to hook the same code into the existing node edit form. The form still breaks and displays the correct message but it also throws two errors due to missing values. How can I remove these errors?

So far

Here's the form code from my custom module. This works as expected.

$form['field_total_vacation'] = array(
  '#type' => 'textfield',
  '#title' => t('Total Vacation'),
  '#size' => 5,
  '#element_validate' => array('element_validate_integer_positive'), 
);

Here's my hook into the node edit form:

function viewspagehack_form_alter(&$form, $form_state, $form_id) {  
  if ($form_id === 'job_advert_node_form') {

    $form['field_total_vacation']['#weight']             = 19;
    $form['field_total_vacation']['#element_validate']   = array('element_validate_integer_positive');
    }
  }

If I enter a non-positive integer into field_total_vacation on the node edit form, it still breaks and throws the correct message: "Total Vacation must be a positive integer" but it also throws:

Notice: Undefined index: #value in element_validate_integer_positive() (line 4190 of C:\XAMPP\htdocs\drupal\includes\form.inc).
Notice: Undefined index: #title in element_validate_integer_positive() (line 4192 of C:\XAMPP\htdocs\drupal\includes\form.inc).

This is because element_validate_integer_positive() takes $element as it's first input and the function then calls:

$element['#value']
$element['#title']

But this error doesn't throw on my custom form which also doesn't take an input. What's going on?

EDIT

I moved #element_validate to here, this means it now has access to #title:

$form['field_total_vacation']['und']['0']['#element_validate']   = array('element_validate_integer_positive');

This removes the title error but leaves the value error. I can't understand why this function takes #value from $element.

function element_validate_integer_positive($element, &$form_state) {
   $value = $element['#value'];

None of the form elements have #value, #value only seems to appear in $form_state. But yet it works in my custom form and not on the node edit.

2
  • Does this help?
    – Clive
    Commented Sep 27, 2013 at 15:40
  • @Clive Partly. I spotted that #value was hiding a couple levels down as you mentioned in that post. But the #value error still exists and I can't understand where my custom form is even getting #value from. Added an edit to my main question. Commented Sep 29, 2013 at 13:23

3 Answers 3

4

the method that work is this

function MYMODULE_form_NODE_FORMID_alter(&$form, &$form_state) {
  dpm($form);
  $form['body'][LANGUAGE_NONE][0][['#element_validate'][] = 'MYMODULE_validate_breads_node_form_alter';
}

/**
 * Implements callback function().
 * Specific alteration for views exposed forms
 */
function MYMODULE_validate_NODE_FORMID_alter($element, &$form, &$form_state) {
  if (empty($element['#value'])) {
    form_error($element, t('Text'));
  }
}
1
  • The callback function signature should be: function myelement_validate($element, &$form_state, $form) (switch $form and $form_state parameters and don't pass $form byref).
    – Koen
    Commented Aug 21, 2017 at 14:30
1

I ended up using the format of Jonathan's answer, although I added an extra validation function as opposed to putting it in #element_validate

function mymodule_form_alter (&$form, $form_state) {
  if ($form_id === 'node_edit_form_id') {
    $form['#validate'][] = 'mymodule_editjobadvert_validate';
  }
}

Two things to note about this. First student_age appears twice because the field can have multiple values and I need to check both.

Second each if checks if the value is a number or empty. Because empty is also ok.

function mymodule_editnode_validate ($form, $form_state) {
  /*element validate doesn't work when adding with form_alter for some reason. http://drupal.stackexchange.com/questions/86990/adding-validation-to-existing-forms-using-element-validate*/
  if(is_numeric($form_state['values']['field_total_vacation']['und']['0']['value']) || $form_state['values']['field_total_vacation']['und']['0']['value'] == NULL ) {
        } else {
          form_set_error('field_total_vacation', "Total Vacation must be a number");
    };
  if(is_numeric($form_state['values']['field_student_age']['und']['0']['value']) || $form_state['values']['field_student_age']['und']['0']['value'] == NULL ) {
        } else {
          form_set_error('field_student_age', "Student age must be a number");
    };
  if(is_numeric($form_state['values']['field_student_age']['und']['1']['value']) || $form_state['values']['field_student_age']['und']['0']['value'] == NULL ) {
        } else {
          form_set_error('field_student_age', "Student age must be a number");
    };
}
0

for Drupal 8 -9 here is an example of adding validation to all of a field type:

/**
 * Implements hook_field_widget_form_alter().
 */
function MYMOD_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
  $field_definition = $context['items']->getFieldDefinition();
  $textarea_fields = [
    'text_with_summary',
    'text_long',
  ];
  if (in_array($field_definition->getType(), $textarea_fields)) {
    if (!empty($element['#element_validate'])) {
      $element['#element_validate'][] = '_MYMOD_textfield_validate';
    }
    else {
      $element['#element_validate']= ['_MYMOD_textfield_validate'];
    }
  }
}

/**
 * Implements hook_validate().
 */
function _MYMOD_textfield_validate($element, $form_state) {
  $max_length = 5000;
  if (!empty($element['#value'])) {
    $value = $element['#value'];
    if (strlen($value) > $max_length) {
      $form_state->setError($element, t('Sorry there is a max input value of 5000 characters'));
    }
  }
}

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.