Category Archives: Prototype/Scriptaculous

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]
  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.