Node save validation throws a max field length error when trying to save a node that the sum character count of the term reference field utilizing the autocomplete deluxe widget exceeds 128 characters.

Comments

blischalk’s picture

After looking into this issue more I believe that I have found the root of the problem.

I believe by default Drupal form textfields have a 128 character maxlength. (http://api.drupal.org/api/drupal/developer%21topics%21forms_api_referenc...)

Within the autocomplete_deluxe module the widget defines a textfield, hidden through css, that stores ajax data values (autocomplete-deluxe-value-field). Since the autocomplete_deluxe module doesn't specify a maxlength it appears that this field falls back to the Drupal textfields default of 128 characters.

This becomes an issue when large amounts of terms are added in a term reference field or when very large scientific / medical terms are added because this maxlength is quickly reached causing failing validation on node save.

If anyone else encounters this issue I am posting some code that may help ease the problem. The code below alters the autocomplete_deluxe elements info, replacing it's process callback with our own callback. Our callback is exactly the same one the module defines except with our own maxlength for that hidden field defined. This workaround has some issues as this maxlength will apply globally for ALL fields using the autocomplete deluxe widget module.

It would seem that a maxlength should probably be configurable on a per field basis to allow as many characters as necessary. It might even be nice to have some sort counter letting you know how many characters are left and prevent you from adding more terms than you can successfully save.

function your_module_element_info_alter(&$type) {
  if (isset($type['autocomplete_deluxe']['#process'])) {
    $type['autocomplete_deluxe']['#process'][0] = '_your_module_element_process';
  }
}

function _your_module_element_process($element) {
  $element['#attached'] = array(
    'library' => array(array('system', 'ui.autocomplete'), array('system', 'ui.button')),
    'js' => array(drupal_get_path('module', 'autocomplete_deluxe') . '/autocomplete_deluxe.js'),
    'css' => array(drupal_get_path('module', 'autocomplete_deluxe') . '/autocomplete_deluxe.css'),
  );
  // Workaround for problems with jquery css in seven theme.
  if ($GLOBALS['theme'] == 'seven') {
    $element['#attached']['css'][] = drupal_get_path('module', 'autocomplete_deluxe') . '/autocomplete_deluxe.seven.css';
  }

  $html_id = drupal_html_id('autocomplete-deluxe-input');

  $element['#after_build'][] = 'autocomplete_deluxe_after_build';

  // Set default options for multiple values.
  $element['#multiple'] = isset($element['#multiple']) ? $element['#multiple'] : FALSE;
  $element['#prefix'] = '<div class="clearfix autocomplete-container">';
  $element['#suffix'] = '</div>';

  $element['values'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'class' => array('autocomplete-deluxe-values'),
    ),
  );

  $element['textfield'] = array(
    '#type' => 'textfield',
    '#size' => isset($element['#size']) ? $element['#size'] : '',
    '#required' => isset($element['#required']) ? $element['#required'] : '',
    '#attributes' => array('class' => array('autocomplete-deluxe-form', 'form-autocomplete'), 'id' => array($html_id)),
    '#default_value' => '',
  );

  $js_settings['autocomplete_deluxe'][$html_id] = array(
    'input_id' => $html_id,
    'min_length' => isset($element['#autocomplete_min_length']) ? $element['#autocomplete_min_length'] : 0,
    'multiple' => $element['#multiple'],
  );

  if (isset($element['#autocomplete_deluxe_path'])) {
    if ($element['#multiple']) {
      $element['value_field'] = array(
        '#type' => 'textfield',
        '#attributes' => array('class' => array('autocomplete-deluxe-value-field')),
        '#default_value' => isset($element['#default_value']) ? $element['#default_value'] : '',
        '#prefix' => '<div class="autocomplete-deluxe-value-container">',
        '#suffix' => '</div>',
        '#maxlength' => 1000, /** We define our custom maxlength here **/
      );
      $element['textfield']['#attributes']['style'] = array('display:none');
    }
    else {
      $element['textfield']['#default_value'] = isset($element['#default_value']) ? $element['#default_value'] : '';
    }

    $js_settings['autocomplete_deluxe'][$html_id] += array(
      'type' => 'ajax',
      'uri' => $element['#autocomplete_deluxe_path'],
    );
  }
  elseif (isset($element['#autocomplete_options'])) {
    $js_settings['autocomplete_deluxe'][$html_id] += array(
      'type' => 'list',
      'data' => $element['#autocomplete_options'],
    );

    $html_id_select = drupal_html_id('autocomplete-deluxe-input-select');
    $element['list_value'] = array(
      '#type' => 'select',
      '#options' => $element['#autocomplete_options'],
      '#multiple' => $element['#multiple'],
      '#attributes' => array('class' => array('autocomplete-deluxe-form', 'form-autocomplete'), 'id' => array($html_id_select)),
      '#default_value' => isset($element['#default_value']) ? $element['#default_value'] : '',
    );

    // Hide textfield so that, in case javascript is deactivated
    $element['textfield']['#attributes']['style'] = 'display: none;';
    $js_settings['autocomplete_deluxe'][$html_id]['select_input'] = $html_id_select;
  }
  else {
    // If there is no source (path or data), we don't want to add the js
    // settings and so the functions will be abborted.
    return $element;
  }
  $element['#attached']['js'][] = array('data' => $js_settings, 'type' => 'setting');

  return $element;
mastap’s picture

Indeed, this seems to be the issue.

  1. Where should your piece of code should be implemented?
  2. Any other findings on this issue?

thanks!

blischalk’s picture

The code I posted previously was meant to be added into a custom module. It isn't a patch to fix autocomplete_deluxe but a work around. You would create a custom module and place the code I provided within it renaming any instances of "your_module" with the name of your module.

mzgajner’s picture

I'm having the same problem. Be kind and assist.

If it helps - this has been fixed for a year and a half in Drupal core:
http://drupal.org/node/971090

ldweeks’s picture

I'm not sure why the developer of autocomplete_deluxe hasn't created a new release of the code, but this problem has actually already been fixed. I created an issue for it (#1601054: Why not release 7.x-1.0-beta6?), but until he creates a release, you'll have to checkout the updated module from git. Here is the commit that fixes the 128 character limit problem, and here is a link to the beta6 tag in the repository viewer.

MGParisi’s picture

Status: Active » Fixed

Change tag to fix as it is already done in GIT. Unfortunately we just have to wait till he creates a new release!

hass’s picture

Priority: Normal » Major

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.