Last updated May 17, 2009. Created by oadaeh on December 28, 2005.
Edited by bekasu, Steven, nedjo. Log in to edit this page.

See this for an extension to this tutorial for more complex form handling in the module builders' forum

This tutorial will lead you through the steps of implementing an autocomplete textfield in your module.

Autocomplete is implemented in Drupal through AJAX. When users type into a textbox, code on the client page dynamically loads new data from the server (a Drupal website) and uses these data to update the user display (provide a drop-down list of matching options, which the user can select from).

Handily, all the mechanics of exchanging data between client and server and of updating the display are handled by the widget, autocomplete.js. Implementing a particular autocomplete textfield requires two parts: (a) a caller (the textfield, with special additions) and (b) a handler, which is a PHP function that parses the request and returns a response.

Prebuilt autocomplete functions

Two autocomplete functions ship with the Drupal core. Each is referenced by an "autocomplete_path"--the uri to which autocomplete requests are sent.

  • user_autocomplete()
    Use this function to load matching user names. Autocomplete path: user/autocomplete.
  • taxonomy_autocomplete()
    Use this function to load matching taxonomy terms from a given vocabulary. Autocomplete path: taxonomy/automplete.

If one of these matches your needs, then all you need to do is include the special #autocomplete_path selector in a form field. Here's an example for user autocomplete (from comment.module):

<?php
  $form
['admin']['author'] = array(
   
'#type' => 'textfield',
   
'#parents' => array('author'),
   
'#title' => t('Authored by'),
   
'#size' => 30,
   
'#maxlength' => 60,
   
'#autocomplete_path' => 'user/autocomplete',
   
'#default_value' => $author,
   
'#weight' => -1
 
);
?>

For taxonomy autocomplete, you include a vocabulary id, as in this example from taxonomy.module:

<?php
  $form
['taxonomy']['tags'][$vocabulary->vid] = array(
   
'#type' => 'textfield',
   
'#default_value' => $typed_string,
   
'#maxlength' => 100,
   
'#autocomplete_path' => 'taxonomy/autocomplete/'. $vocabulary->vid,
   
'#required' => $vocabulary->required,
   
'#title' => $vocabulary->name,
   
'#description' => t('A comma-separated list of terms describing this content (Example: funny, bungie jumping, "Company, Inc.").')
  );
?>

Building a custom autocomplete function

If you want to make your own autocomplete function to answer a need not already met, there are a couple of additional steps.

  • Write a handler function. This will receive an autocomplete request and return data to the client in a form ready to be parsed by automplete.js.

    user_autocomplete() is a good model:

    <?php
    /**
    * Retrieve a pipe delimited string of autocomplete suggestions for existing users
    */
    function user_autocomplete($string) {
     
    $matches = array();
     
    $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10);
      while (
    $user = db_fetch_object($result)) {
       
    $matches[$user->name] = check_plain($user->name);
      }
      print
    drupal_to_js($matches);
      exit();
    }
    ?>

    Note that you are (a) finding matching records based on user input (b) constructing an array of matches (c) converting the array to JavaScript code and (d) outputting the results.

    Also note that we need to escape the user name in the $matches array's values: this is because the values are HTML. Not escaping would open up XSS holes. On the other hand, it also means that you can mark-up the autocomplete suggestions any way you like (for example, by adding a small user picture to each match).

  • Create a menu path to your function.
    Users need to be able to reach your handler. The user_menu() lines are:

    <?php
      $items
    [] = array(
       
    'path' => 'user/autocomplete',
       
    'title' => t('user autocomplete'),
       
    'callback' => 'user_autocomplete',
       
    'access' => $view_access,
       
    'type' => MENU_CALLBACK
     
    );
    ?>
  • Reference your path in form textfields.
    Having put a handler in place, you can now reference it as an autocomplete path in form fields, as with the existing user/autocomplete and taxonomy/autocomplete handlers.

Security note: make sure your autocomplete handler has appropriate menu permissions set on it, and respects existing access control mechanisms. Otherwise, you might be exposing sensitive information through the autocomplete.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

You may use the following which will work in most situations.

<?php
print drupal_to_js($matches);
exit();
?>

Very similar and almost the same:

<?php
drupal_json
($matches);
?>

Only problem is: drupal_json uses drupal_set_header to print out some headers. Which could cause issues in some servers such as an HTTP Error 0 pop-up in javascript. It may have to do with https:// I'm not sure.

Also:

<?php
$r
= db_query("SELECT name FROM {users} WHERE name LIKE LOWER('%%%s%%')");
?>

Would work better if you need people to search names without knowing what it starts like. Not everyone remembers the first few characters. Could possibly add a bit more time on your load.

E.g.: name: zzZZZzzzBob155
So user can search 'Bob' to find it.

-
CE - VT