6098 comments
2357 subscribers
6257 on Twitter
Subscribe! Feed reader E-mail

Drupal: Overriding Drupal autocompletion to pass more parameters

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:

Drupal.ACDB.prototype.customSearch = function (searchString) {
    searchString = searchString + "/" + $("#otherfield").val();
    return this.search(searchString);
};

Drupal.jsAC.prototype.populatePopup = function () {
  // Show popup
  if (this.popup) {
    $(this.popup).remove();
  }
  this.selected = false;
  this.popup = document.createElement('div');
  this.popup.id = 'autocomplete';
  this.popup.owner = this;
  $(this.popup).css({
    marginTop: this.input.offsetHeight +'px',
    width: (this.input.offsetWidth - 4) +'px',
    display: 'none'
  });
  $(this.input).before(this.popup);

  // Do search
  this.db.owner = this;
  if (this.input.id == 'edit-your-search-field') {
    this.db.customSearch(this.input.value);
  } else {
    this.db.search(this.input.value);
  }
}

Drupal.behaviors.rebindAutocomplete = function(context) {
    // Unbind the behaviors to prevent multiple search handlers
    $("#edit-your-search-field").unbind('keydown').unbind('keyup').unbind('blur').removeClass('autocomplete-processed');
    // Rebind autocompletion with the new code
    Drupal.behaviors.autocomplete(context);
}

You’ll need to use drupal_add_js to add misc/autocomplete.js before you add the Javascript file for your form.

Hope this helps!

2011-08-08 Mon 19:16

Short URL: http://sachachua.com/blog/p/22409
  • http://freegeekchicago.org David Eads

    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.

  • 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().

    $path = drupal_get_path(‘module’, ‘my_module’);
    drupal_add_js($path . ‘/my_module.js’, array(‘weight’ => 20));

    See http://api.drupal.org/api/drupal/includes–common.inc/function/drupal_add_js/7#comment-14514

    • http://sachachua.com Sacha Chua

      Will: Thanks for sharing the missing steps! =)

  • Coen Pelckmans

    I made a few changes for more flexibility (Version: Drupal 7)

    In the custom do search in Drupal.jsAC.prototype.populatePopup
    // Do search
    this.db.owner = this;
    if ($(this.input).attr('custom-autocomplete') == 'autocomplete') {
    this.db.customSearch(this.input.value);
    } else {
    this.db.search(this.input.value);
    }

    Changed the customSearch function
    Drupal.ACDB.prototype.customSearch = function (searchString) {

    // loop through all elements with the filter attribute and add them to the string
    $.each($("[custom-autocomplete=filter]"), function(i,v) {
    var element = $(v);
    searchString = element.val() + "/" + searchString;
    });

    return this.search(searchString);
    };

    Added a few attributes to the elements in my form

    addedform['myFilterElement']['#attributes'] = array( 'custom-autocomplete' => 'filter');
    added form['myAutoCompleteElement']['#attributes'] = array( 'custom-autocomplete' => 'autocomplete');

    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

    I solved it like this:
    Add a new #attributes value:

    $form_element['#attributes'] = array ('custom-autocomplete' => 'filter',
    'custom-autocomplete-index' => $index);

    $index can contain anything, just as long as it is different between the field instances. I’ve used the field delta value which works nicely.

    Also add support for this in your jQuery functionality:

    First, change the row: this.db.customSearch(this.input.value);
    to
    this.db.customSearch(this.input.value, index);

    Second, change the customSearch function:


    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) {

    var element = jQuery(v);
    // Extra check to manage forms with multiple field deltas
    if (element.attr('custom-autocomplete-index') == index) {
    searchString = element.val() + "/" + searchString;
    }
    });

    return this.search(searchString);
    };

    I hope the can be of use to someone.

    //Frippuz

    • http://sachachua.com Sacha Chua

      Thanks for sharing!

  • Shinto

    Good !!!!! Thanks :)

On This Day...

  • 2012: Learning more about Android development — From Tuesday: I spent most of the long weekend learning about Android development by working on the MobileOrg for Android [...]
  • 2010: Monthly review: July 2010 — Last month, I said: What will July be like? I want to polish my community toolkit and share it with more [...]
  • 2009: Improv: Catch 23′s Next Act, people-watching — Hat-tip to Taylor for telling me about Catch 23‘s improv event at the Comedy Bar last night. It was a [...]
  • 2009: The sweetness of life — W- and I made apricot syrup. It’s amazing. I’m tempted to go and make pancakes right now. I’m sure they’re fine for [...]
  • 2008: Drupal 5: Migrating a production database to a QA server — Building on the configuration management strategy I described last time, I wrote some scripts to make it easier for other [...]
  • 2008: Deploying to servers — I’m heading to the Philippines tomorrow, and to make life easer for the two other Windows-based PHP developers on my [...]
  • 2007: I survived my defense! — zomg, I’m actually done with the defense. I need to make a few minor revisions, but the bulk of my work [...]
  • 2006: Raided the library — Having discovered the joys of the online book request system, I raided the library for 22 books on various topics including [...]
  • 2006: Time bubble — For some reason or another, my initial “Wow, this has been quite an eventful year” reflection included my stay in Japan. [...]
  • 2005: My Web 2.0 – Yahoo’s social search — Yahoo’s social search engine, My Web 2.0, certainly looks promising. It automatically picks up your Yahoo Messenger contacts and prioritizes their (and [...]
  • 2004: del.icio.us: sachac — http://del.icio.us/sachac: My del.icio.us page. New URLs will be posted there instead of on this blog, because blogging to del.icio.us is slightly more [...]
  • 2004: Myrkraverk’s box — -----BEGIN PGP MESSAGE----- Version: GnuPG v1.2.4 (GNU/Linux) hQEOAzQ6c9jHW5SMEAP/S9ch+peMGLyEn7Cmu0PdVIu3QW7XP75BJDypzQRzhOOh OwONxwtnH3yzkOfrwNxzQVPb5fyfWQgOjtlLZdPeDAxV8uBvj3ysmUwFH0SVSaKX O/wR0mr801hW1kbLR073+J8+Xvz5ioLb+3B1Kt1knaZ1U51XGxTieCaEQ3rpx94E AImExgp+j8Neuv40itenuroVSmM3uFAx1yCvlbc1pDAJOJp//X7AFRPsxwXxFidW rDHojDShCqGzy9CCQ10QfLdc1AswQIf1EP4V+BfYWp4Cg1byoBvjw0+2VEmuW196 rUh+8FyDUaigarCB64/M1fW6E2+0vNZ8SvG8bB77Z6MQ0mEBcuESqr1lrTDACIzs pGGuixg3TRzVflhH0Cf9jwid8je28gOqDUiGAhg/MGFQnroSpGfBVy/tqE227eRP mh6qnBpq9fBr0TcHPAhqjhghlmj7jP0WWl7i+LFZpAvhRRHc =c0jl -----END PGP MESSAGE-----
  • 2004: AOTS confirmed — Incidentally, I really _am_ going on the industry training trip to Japan. I’ll be leaving on August 25.

Get the highlights as a PDF!

Stories from my Twenties: Highlights from a Decade of Blogging

Free sample!