Last updated 1 October 2018. Created on 14 July 2010.
Edited by alvar0hurtad0, konordo, kapacs, aquadrop. Log in to edit this page.
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 this 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/autocomplete.
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):
$form['admin']['author'] = array(
'#type' => 'textfield',
'#title' => t('Authored by'),
'#size' => 30,
'#maxlength' => 60,
'#autocomplete_path' => 'user/autocomplete',
'#default_value' => $author,
'#weight' => -1,
);
For taxonomy autocomplete, include a vocabulary id, as in this example from taxonomy.module:
$form['taxonomy']['tags'][$vocabulary->vid] = array('#type' => 'textfield',
'#title' => $vocabulary->name,
'#description' => $help,
'#required' => $vocabulary->required,
'#default_value' => $typed_string,
'#autocomplete_path' => 'taxonomy/autocomplete/'. $vocabulary->vid,
'#weight' => $vocabulary->weight,
'#maxlength' => 1024,
);
For Drupal 7 the taxonomy_autocomplete function takes as parameter the field_name, which is the name of the term reference field. This is the field name of term reference assigned to entity(i.e. node) to be edited. A quick verification may help by manually making a request via http://site.com/taxonomy/autocomplete/@field_name from a browser. If it returns '[]' then it is working, otherwise. It will provide an error message that can help troubleshoot further.
Example
$form['example'] = array(
'#type' => 'textfield',
'#title' => t('This is the Title'),
'#autocomplete_path' => 'taxonomy/autocomplete/<strong>taxonomy_vocabulary_1</strong>',
'#maxlength' => 30,
);
where taxonomy_vocabulary_1 is the machine name of the taxonomy reference field.
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.
The form
The form will contain an element such as
$form['city'] = array(
'#type' => 'textfield',
'#title' => 'City',
'#maxlength' => 128,
'#autocomplete_path' => 'cities/autocomplete',
);
Addition to hook_menu
You must add #autocomplete_path to your hook_menu function.
function cities_menu(){
...
// Path with autocomplete function for cities.
$items['cities/autocomplete'] = array(
'title' => 'Autocomplete for cities',
'page callback' => '_cities_autocomplete',
'access arguments' => array('use autocomplete'), //or whatever permission makes sense
'type' => MENU_CALLBACK
);
return $items;
Make a call to the Database, D6 Version
Write the handler function. This will receive an autocomplete request and return data to the client in a form ready to be parsed by automplete.js.
/**
* autocomplete helper
* $string = string for search
*/
function _cities_autocomplete($string) {
$matches = array();
//search table `cities` for cities that begin with the letters the user enters in the form
$result = db_query_range("SELECT city FROM {cities} WHERE LOWER(city) LIKE LOWER('%s%')", $string, 0, 10);
// add matches to $matches
while ($data = db_fetch_object($result)) {
$matches[$data->city] = check_plain($data->city);
}
// return for JS
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 city 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.
Make a call to the Database, D7 Version
If you on Drupal 7, and want to use the Database API, your code would look slightly different.
/**
* autocomplete helper
* $string = string for search
*/
function _cities_autocomplete($string) {
$matches = array();
$result = db_select('cities', 'c')
->fields('c', array('city'))
->condition('city', '%' . db_like($string) . '%', 'LIKE')
->execute();
// save the query to matches
foreach ($result as $row) {
$matches[$row->city] = check_plain($row->city);
}
// Return the result to the form in json
drupal_json_output($matches);
}
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.
Adapted from http://drupal.org/node/208424#comment-686252, http://drupal.org/node/42552 and http://timonweb.com/how-create-ajax-autocomplete-textfield-drupal-7
Additional example for D6: http://digitalillusion.altervista.org/wordpress/2009/01/12/drupal-6-link...
Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.
Comments
New callback
I've replaced:
print drupal_to_js($matches);
exit();
with:
drupal_json($matches);
with good results.
Reference: http://drupal.org/update/modules/6/7#rename-drupal-to-js
Log in or register to post comments
I can't get it to work!
This is driving me nuts. I've tried to make a custom autocomplete function as described above. Did not work. Then I copy and pasted the whole code (of course I put it into the appropriate functions). I created a table 'cities' with several entries for 'city'. Did not work.
When I use user/autocomplete, it's working fine. If I change it to cities/autocomplete then I don't get the small autocomplete circle or anything.
It simply won't work.
Am I stupid or is there something wrong with the code? Please help, I'm slowly despairing =/
Log in or register to post comments
Solved it
Wow, after slaving for hours I find the solution a couple of minutes after I comment here.
The code above does indeed need changing. The code that belong into the hook_menu requires a 'return $items;' at the end. The author of the above tutorial probably overlooked this.
edit: I amended the code in the tutorial accordingly
Log in or register to post comments
Great Walkthrough
I was hitting a wall about autocomplete and how I couldn't get mine to work.
Then, I found the small glitch.
This didn't work:
This did:
The difference is that the path had to not have a leading slash.
Log in or register to post comments
For Drupal 7 code is
For Drupal 7 code is something like this.
where field_tags is taxonomy field in node with widget type autocomplete.
Log in or register to post comments
Thx, works like a charm !
Thx, works like a charm !
Log in or register to post comments
Path should not start with search/...
Do not start your Path with search as in "search/yourlistpath". This will not work because it triggers a Search. Obvious only to those who know ;)
Log in or register to post comments
The textfield needs an id.
I was seeing this error in firebug:
I also saw a notice in Drupal referencing line 3707 of forms.inc. This is in Drupal 7.12.
If I add an id to the city field in hook_form, the errors go away...
Log in or register to post comments
Thanks arnoldbird
I was having trouble with this for hours. All of the tutorials I encountered have very specific syntax, which I followed.
My autocomplete fields would not get any results until I read this and added the unique ID.
Log in or register to post comments
Autocomplete example for custom text field
Log in or register to post comments
Thanks!!!
Thanks arnoldbird!!! I had the same issue with
and adding the '#id' parameter solved it. ...using Drupal 7.23
Log in or register to post comments
OMG, thank you! ID is MANDATORY
The #id property appears to be mandatory if you want you user entity reference autocomplete to work at all. Thanks!
Log in or register to post comments
[Resolved]How to implement that in a block with various paths
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.
Log in or register to post comments
I added a field radio with
I added a field radio with two options: "user" or "title".
When this field is selected, the autocomplete should display its content.
How to do this?
Thanks
Log in or register to post comments
An approach suggested by
An approach suggested by nevets:
Thanks!
Log in or register to post comments
Just a little more detail please
I am a recent convert from DotNetNuke to Drupal. So I would really appreciate some more help with this feature.
I have 2 questions -
1. $form['city'] = array(... Does this portion add a text box? I already have a text box in my code for the "Content". How can I adapt this to that textbox (input)?
2. Do the addition to hook_menu and the callback function go in system.api.php? Or should I be adding it somewhere else?
Thank you for your replies
Sai
Log in or register to post comments
How can this be modified to getting data from a remote server
How can the autocomplete form be modified in order to be bring the information from a remote server (e.g. accessing it via a URL) doing like a REST request, instead of getting the information from a local database? Any pointers would be really appreciated. Thank you!
Log in or register to post comments
Nice documentation. Saved my
Nice documentation. Saved my time.
Thank You,
Shashwat Purav
Log in or register to post comments
Drupal 8 Issue
MMMM is drupal 8 core auto complete broken or am i just wrong...
code
in form:
this gives me a strange error JSON gives correct value but
JS says ....
TypeError: suggestions.indexOf is not a function
var index = suggestions.indexOf(tagged[i]);
this is correct because suggestions is an object ..... what is a fella to do now :(
Log in or register to post comments
MY bad Drupal 8 is ok !
Log in or register to post comments
Jesus"Uncaught TypeError: Cannot read property 'form' of undefin
For the record, today is Christmas! And thanks to all the truth seeker before me! It's been hell of hours to have had a blade in my teeth to try to figure out wt..
"Uncaught TypeError: Cannot read property 'form' of undefined" which caused by autocomplete used in a custom form which try to render itself, then the #id must be there plus the form['xxx'] must be the same as the #id
$form['edit-keyword'] = array(
'#id' => 'edit-keyword',
'#type' => 'textfield',
'#default_value' => '',
'#autocomplete_path' => 'n-search/autocomplete',
);
Right after adding the #id, it's a merry Xmas all of a sudden!
Log in or register to post comments
来自 https://www.drupal.org/node/854216
forms api autocomplete
I'm trying to make a module that will incorporate an autocomplete feature.
I a form setup, where you go to say, www.domain.com/?q=create
and you get this form:
I got the section for "'#autocomplete_path' => 'user/autocomplete'" from the forms api, but it isn't very useful. I have no idea what that's being autocompleted with. I want to autocomplete with fields from a specific field in a table custom to my module. I have the table {dae_course} with columns (id, course_code, course_number, course_name). In the form, where the user is entering the course code, I want it to autocomplete with data from {dae_course}.course_code.
How do I set this up?
⋅ Categories: Drupal 6.xLog in or register to post comments
Comments
Check this out.
I think that's what you are looking for http://drupal.org/node/147029 .
It explains how to autocomplete a form fields. I never implemented that but as far as i can see what you are doing is right but you need to implement the autocomplete.module and map there the path you defined on #autocomplete_path.
I'm spanish and my english sucks, so I'm sorry if you couldn't understand something. Tell me if you need a better explanation.
Log in or register to post comments
I'm trying to follow this, as
I'm trying to follow this, as loosly as possible, but having problems.
I want this to be integrated into my module that already exists, so I'm not sure about what I'm doing. I don't want to have to make a new autocomp module, just put the code into my module. And I already have a hook_menu, which is this
Each part of $items is already an existing form. For example, the one I'm trying to get the autocomplete to work for is the submit/course.
Here are my 3 functions for the form, including the coursecode_autocomplete function I'm attempting to have functional.
I just don't want to have to put the autocomplete functions outside my module. As far as I can tell, it should be somewhat close to actually working though... But I'm not even getting the autocomplete circle to the right.
Maybe you can see what's wrong? just tell me if you need more information than I currently provided, but that should be all the relevant functions.
thanks
Log in or register to post comments
Do it.
You don't want to implement it to a separate module and you don't have to. You can do it into the same form module. But what you need is to create a new menu entry in your module with the path that you has at the autocomplete_path. Something like that.
Now your path exists and is mapped to your function. You should check the post i gave to you, it's a good example.
I hope this help.
Log in or register to post comments
Ah, that's good to know. I
Ah, that's good to know. I guess I was a bit thrown off from the instructions where it says stuff like "Create a folder "autocomp" in your module folder. path chould be something like this: \sites\all\modules\autocomp
and put the following in it.". Implying that you need to make a new module.
So I have now followed the tutorial, but I can't seem to get it to work. I've tried changing function names and everything.... Maybe it's something small I'm overlooking from being a new developer for drupal.
But even when I use the exact same code, I don't get anything. Clearly I don't want it to return usernames, but I was doing that as a test. That it's self isn't bringing anything up. Maybe it's some sort naming convention I didn't quite pick up on, where the example code would only work on the example module? Here's what I have anyway
Select, relevant parts anyway
Anything standing out to you as to why this wouldn't work? Also, I tried the if($may_cache), it didn't make any difference. And from a quick reading on the arguement, I don't think I need that in my code.
Log in or register to post comments
Your menu definition is a
Your menu definition is a Drupal 5 menu definition, and has lots of errors in it even for a Drupal 5 menu. It should look like this:
Log in or register to post comments
thanks
that actually does look more in-line with what I learned from other sites. I was following the tutorial, which must be for drupal 5 then?
But I still don't get anything to come up from the autocomplete. It's not even getting the circle on the right hand side indicating that it hasautocomplete (if it even should for a custom one?)
Log in or register to post comments
Did you clear your cache? If
Did you clear your cache? If the path doesn't exist, the circle won't show. If the cache isn't cleared, the path won't exist.
To test to see if your callback function is working and the path is correct, access:
site.com/autocomp/myautocomp/somestring
where site.com is your actual domain name.
Log in or register to post comments
Sort of? I'm not seeing
Sort of? I'm not seeing anything, but the page does exist. I get an access denied message. I'm assuming because there's nothing defined to actually be shown on the page? But I did flush all cache before trying
Note* I am logged in as account #1, which as far as I understand, should have full permissions for everything.
Log in or register to post comments
In that case, change this
In that case, change this line:
to this:
Log in or register to post comments
Problem still persists. Is
Problem still persists.
Is there some sort of permissions setting I need to add to my module?
This is what my .module file has
hook_access ( I tried commenting that out, just to see if that was a problem)
hook_menu
myautocomp
courseTeachSLO_page
slo_page
slo_form
.
.
.
bla bla, and a few other functions to show some forms (which work no problem, except the autocomplete aspect)
Log in or register to post comments
Title with t().
And give the title with a t() function.
Log in or register to post comments
ya, I updated that already.
ya, I updated that already.
thanks though :)
Log in or register to post comments
I hate to sound like a broken
I hate to sound like a broken record, but did you clear your cache?
And you don't use t() on menu titles. t() is the default 'title callback' that is used if a title callback is not specified. If you wrap your title in t(), it gets translated twice.
Log in or register to post comments
Yes. I flushed all cache
Yes. I flushed all cache several times (I just keep saying to myself "maybe this time it will work). I also removed the t function from the titles.
Log in or register to post comments
t() is default 'title callback'
Do not use t() in 'title' property. Read the API docs.
Log in or register to post comments
Show us your current
Show us your current hook_menu() then.
Log in or register to post comments
here it is
The module needs a lot of forms, so there's going to be some irrelevant information there.
The autocomplete one is the last addition to $items
Log in or register to post comments
That's because this isn't
That's because this isn't what I showed you:
'access' => array('access content'),
Log in or register to post comments
I could have swore it was right
I thought I changed that. I fixed it to be
But I still get access denied (I did flush cache again).
Log in or register to post comments
No 'e' in arguments.
No 'e' in arguments.
Log in or register to post comments
Thaank youu
hours of headaches solved.
Thank you very, very much.
You have absolutely no idea how much I appreciate your help. Especially since it was probably a pain where I had such preventable mistakes (re-typing rather then copy/paste).
Log in or register to post comments
Glad it worked out for you.
Glad it worked out for you.
Log in or register to post comments
It works with this example
Click here : Test Autocomplete form
Regards,
Veera Prasad Dagudu
来自 https://www.drupal.org/forum/support/module-development-and-code-questions/2010-07-06/forms-api-autocomplete