 

Drupal・3 min read・Last update on November 8, 2019

# Implementing #autocomplete in Drupal 8 with Custom Callbacks

 

 

 

 ![Implementing #autocomplete in Drupal 8 with Custom Callbacks](/sites/default/files/remediation-media/64e5ddecd8b51449bff05add_blog-featured-image.webp) 

 



 

   Table of contents  - [Step 1: Assign autocomplete properties to textfield](#step-1-assign-autocomplete-properties-to-textfield)
- [Step 2: Define autocomplete route](#step-2-define-autocomplete-route)
- [Step 3: Add Controller and return JSON response](#step-3-add-controller-and-return-json-response)
 
  

 

Autocomplete on textfields like tags / user &amp; node reference helps improve the UX and interactivity for your site visitors, In this blog post I'd like to cover how to implement autocomplete functionality in Drupal 8, including implementing a custom callback

### Step 1: Assign autocomplete properties to textfield

As per Drupal Change records, #autocomplete\_path has been replaced by #autocomplete\_route\_name and #autocomplete\_parameters for autocomplete fields ( More details -- <https://www.drupal.org/node/2070985>).

The very first step is to assign appropriate properties to the textfield:

1. '**\#autocomplete\_route\_name**':  
     for passing route name of callback URL to be used by autocomplete Javascript Library.
2. '**\#autocomplete\_route\_parameters':**  
     for passing array of arguments to be passed to autocomplete handler.

 ```

$form['name'] = array(
    '#type' => 'textfield',
    '#autocomplete_route_name' => 'my_module.autocomplete',
    '#autocomplete_route_parameters' => array('field_name' => 'name', 'count' => 10),
);

```

Thats all! for adding an #autocomplete callback to a textfield.

**However**, there might be cases where the routes provided by core might not suffice as we might different response in JSON or additional data. Lets take a look at how to write a autocomplete callback, we will be using using my\_module.autocomplete route and will pass arguments: 'name' as field\_name and 10 as count.

### Step 2: Define autocomplete route

Now, add the 'my\_module.autocomplete' route in **my\_module.routing.yml** file as:

 ```

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

```

While Passing parameters to controller, use the same names in curly braces, which were used while defining the autocomplete\_route\_parameters. Defining \_format as json is a good practise.

### Step 3: Add Controller and return JSON response

Finally, we need to generate the JSON response for our field element. So, proceeding further we would be creating AutoCompleteController class file at **my\_module &gt; src &gt; Controller &gt; AutocompleteController.php**.

 ```

<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Component\Utility\Tags;
use Drupal\Component\Utility\Unicode;

/**
 * Defines a route controller for entity autocomplete form elements.
 */
class AutocompleteController extends ControllerBase {

  /**
   * Handler for autocomplete request.
   */
  public function handleAutocomplete(Request $request, $field_name, $count) {
    $results = [];

    // Get the typed string from the URL, if it exists.
    if ($input = $request->query->get('q')) {
      $typed_string = Tags::explode($input);
      $typed_string = Unicode::strtolower(array_pop($typed_string));
      // @todo: Apply logic for generating results based on typed_string and other
      // arguments passed.
      for ($i = 0; $i < $count; $i++) {
        $results[] = [
          'value' => $field_name . '_' . $i . '(' . $i . ')',
          'label' => $field_name . ' ' . $i,
        ];
      }
    }

    return new JsonResponse($results);
  }

}
```

We would be extending ControllerBase class and would then define our handler method, which will return results. Parameters for the handler would be Request object and arguments (field\_name and count) passed in routing.yml file. From the Request object, we would be getting the typed string from the URL. Besides, we do have other route parameters (field\_name and Count) on the basis of which we can generate the results array.

An important point to be noticed here is, we need the **results array to have data in 'value' and 'label' key-value pair** as we have done above. Then finally we would be generating JsonResponse by creating new JsonResponse object and passing $results.

That's all we need to make autocomplete field working. Rebuild the cache and load the form page to see results.

 



Written by

Purushotam Rai

 

 

 

 

 

 

 ## We'd love to talk about your business objectives

 [ Contact Us  ](/contact)