Update 2014-02-19: See LittleDynamo’s comment with a link to this StackOverflow answer.
Update 2014-02-11: See Claus’ comment below for a better way to do this.

Drupal autocompletion is easy – just add #autocomplete_path to a Form API element, set it to something that returns a JSON hash, and off you go.

What if you want to pass form values into your autocompletion function so that you can filter results?

Searching, I found some pages that suggested changing the value in the hidden autocomplete field so that it would go to a different URL. However, that probably doesn’t handle the autocomplete cache. Here’s another way to do it:

You can also override these methods in a JS file you create yourself as long as it is loaded after misc/autocomplete.js. That’s a safer and definitely more preferred technique.

user

hi

http://sachachua.com Sacha Chua

Yup, that’s what I did – I put the custom code in a Javascript file that I included after misc/autocomplete.js. =)

Will Hartmann

Thanks. This was very helpful, but to get it to work, I also had to copy Drupal.ACDB.prototype.search() from autocomplete.js into my custom JS file and remove the encodeURIComponent(). Otherwise, the / between the first and second argument gets encoded into /.

Also, make sure your custom JS file loads after the autocomplete.js by adding a weight to the drupal_add_js().

checked if the args are set in the right order
my_autocomplete_path_function(arg1, arg2, arg3, ..., $string) {
}

I also made the change like Hartmann said: removed the encodeURIComponent

Frippuz

Great post Sacha!

If you want to use this to add or replace existing autocomple functionality in a multi value field, you will need a way to separate the form elements containing the custom-autocomplete properties. Without this addition the searches will contain values from ALL the field instances using ‘custom-autocomplete’ => ‘filter’.
You will for example get a search URL like this: orange/orange/orange/apple/gold instead of just apple/gold

Drupal.ACDB.prototype.customSearch = function (searchString, index) {
// loop through all elements with the filter attribute and add them to the string
jQuery.each(jQuery("[custom-autocomplete=filter]"), function(i,v) {

Thanks for this post, I referred to it several times and it’s still helpful two and a half year later :-)

Maybe this helps someone: for a related use case, I overrode the search function in Drupal.ACDB.prototype. By tying the override to the document.ready event I didn’t have to ensure that misc/autocomplete.js got included before my code:

This unbinds all events, not just those added by autocomplete.js. Even if you control all code on the site, it has the potential to break browser plugins and user scripts. Sorry for criticizing it without offering a solution, but I felt a need to advise against that kind of coding :/