Using Autocompleter.Local with Ajax Lists

The Autocompleter suite of functions in Scriptaculous are pretty nice. While they don’t solve every autocomplete problem straight out, they do provide a good starting point.

However, the answers to problems in Javascript are not always obvious. Despite some amazing support from Firebug, debugging is often difficult and tracing down problems can be rough.

Earlier this week, I ran into a very strange problem with Autocompleter.Local. I was designing a page that would query the server for a list of cities in a state and load that list into the Autocompleter. The catch was that the state could be changed at any time by the user, and the array containing the list of cities available would be updated asynchronously from the server. (While there is an Autocompleter.Ajax for automatic server updates, this assumes the autocompletion is done on the server side which I deemed too slow to be very functional in our case.) The specific issue I was having was that the city name was inserted into the target text field multiple times as the number of hits to the server for updated city lists increased.

I discovered, after looking over code in control.js, that the Autocompleter attaches event observers every time it is newed up. These event observers are difficult to remove manually because they pass in states of the specific object that are often no longer available. I had code that was doing something like:


[get list of city names for a state into cityNameList]
if(!autocompleter)
  autocompleter = new Autocompleter.Local('cityTextfield', 
   'cityAutocompleteList', cityNameList);

but the the observers that the Autocompleter was creating were being piled up on each other every time I “reset” the Autocompleter to a new instance.

I discovered that the Autocompleter data is stored in the .options.array field. While it is not documented as part of the API, updating this array effectively updated the Autocompleter without adding new event observers. All I had to do was new up the Autocompleter variable once and then update this array field (directly; using dot notation) every time the data from the server changed.

Advertisements

About johnnywey

Welcome to A Regular Expression. This blog is designed to reflect my thoughts on life, music, software design, Apple, faith, philosophy, and whatever else I can think of.

Posted on January 14, 2009, in Programming, Prototype/Scriptaculous. Bookmark the permalink. 2 Comments.

  1. This post was very useful for me.
    I had a select box with two options: Debit and Credit.

    Every time the user changed the selected option the following function was called in my code:

    function createAutocompleter() {
    var type = $(‘type’).value;
    if (type == ‘D’) {
    new Autocompleter.Local(‘…’, ‘…’, debitCategories, {choices:7});
    } else {
    new Autocompleter.Local(‘…’, ‘…’, creditCategories, {choices:7});
    }
    }

    And every time ‘new Autocompleter.Local…’ was executed I had the same problem you describe in your post.

    Your post help me to solve the problem.

    Thank you.

  2. Great had the same problem and it was driving me nuts, thanks a lot!!!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: