How to create a custom Autocomplete Entity Field Widget using the Drupal 8 Form API

Auteur(s) de l'article

In this article, I will not explain how to create a custom Autocomplete using the Drupal 8 Form API — which should only be used on custom Form using the Drupal Admin UI.
Here I will try to expose you a step-by-step guide which explains how you can create a custom Autocomplete Field Widget using the Drupal 8 Form API Core feature — An autocomplete that you must only use in your Drupal Admin UI form (Nodes, Taxonomies, …).
This tutorial may help you in the following case: Create a custom Drupal Entity Field Widget Autocomplete that fetch data outside of Drupal (eg. from an API) but still store and display final data into Drupal Entities.
If you are looking for resources which explains how to implement Views to alter an Autocomplete Field, please refer to this excellent guide.
In the other hand, if you are looking for resources which explains how to create an autocomplete that you could use in your own Drupal frontend applications, please refer to my previous blog post.
Truth can only be found in one place: the code

Robert C. Martin

Clean Code: A Handbook of Agile Software Craftsmanship

The other day, I was asked to create a custom Autocomplete Field for Node in a project which should fetch data from a custom RESTfull endpoint.
Let's see how I achieve that.
Oh, for security reason, I will replace the original RESTfull endpoint by https://swapi.dev/ - a Star Wars RESTfull API.

Step 1- The custom Autocomplete Field Type

The FieldType will define the way our data will be stored in Database.

Step 2- The custom Autocomplete Field Widget

The FieldWidget will define how the Form element will look likes and how data are processed before saved.
At first sight, you may be interested to use the #entity_autocomplete field type - it seems exactly what you need. Unfortunately, this is not. Indeed, the #entity_autocomplete doesn't allow you any customisation.
So, you will need the old folk's #textfield and his cousin attribute #autocomplete_route_name
The #autocomplete_route_name attribute will allow you to define a route to handle the autocomplete business logic (data you will return given the user input).
You also may add the #autocomplete_route_parameters attribute, this one gives you the possibility to send a fixed unalterable parameter to your #autocomplete_route_name, you may use it to fix the number of results to return.

Step 3 - Define autocomplete route

Now you know how to create the autocomplete form, but you will need a route to manage the logic which will fetch data & return them. How? By simply adding the reference to the route — where data will get retrieved from — to your swapi.routing.yml file:
Be careful to use the same route name (here swapi.people.autocomplete) in your previous #autocomplete_route_name.
Also, be sure to change permission according to your own needs.

Step 4 - Add Controller, Fetch the API and return JSON response

Now having a routing & a form, you have to define your custom controller, with the handleAutocomplete method.
Well, it's precisely this method that makes sure that the proper data gets collected and properly formatted once requested by Drupal.
Let's dig deeper and see how we can precisely deal with specific JSON response for our textfield element.
  1. Setup an _ PeopleAutcompleteController_ class file under my_module/src/Controller/PeopleAutcompleteController.php;
  2. Then, extend the ControllerBase class and setup your handle method (in our case ::handleAutocomplete see swapi.routing.yml);

Step 5 - The custom Autocomplete Field Formatter

The FieldFormatter define the way data will be display on the Frontend.
That's pretty much all the hocus-pocus that you need to have an autocomplete based on a textfield of Drupal 8.

Sources

For the most curious of you, here are some sources of additional information that inspired the creation of this article.
Purushotam Rai (24 November, 2016). Implementing #autocomplete in Drupal 8 with Custom Callbacks
See on https://www.qed42.com/blog/autocom...
Stijn Berkers (28 February, 2018). How to produce a custom auto-complete field in drupal 8
See on https://lucius.digital/en/blog/drupal...
Make me alive (4 May, 2014). Adding autocomplete for text-field
See on https://drupal.stackexchange.com/…/..
Stijn Berkers (18 July, 2018). How to add autocomplete to text fields in drupal 8: defining a custom route
See on https://www.optasy.com/blog/how-add-autocom...