jQuery UI has reached end of life and is being phased out of Drupal core as a result. jQuery UI autocomplete has been deprecated as part of that process. and Autocomplete functionality is now provided by a new library, @drupal/a11y_autocomplete.
Although autocomplete inputs will no longer use jQuery UI to execute their functionality, two backwards compatibility layers have been provided to make this change minimally disruptive. For the vast majority of use cases,
API backwards compatiblity
By default, autocomplete-enabled inputs include a backwards-compatible shim so the jQuery UI autocomplete API will continue to work for most use cases. For example, usage such as $('#autocomplete-input').autocomplete(options); will continue to work as expected despite jQuery UI autocomplete not being loaded. When the jQuery UI autocomplete API is used, a a JavaScript deprecation notice will be triggered.
API Backwards compatibility scope
- All Autocomplete specific functionality is supported (i.e. everything documented in the jQuery UI Autocomplete API) This includes:
- Options: appendTo, autoFocus, classes, delay, disabled, minLength, position, source
- Methods: close, destroy, disable, enable, instance, option, search, widget
- Events: change, close, create, focus, open, response, search, select
- Extension Points: _renderItem, _renderMenu, _resizeMenu
-
Extending jQuery UI functionality viajQuery UI widget factory has limited backwards compatibility support. If a site codebase has no calls to
$.widget('[a string that includes "autocomplete"]'), then it is not impacted by this backwards compatibility limitation.When using the widget factory to extend autocomplete, such as with calls like this
$.widget( "custom.autocomplete", {foo: bar, dip: dobson});, only autocomplete-specific methods (close, destroy, disable, enable, instance, option, search, widget) will be overridden. This widget factory usage does not support widget-scoped methods such as_addClass,_create,_delay,,_destroy,_superetc. Code that attempts to use these methods will fail ungracefully in order to unambiguously convey the fact that this usage is no longer supported. If a given autocomplete implementation includes this now-unsupported use case, this will be immediately apparent in the JS console as soon as the page loads.
jQuery UI Autocomplete Options -> A11y_Autocomplete Equivalents
| appendTo | There is no 1:1 equivalent, and the default behavior is different. jQuery UI defaults to appending autocomplete suggestion lists to the body element, while A11y Autocomplete appends the suggestion lists to a <div data-drupal-autocomplete-wrapper> that wraps the autocomplete-enabled input.
To achieve the same results as jQuery UI |
| autoFocus | Identical in A11y_Autocomplete, same option name, functionality and default value |
| classes | There is no 1:1 equivalent, but there are many ways to achieve the same results. Our recommended approach is doing this via event listener.
|
| delay | ##PENDING## |
| disabled | No 1:1 equivalent and not configurable via option. This option disables autocomplete functionality on an input without disabling the input. This is best accomplished in A11y_Autocomplete via event listener:
|
| minLength | The equivalent option in A11y_Autocomplete is minChars, and the default value is 1 in both |
| position | There is no 1:1 equvalent. In A11y autocomplete, the positioning of the list options is most easily customized via CSS styling. |
| source | The jQuery UI source option can be used in a variety of ways. The A11y_Autocomplete equivalent is different based on how it is used.
|
jQuery UI Autocomplete Methods -> A11y_Autocomplete Equivalents
| close | autocompleteInstance.close() |
| destroy | autocompleteInstance.close() |
| disable | No 1:1 equivalent, best accomplished via event listener.
|
| enable | Use the same approach as disable above. The condition in the event listener will determine whether or not to disable the input. |
| instance | There's no exact 1:1 equivalent but most properties remain available
Other instance properties provided by jQuery UI Autocomplete do not have equivalents available in A11y_Autocomplete |
| option |
|
| search | No direct equivalent. It requires using JavaScript to replicate the steps of searching: focus the input, enter a value, trigger search via keyboard event:
can interpret this as a cancelled search attempt. |
| widget | This provides the <ul> that contains list options as a jQuery object. The value returned by $autocompleteInstance.autocomplete( "widget" ) is equivalent to jQuery(autocompleteInstance.ul) |
jQuery UI Autocomplete Events -> A11y_Autocomplete Equivalents
change |
autocomplete-change |
close |
autocomplete-close |
create |
autocomplete-created |
focus |
autocomplete-highlight |
open |
autocomplete-open |
response |
autocomplete-response |
search |
autocomplete-pre-search |
select |
autocomplete-select |
jQuery UI Autocomplete Extension Points -> A11y_Autocomplete Equivalents
| _renderItem | No direct equivalent, but most uses of _renderItem can be accomplished by overriding the suggestionItem()method of the autocompleteInstance. This can also be accomplished by adding an event listener that customizes the list items.
|
| _renderMenu | No direct equivalent, but most uses of _renderItem can be accomplished by overriding the implementList()method of the autocompleteInstance. This can also be accomplished by adding an event listener that customizes the ul.
|
| _resizeMenu | No direct equivalent. Use the same event listener approach as _renderMenu, and set sizes there:
|
This API backwards compatibility shim will be removed in Drupal 10. For sites that still require the jQuery UI autocomplete in Drupal 10, jQuery UI autocomplete is still available as a contributed module https://www.drupal.org/project/jquery_ui_autocomplete/.
Running the API shim
By default, the shim is enabled on all autocomplete-enabled inputs initialized by Drupal.autocomplete. It may be necessary for contributed projects to have to manually initialize the shim when upgrading to use the new autocomplete library. The shim will reduce the likely hood of causing regressions with other modules that are potentially working on top of the contributed project.
It is important to attach the jQuery UI shim with the assumption that it might not always exist because the jQuery UI shim will be removed in Drupal 10.
-
Add dependency for the
core/autocomplete.jqueryui.shimlibrary.library: ... dependencies: - core/autocomplete.jqueryui.shim -
Attach jQuery UI shim after initializing the autocomplete library:
const autocomplete = A11yAutocomplete(input, options); // Drupal.autocompleteShim is removed in Drupal 10. If it doesn't exist, the // shim doesn't have to be initialized. if (Drupal.autocompleteShim && autocomplete._internal_object) { Drupal.autocompleteShim.jqueryUiShimInit(autocomplete._internal_object, options); }
Markup backwards compatibility
The markup generated by A11y_Autocomplete is different than that generated by jQuery UI autocomplete. Themes declaring Stable or Stable 9 as a base theme will continue to render autocomplete inputs with markup matching jQuery UI's. For sites needing to maintain jQuery UI markup, but not able to use Stable/Stable 9 as as base theme, it is also possible to provide backwards compatible markup by copying js/autocomplete from Stable or Stable 9 (they are identical) and loading it via a custom module or theme. If your site does not include autocomplete-specific custom styling or JavaScript customizations that rely on a specific DOM structure, this layer is likely unnecessary.