How To Create an Ajax Autocomplete Textfield In Drupal 7

26 Jul · by Tim Kamanin · 2 min read

People are lazy by nature and love when something is done for them automatically. As web developers, we can always use this need in our website designs by creating different autocomplete fields to ease website visitor's experience. Being the best CMS platform outhere, Drupal allows us to create autocomplete fields within a blink of an eye. Here's how to do this: Let's imagine, you're building some form where you want to help user with an autocomplete. For example, this can be a "City" input textfield. You can have something similar to the following form:

function module_name_form() {
  $form = array();

  $form['city'] = array(
'#title' => t('City'),
'#type' => 'textfield',
'#autocomplete_path' => 'example/autocomplete',
   );

  $form['submit'] = array(
'#type' => 'submit',
'#value' => 'Save',
  );

  return $form;
}

The most interesting part here is: ' #autocomplete_path' => 'example/autocomplete' which defines an autocomplete callback for our textfield. When user types something into our textfield, Drupal sends a request via this url to send data you input and to receive suggestions via json if there are any. To make Drupal aware of this path, let's add it to the menu system:

function module_name_menu() {  
  $items['example/autocomplete'] = array(
'page callback' => '_module_name_autocomplete',
'access arguments' => array('access example autocomplete'),
'type' => MENU_CALLBACK
  );
  return $items;
}

The last step is to create a _module_name_autocomplete function which will look for a suggestion and return it to the user.

function _module_name_autocomplete($string) {
  $matches = array();

  // Some fantasy DB table which holds cities
  $query = db_select('cities', 'c');

  // Select rows that match the string
  $return = $query
->fields('c', array('city'))
->condition('c.city', '%' . db_like($string) . '%', 'LIKE')
->range(0, 10)
->execute();

  // add matches to $matches  
  foreach ($return as $row) {
$matches[$row->city] = check_plain($row->city);
  }

  // return for JS
  drupal_json_output($matches);
}

In this function we query DB to find a match for a string typed in by a user. I use Dynamic queries (http://drupal.org/node/310075) to get data from a DB, if you feel yourself more comfortable with a SQL approach, feel free to use it as well. The current query is a fantasy one, yours can be a very different from this. If you want for a more advanced example, look in to the Drupal's core taxonomy autocomplete function which can be found in ' modules/taxonomy/taxonomy.pages.inc', line 79: function taxonomy_autocomplete. All in all, I guess now you have an idea about hot to create an autocomplete text field in your custom Drupal 7 module.

Happy Drupal Coding!

Comments

Required for comment verification



Rod Tatham

Thanks for sharing this - very helpful.

In case it helps someone, you need to tell Drupal in your hook_menu that you're loading a form, using 'drupal_get_form' as a page callback. I wonder if that's why stomerfull was not autocomplete working in the text field? Here's an example:

function module_name_menu() { 

// here's the extra bit
$items['here/is/the/form'] = array(
    'title' => 'Here is the form title',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('module_name_form'),
    'access arguments' => array('access user profiles')
);

// end of extra bit
$items['example/autocomplete'] = array(
    'page callback' => '_module_name_autocomplete',
    'access arguments' => array('access example autocomplete'),
  'type' => MENU_CALLBACK
);

return $items;

Thanks again!

Reply · 2 years, 1 month ago
Kirti

I have implemented autocomplete for 4 fields in my form. i.e treatments, services, city and area all are terms. Base on this example I can write any treatment name and get result. What I am aiming is how can I create treatment prefilled, once form load and click on treatment it need to show all the terms and if I search for treatment then it should suggest me as well. My client is looking similar to http://wahanda.com

I would appreciate if you can help me or provide piece of code. That help me a lot.

Thank you for sharing such article.

Reply · 2 years, 5 months ago
Mac0s
return drupal_json_output(drupal_map_assoc(db_select('cities', 'c')
->fields('c', array('city'))
->condition('c.city', '%' . db_like($string) . '%', 'LIKE')
->range(0, 10)
->execute()
->fetchCol()));

not correct:

->condition('c.city', '%' . db_like($string) . '%', 'LIKE')

correct:

->condition('c.city',db_like($string) . '%', 'LIKE')
Reply · 6 years, 4 months ago
Garik

Thanks for the recipe! Tell me, please, how to pass an additional argument to the _module_name_autocomplete? For example, to restrict the search for the terms of taxonomy I want to pass to the function vid of vocabulary.

Reply · 6 years, 4 months ago
monika kadam

Thank's your code works perfectly fine.... :-)

Reply · 6 years, 4 months ago
wilzonm

as show where show, example please?

Reply · 6 years, 4 months ago
Ruchira

Wan to know how to use that form. Thanks

Reply · 6 years, 4 months ago
stomerfull

Hello , Not able to get autocomplete working where user is not logging (anonymous) Thanks in advance for your help

Reply · 6 years, 4 months ago
Marco

Thanks! Your code for autocomplete textfield worked perfectly, but how to implement that in a block ? A block is published in various paths... Best regards.

Reply · 6 years, 4 months ago
Jayaram

How do i filter autocomplete results based on content type? I want the user to select the filter type.

Reply · 6 years, 4 months ago
baobao

Thanks :)

Reply · 6 years, 4 months ago
ryan

re: the problem I reported here a few minutes ago, I posted a solution/workaround at http://drupal.org/node/854216#comment-5681368 No doubt it's not a problem with the code on this page. Perhaps a bug in Drupal. Not sure.

Reply · 6 years, 4 months ago
ryan

Not working for me. In firebug I'm seeing... uncaught exception: Syntax error, unrecognized expression: #

Reply · 6 years, 4 months ago
kkatusic

Nice tuts, but how can I append new city, not replace? Thx

Reply · 6 years, 4 months ago
Vadim

On a simple page it work great, but what to do in the case if I output a page in a modal window using fancybox ?

Reply · 6 years, 4 months ago
SomethingOn

I followed your code for a hook_form_alter and it worked perfectly, BUT when I tried adding the code to a custom module (block with a form in it) the form shows up but the auto-complete isn't working. Looks like the autocomplete JS library isn't there. Is there something I have to tell Drupal in my_modue_init or something to make sure it loads the necessary libraries?

Reply · 6 years, 4 months ago
Kelly

Since there was a hole in the Drupal documentation, I adapted this to drupal.org and attributed this page, please check out http://drupal.org/node/854216 for more info.

Reply · 6 years, 4 months ago
Kelly

Finally...Thanks for sharing. I have been looking for sometime on how to make an autocomplete field in Drupal 7 using the database api. I have found a ton of examples, but yours was the only one that was using the "propper" db api way. Should be on the Docs page at drupal.org.

Reply · 6 years, 4 months ago