Monday, December 25, 2006

jquery: tweaking auto-complete plugin for multiple words in a single input

If you have composed mails in gmail, then you would know that it allows to select multiple auto-complete email addresses separated by commas. That's what I want to implement in jquery auto-complete plugin. Currently it works like google suggest, allowing only one auto-complete word.

If you haven't used JQuery before, I suggest you to go over the site and see some examples and try some.

Well JQuery is the first javascript framework that I have ever used and got stuck with its beauty. Later I came to know about similar javascript frameworks like prototype, scriptulous. But now I am used to jquery. The another beauty is there are many third party plugins.

I extended the auto-complete plugin so that now it allows to choose the auto-complete mode - multiple or single. With multiple, it will work like gmail compose and with single it works like google suggest. Well single is what the original plugin provides. I will explain the changes done to achieve multiple mode.


$.fn.autocomplete = function(url, options) {
...
options.mode = options.mode || "single";
options.multipleSeparator =
options.multipleSeparator || ",";
...
}
The default mode is single. If you pass 'multiple', now it should work like gmail compose. multipleSeparator separates the multiple words. The default is comma. Try to pass different parameters when you initialize the function.

$(document).ready(function() {
$("#suggest").autocomplete('search.php', { minChars:1,
matchSubset:1, matchContains:1, cacheLength:10,
onItemSelect:selectItem, formatItem:formatItem,
selectOnly:1, mode:"multiple",
multipleSeparator:"|" });
});

When the item gets selected, you need to find whether it's multiple or single. If it's single, you don't need to do anything. But for multiple, you have to search for the separator and append the selected new value to the old one in the selectItem(...) function.
function selectItem(li) {
...
if(options.mode == "multiple") {
old_value = $input.val();
if(old_value.lastIndexOf(options.multipleSeparator) >= 1) {
sep_pos = old_value.lastIndexOf(options.multipleSeparator);
value = old_value.substr(0,sep_pos+1);
new_value = value + v +options.multipleSeparator;
} else {
new_value = v + options.multipleSeparator;
}
} else {
new_value = v;
}
...
}
The plugin use ajax to fetch the items from either file or database. For that it needs to construct url on its own. If you type 'a', then the url will be http://abc.com/search.php?q=a and it fetches data from that url. However when we are in multiple mode, the input will contain something like "ant,b", in this case, the constructed url will be http://abc.com/search.php?q=ant,b. Since only "b" needs to be passed , the text before comma should be excluded. So this needs some tweaks in the makeUrl(...) function.
function makeUrl(q) {
if(options.mode == "multiple") {
if(q.lastIndexOf(options.multipleSeparator) >= 1) {
sep_pos = q.lastIndexOf(options.multipleSeparator);
q = q.substr(sep_pos+1);
}
}
...
}

The package, containing jquery and modified auto-plugin code, can be downloaded from here.
Click here for the original auto-complete source.

10 comments:

kumarldh said...

have u seen YUI, man am n confusion, i use prototype rit now, issue with prototype was lack of documentation, which has been covered by the new site they have developed. now one my of client says jquery is best, i really dont kno and cant compare these 2 until unless i use both, crap.

anjesh said...

I haven't used YUI and also not prototype. I can't say which one is best. So far jquery satisfies my needs and haven't demanded me for other frameworks.

Dylan said...

I've used both YUI with prototype and jquery extensively. jQuery has a much wider, more open development community surrounding it, seems less problematic, more extensible and much lighter. I've moved all my application development away from YUI and toward jQuery.

Just found your auto-complete -- looking forward to trying it out.

Dylan
UCSD School of Medicine

Anonymous said...

I like your autocomplete jQuery plugin, but your documentation is a little sparse, especially considering the original author decided to provide no documentation. I was hoping you could provide a little more detail on the options in your script.

Also, this script doesn't work if you select "mustMatch:1" because selectItem keeps being called by hideResultsNow and it is an infinite loop.

Jökull Sólberg Auðunsson said...

I wrote something very similar on my own. Here is the code that removes the last word and appends the chosen word.

var taginput = ("input.selected")[0];
var tag = $("#suggestions li.selected")[0];
words = taginput.value.split(" ");
words.splice(-1,1,tag.innerHTML);
$(taginput).val(words.join(" "));

floehopper said...

mycodes.schtuff.com doesn't seem to exist any more. Any chance you could post your code somewhere else? Thanks.

Matt said...

It is still there on mycodes.schtuff.com. You have to click on the weird unmarked icon underneath the "announcement" icon.

Paulo Fernandes said...

link is broken.

sourceboy said...

broken link

CheetahTech said...

LINK IS BROKEN!!!!