0

How do I disable the #maxlength validation on a field I've added to the user entity form?

Let me explain: I want my field to be 10 characters long in the database, so I've set a max length of 10 at the field UI. However, at the form level I want it to have a formatting mask that makes it be 14 characters long.

Even though I could disable its #maxlength property via hook_form_alter and get to enter more than 10 characters, the validation for such property is still up when I submit the form.

Since I don't want to remove the mask via JS by the time the form gets submitted, my intention was to to bypass form validation only for the max length property of this field (or even for the whole field) and then at a presave hook I'd remove the mask and store only the original 10 characters to the database.

Hope I've made it clear.

Thank you.

1

You didn't give an explanation of your rules for your input, but for an example, imagine that the format of the required value is XXX-XXXXXXXXXX, where X is a numeral, and the hyphen is always at position 4.

  1. Change the maxlength on the HTML input to allow more characters. Add your own validation handler to be run before the default validation handlers. Add your own submit handler to be run on submission.

    use Drupal\Core\Form\FormStateInterface;
    
    function HOOK_form_alter(array $form, FormStateInterface $form_state, $form_id) {
      if ($form_id == 'some_form_id') {
        if (isset($form['some_field'])) {
          // Change the HTML max length to 14.
          $form['some_field']['#maxlength'] = 14;
    
          // Insert a custom validation handler to be run BEFORE
          // the default handlers.
          array_unshift($form['#validate'], 'my_module_FORM_ID_validate');
    
          // Add your own submit handler to deal with the submitted values:
          $form['actions']['submit']['#submit'][] = 'my_module_FORM_ID_submit';
        }
      }
    }
    
  2. In the validation handler, parse the value in this handler, replacing the value in the field with the 10-character value, so it can pass validation. Store the other 4 characters in the $form_state

    function my_module_FORM_ID_validate(array &$form, FormStateInterface $form_state) {
      if ($value = $form_state->getValue('some_field')) {
        // Check that the submitted value is in the right format, and
        // parse the value into $matches.
        if (preg_match('/(\d{3})-(\d{10})/', $value, $matches)) {
          // Store the 10-digit value in the field, to be passed through
          // default submit handlers.
          $form_state->setValueForElement('some_field', $matches[2));
    
          // Store the other three digits in the $form_state.
          $form_state->set('some_key', $matches[1]);
        }
        else {
          // The submitted value was not in the correct format.
          $form_state->setError($form['some_field'], t('Some Field must be in the format XXX-XXXXXXXXXX where the Xs are numeric'));
        }
      }
    

    }

  3. Use the values as necessary in the submit handler.

    function my_module_FORM_ID_validate(array &$form, FormStateInterface $form_state) {
      $key1 = $form_state->get('some_key');
      $key2 = $form_state->getValue('some_field');
      // Do what you need with these values.
    }
    
  • Additionally, the recommended method to set a new value to field at form validation is $form_state->setValueForElement(), as per the docs. Thank you @Jaypan! – Heitor Althmann Jul 26 at 20:23

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.