Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

How to Add Autocomplete to Text Fields in Drupal 8: Defining a Custom Route

Parent Feed: 

Let's say that it's a WhatsApp-like, a decoupled, Drupal 8-backed, real-time chat platform that you're building. One using Node.js. In this case, implementing field autocomplete functionality becomes a must, doesn't it? But how do you add autocomplete to text fields in Drupal 8?

Needless to add that such otherwise "basic" functionality — implemented on fields like node reference and user/tags — would instantly:
 

  1. improve the user experience 
  2. increase the level of user interactivity and engagement
     

Users would group around different "channels" and be able to easily add new members. The auto-complete text fields will make the whole “new member coopting” process conveniently easy:

Users would only need to start typing and an array of name suggestions (of the already existing team members) would spring up.

But let's see, specifically, what are the steps to take to implement autocomplete functionality in Drupal 8:
 

1. The Drupal Autocomplete Form Element: Adding Properties to the Text Field

The first basic step to take is to define your form element. The one that will enable your app's users, on the front-end, to select from the suggested team members' names. For this:
 

  1. navigate to “Form” (you'll find it under “Entity”)
  2. scroll the menu down to ”NewChannelForm.php”
     

Note: using “#autocomplete_route_name element”, when defining your form element, will let Drupal know that it should ignore it on the front-end.

And now, let's go ahead and assign specific properties to your form's text field! For this:
 

  1. define “#autocomplete_route_name”, so that the autocomplete JavaScript library uses the route name of callback URL
  2. define “#autocomplete_route_parameters”, so that an array of arguments gets passed to autocomplete handler
     
$form['name'] = array(
    '#type' => 'textfield',
    '#autocomplete_route_name' => 'my_module.autocomplete',
    '#autocomplete_route_parameters' => array('field_name' => 'name', 'count' => 5),
);


And this is how you add #autocomplete callback to your fill-in form's text field in Drupal 8!

Note: in certain cases — where you have additional data or different response in JSON —  the core-provided routes might just not be enough. Then, you'll need to write an autocomplete callback using the “my_module. autocomplete“ route and the proper arguments (“name” for the field name and “5” as count, let's say).

And here's specifically how you write a custom route:
 

2. Add Autocomplete to Text Fields in Drupal 8: Define a Custom Route

How? By simply adding the reference to the route — where data will get retrieved from — to your “my_module.routing.yml file”:
 

my_module.autocomplete: path: '/my-module-autocomplete/{field_name}/{count}' defaults: _controller: '\Drupal\my_module\Controller\AutocompleteController::handleAutocomplete' _format: json requirements: _access: 'TRUE' 


Note: remember to use the same names in the curly braces (those that you inserted when you defined your “autocomplete_route_parameters”) when you pass parameters to the controller!
 

3. Add Controller with Custom Query Parameters

In the custom route that you will have defined, you'll have a custom controller AutocompleteController, with the handleAutocomplete method.

Well, it's precisely this method that makes sure that the proper data gets collected and properly formatted once served.

But let's delve deeper into details and see how precisely we can generate the specific JSON response for our text field element.

For this, we'll need to:
 

  • set up a AutoCompleteController class file under “my_module>src>Controller > AutocompleteController.php"
     
  • then, extend the ControllerBase class and set up our handle method (the one “responsible” for displaying the proper results)
     
  • it's the Request object and those arguments already defined in your routing.yml.file (“name” for the field name and “5” for the count, remember?) that will pass for your handler's parameters
     
  • the Request object will be the one returning the typed string from URL, whereas the “field_name” and the “count” route parameters will be the ones providing the results array.
     

Note: once you get to this step here, as you add autocomplete to text fields in Drupal 8, remember that you should be having data in “value” and “label” key-value, as well:

Next, you'll set up a new JsonResponse object and pass $results, thus generating a return JsonResponse.
 

Summing Up

That's pretty much all the “hocus pocus” that you need to do to add autocomplete to text fields in Drupal 8. Now the proper data results should be generated.

Just reload your app's form page and run a quick test:

Try to create a brand new channel in your app and to add some of the already existing team members.

Does the text field have autocomplete functionality added to?

Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web