Drupal 8 - Create an autocomplete field

By xngo on March 10, 2019

Overview

Autocomplete field improves the user experience of your website. In this tutorial, I will show how to implement an autocomplete field for the node title.

Add autocomplete field in your form

To turn your input field into an autocomplete field, simply add the #autocomplete_route_name attribute to your field. For my case, I added in ./modules/tradesteps/src/Form/MyFormAutocomplete.php as follows:

<?php
namespace Drupal\tradesteps\Form;
 
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
 
class MyFormAutocomplete extends FormBase {
 
    public function buildForm(array $form, FormStateInterface $form_state) {
 
        // Add autocomplete routing to turn your field into an autocomplete field.
        $form['title'] = [
                            '#type' => 'textfield',
                            '#title' => $this->t('Title'),
                            '#autocomplete_route_name' => 'tradesteps.autocomplete_field',
                        ];
 
        return $form;
    }
 
    public function getFormId() {
        return 'tradesteps_autocompleteform';
    }
 
    public function submitForm(array &$form, FormStateInterface $form_state) {
    }
 
}

Add autocomplete routing

Add the autocomplete routing information in ./modules/tradesteps/tradesteps.routing.yml, like the following:

# The routing for your autocomplete query.
tradesteps.autocomplete_field:
  path: '/autocomplete_field'
  defaults:
    _controller: 'Drupal\tradesteps\Controller\Autocomplete::handleAutocomplete'
    _format: json
  requirements:
    _permission: 'access content'
 
# For completness, I put the test form page routing here too.
tradesteps.autocomplete_form:
  path: '/autocomplete_form'
  defaults:
    _form: 'Drupal\tradesteps\Form\MyFormAutocomplete'
    _title: 'Form using autocomplete field'
  requirements:
    _permission: 'access content'

Implement the autocomplete controller

Here is how I implement the controller to handle the autocomplete field. In ./modules/tradesteps/src/Controller/Autocomplete.php, add

<?php
namespace Drupal\tradesteps\Controller;
 
use Drupal\Core\Controller\ControllerBase;
 
// Use for autocomplete.
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
 
class Autocomplete extends ControllerBase {
 
    public function handleAutocomplete(Request $request) {
        $matches = array();
 
        // Get the string that is being typed.
        $string = $request->query->get('q');
 
        if ($string) {
            // Search in database.
            $query = \Drupal::entityQuery('node')
                                    ->condition('status', 1)
                                    ->condition('title', '%'.db_like($string).'%', 'LIKE');
            $nids = $query->execute();
            $result = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($nids);
 
            // Format results found as json.
            foreach ($result as $row) {
                $matches[] = ['value' => $row->nid->value, 'label' => $row->title->value];
            }
        }
        return new JsonResponse($matches);
    }
}

Test autocomplete field

  1. Clear your cache.
  2. Open http://your-domain.com/autocomplete_form
  3. Type in a title that can be found in your database.

Screenshot of autocomplete field

Github

  • https://github.com/xuanngo2001/drupal-autocomplete-field.git

About the author

Xuan Ngo is the founder of OpenWritings.net. He currently lives in Montreal, Canada. He loves to write about programming and open source subjects.