Cobalt Edge

 
« Back to blog

Update on Rails, jQuery, autocomplete

Today I changed my auto_complete_jquery plugin (which I blogged about previously) to work with a different jQuery autocomplete plugin (that's not confusing is it?!). Previously, I'd been using the "jquery-autocomplete" plugin, but had been having problems with it always being case sensitive, and with it being pretty darn slow. To solve that, I wound up switching to Dylan Verheul's jquery autocomplete plugin, which is fantastic! So, I had to update my plugin (literally changed two lines, along with the readme and some comments).

So, what does it all mean? First, things are no longer case-sensitive (although you can tweak that if you need it, see the docs for DV's jquery plugin). Second, the speed is near instant, and if it's taking any time at all, there's now a CSS style you can set to show an indicator while the AJAX call is running (nice!). Further, there are a slew of options you can set, but one of the coolest things is the ability to set a formatter JavaScript function to adjust the display of the returned results, but without affecting the actual value that is placed in your text field. This is really cool for providing further information about a given matched item. For example, I use it to display, on a line below the matched name, the location of the item. There's an interactive example of this on Dylan Verheul's site.

I highly recommend updating all around on this. For those that might be using my prior version, the changes you'd need to make are:


  • Change your JavaScript calls that make a HTML input into an auto-complete from this format:
    $("input#post_title").autocomplete({ ajax: "auto_complete_for_post_title" })

    to this:
    $("input#post_title").autocomplete("auto_complete_for_post_title")


  • Update to the HEAD of my plugin.

  • Remove the old jquery.ui.autocomplete*.js files, and install Dylan's single jquery.autocomplete.js file, updating your JS includes accordingly. Same goes for the stylesheet.

Note, to do the cool 2nd line output of auto-complete items, you will need to write your own auto-complete Rails action, which means you don't need my plugin :) I may update my plugin at some point so you can pass a block in to the autocomplete function to create this same scenario, but this is pretty specific stuff, so we'll see. As a very brief set of instructions to do this, you can essentially copy-paste the auto-complete method that gets defined by my plugin, and then update what you return as text. To do the 2nd line bit, you want to return items in the format, "item|2nd line stuff", (so use the pipe symbol to separate the two lines). Then, you can use a simple JavaScript formatter function like:

function formatAutocompleteItem(row) {        return row[0] + "<br><i>" + row[1] + "</i>";}

Then, update your call to the jQuery autocomplete that sets up a field as autocomplete to be:

$("input#post_title").autocomplete("auto_complete_for_post_title", { formatItem:formatAutocompleteItem })

Enjoy!

Comments (3)

May 16, 2010
John said...
Hello, thanks a lot for this plugin. I set it up according to the instructions yet I am getting this error.

ActiveRecord::RecordNotFound (Couldn't find Story with ID=auto_complete_for_story_tag_list):
cancan (1.1.1) lib/cancan/controller_resource.rb:22:in `find'
cancan (1.1.1) lib/cancan/resource_authorization.rb:27:in `load_resource'
cancan (1.1.1) lib/cancan/resource_authorization.rb:18:in `load_and_authorize_resource'
cancan (1.1.1) lib/cancan/resource_authorization.rb:7:in `send'
cancan (1.1.1) lib/cancan/resource_authorization.rb:7:in `add_before_filter'

Have you encountered this before? It would be greatly appreciated if you could help. Thank you!

May 17, 2010
John, honestly, I don't use the plugin anymore. I found that my needs for autocompletes were usually far more specific that just pulling a generic database column, and thus the plugin was hardly used, if at all, and just overhead. If you look at what you need to do to implement an autocomplete, it's pretty simple, so often it's just as easy to write it yourself, and then easier to debug. Also, I use a different jQuery plugin than when this was written. So, a few notes:

- First, from your message, it looks like you're using the CanCan authentication plugin. And, maybe whatever controller you have it for is set to authenticate all actions, but maybe you don't want authentication on your autocomplete (maybe, I don't know the context, but that's what it looks like), so you may need to disable CanCan for the autocomplete action.

- I'd recommend either using the autocomplete plugin that comes with jQuery UI 1.8, if you're using that version of jQuery UI, or use the "Bassistance" autocomplete jQuery plugin (which is what I use), as it has more features and flexibility. The Bassistance one, is here: http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
I also have been keeping a few notes on the Bassistance one, as it does have a few quirks: http://gist.github.com/394193

- Write your own autocomplete method. You can start with what's in the plugin, although that can likely be optimized. I also find that for our use, I do things like strip out various punctuation (which can also cause problems in various SQL DB's if you send that through).

May 17, 2010
John said...
Thanks Chris,

I appreciate the thorough response. I did see that Can Can was giving me issues. I will check out the ones you mentioned and I also did look through the plugin code and had some fun with it. Thank you!

I will most likely end up writing my own for the learning experience. : )

Leave a comment...