Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

Say you implement a textfield widget with autocompletion (like core does):

/**
 * Implements hook_elemenet_info().
 */
function system_element_info() {
  $types['textfield'] = array(
    '#input' => TRUE,
    '#size' => 60,
    '#maxlength' => 128,
    '#autocomplete_path' => FALSE,
    '#process' => array('ajax_process_form'),
    '#theme' => 'textfield',
    '#theme_wrappers' => array('form_element'),
  );
  return $types;
}

In Drupal 7 you had to append a hidden helper element in your theme function, to do autocompletion:

function theme_textfield($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'text';
  element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
  _form_set_class($element, array('form-text'));

  // !!! Create an autocompletion helper element using the #autocomplete_path
  // property.
  $extra = '';
  if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
    drupal_add_library('system', 'drupal.autocomplete');
    $element['#attributes']['class'][] = 'form-autocomplete';

    $attributes = array();
    $attributes['type'] = 'hidden';
    $attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
    $attributes['value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
    $attributes['disabled'] = 'disabled';
    $attributes['class'][] = 'autocomplete';
    $extra = '<input' . drupal_attributes($attributes) . ' />';
  }

  $output = '<input' . drupal_attributes($element['#attributes']) . ' />';

  // !!! Append the helper element to the textfield.
  return $output . $extra;
}

 

In Drupal 8 you add an additional processing callback to your element type:

  $types['textfield'] = array(
    '#input' => TRUE,
    '#size' => 60,
    '#maxlength' => 128,
    '#autocomplete_path' => FALSE,
    '#process' => array('form_process_autocomplete', 'ajax_process_form'),
            /// !!! Add form_process_autocomplete().
    '#theme' => 'textfield',
    '#theme_wrappers' => array('form_element'),
  );

Then, in the theme function:

function theme_textfield($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'text';
  element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
  _form_set_class($element, array('form-text'));

  // !!! Return the HTML for the element itself and append all child elements,
  // because form_process_autocomplete() will have automatically
  // added the hidden helper as a child.
  return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
}
Impacts: 
Module developers
Themers