Drupal Forms API: demystifying autocomplete fields
http://www.centurionwebdev.com/content/drupal-forms-api-demystifying-aut...
One of the coolest features of the Drupal 6 forms API is being able to set up your own autocomplete fields. Initially I had a hard time figuring these suckers out so I'm going to try to explain how they work.
Overview
Before we get into the code let's take a quick look at what's going on when an autocomplete field does it's thing. When you start typing in an autocomplete field it sets off a chain of events:
* The text you've entered is captured and sent to the server via AJAX
* The text is examined against a list of possible values. Any matches are bundled up for transport
* The list of matches is sent back to the form and are listed to the user
Fortunately Drupal's form API handles the form rendering and AJAX for us automatically, we just need to tell it where to send the user's input and how to test that input for matches. There are three main bits of code to an autocomplete textfield that makes it tick:
+ the field code
+ a menu item
+ a callback function
The field code
If you've worked with the Drupal form API at all you should be familiar with coding a field. Here's a quick example of a standard text field:
$form['text'] = array(
'#type' => 'textfield',
'#title' => t('enter some text'),
'#description' => t('some text entered by the user'),
);
This code snipped should produce a standard text field with a title and description. Nothing fancy. But let's say we want to convert our text field to autocomplete. To do that we need to tell the field where to look for possible matches. We can do that by adding an autocomplete path to the field like so:
$form['text'] = array(
'#type' => 'textfield',
'#title' => t('enter some text'),
'#description' => t('some text entered by the user'),
'#autocomplete_path' => 'match_my_text',
);
Simple enough, but what does autocomplete_path actually do? This path is where the field will send the user input (via AJAX) to get a list of possible matches. This is where the menu system comes into play.
The Menu Item
To get a any kind of path set up in Drupal you need to use the menu system to register it. This means we need to add an item to hook_menu() that's acts as a placeholder for our autocomplete path.
$items['match_my_text'] = array(
'title' => 'text matching',
'page callback' => 'text_autocomplete',
'access callback' => array(TRUE),
'type' => MENU_CALLBACK,
);
Now when ?q=match_my_text (or /match_my_text if you have clean urls enabled) is referenced our custom text_autocomplete() function is returned. Let's take a closer look at what that function does.
The callback function
Page callback tells the menu system what function should be called when this menu item is visited so now that we have a menu item we need to write the function that it calls, in this case text_autocomplete().
function text_autocomplete($string=''){
$matches = array();
if($string){
/*user input has been passed to the function, let's
see if it matches anything*/
$possible_values = array(
'goth',
'steampunk',
'cosplay',
);
foreach($possible_values as $value){
if(preg_match("/$string/i",$value){
$matches[$value] = $value;
}
}
}
drupal_json($matches);
}
So this function takes the value the user has typed into our text field (that has been dutifully passed to it via AJAX) and checks to see if it's a partial match for any of the values in an array. This could just as easily be a result set from the database or even another function call. Anyway, for each partial match found that match is added to the $matches array, which is then returned to the caller via drupal_json().
That's pretty much all there is to it.
- Login to post comments