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

In order to improve the user experience for content creators and improve developer's ability to support Drupal's autocomplete behavior we decided to upgrade Drupal's autocomplete component by using jQuery UI's Autocomplete component.

Before

In Drupal 7 we namespaced out the autocomplete component and it's method under the "Drupal" global namespace. For example:

Drupal.behaviors.autocomplete = { ... }
Drupal.autocompleteSubmit = function () { ... }
/**
 * An AutoComplete object.
 */
Drupal.jsAC

/**
 * An AutoComplete DataBase object.
 */
Drupal.ACDB

The autocomplete implementation was proprietary.

After

In Drupal 8 we have changed our approach to handling autocomplete considerably. Drupal.jsAC and Drupal.ACDB have been removed. Instead, we use jQuery UI's autocomplete plugin.

Autocomplete is attached to input elements through the render system. Two properties are required:

#autocomplete_route_name
'#process' => array('form_process_autocomplete', 'ajax_process_form')

The property #autocomplete_route_name is FALSE by default, which bypassing loading of autocomplete assets. By providing a path to an endpoint that will process and return autocomplete suggestions, the form element will be marked up to indicate that it is an autocomplete field. This markup is added in the process function form_process_autocomplete. The class form-autocomplete is added to autocomplete elements and this class is used as a selector to attach the necessary behaviors to the DOM element, those being found in Drupal.behaviors.autocomplete.

This change should largely be invisible to the common site builder, administrator, and editor as you will still be able to choose fields with autocomplete behavior just as you did in Drupal 7. The main change is in how this behavior is supported by the system and the reliability of the code behind it.

Perhaps a small set of themers who want to reuse this common autocomplete behavior will need to know the specifics of how this behavior works. For this audience a deep dive into /core/misc/autocomplete.js will be necessary.

Impacts: 
Site builders, administrators, editors
Module developers
Themers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

taggartj’s picture

$form[''myform_search'] = array(
      '#type' => 'textfield',
      '#title' => 'some text',
      '#default_value' => isset($form_state->values['myform_search']) ? $form_state->values['myform_search'] : '',
      '#autocomplete_route_name' => 'somecustom.autocomplete',
      '#autocomplete_route_parameters' => array(),
    );

somecustom.autocomplete
path: '/some-custom/autocomplete'
defaults:
_controller: '\Drupal\MYMODULE\Form\MYFormCLASS::myCallback'
requirements:
_permission: 'access content'

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
   * This is a quick function for address search auto compete call back.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The current request object containing the search string.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   A JSON response containing the autocomplete suggestions.
   */
  public static function myCallback(Request $request) {
    $string = $request->query->get('q');
    $matches = array();
    $matches[] = array('value' => $string . ' (1)', 'label' => $string);
    $matches[] = array('value' => 'beer (2)', 'label' => $string . '1');
    return new JsonResponse($matches);

and in custom js

var autocomplete = Drupal.autocomplete;
var myAutoBox = $("#edit-myform-search").autocomplete({
      select: function( event, ui ) {
        //console.log( event);
        //console.log( ui );
      }
   });