This is in response to a question asked about a jquery autocomplete plugin.
The question was, if you are using this jquery autocomplete plugin how do you get the .autocomplete function to include other fields so that you can have a context type of search. One person (bendewey) answered that you can do the following.
var selectedCategory = $('.categories').val();
var query = '';
if (selectedCategory !== 0)
{
query = '?category=' + selectedCategory;
}
$("#suggest4").autocomplete('search_service.svc' + query, {
// options
});
This is 1/2 correct. The problem is that when .autocomplete() is called, the url + query are evaluated immediately which means that the current (at time of page loading most likely) selected category value will ALWAYS be used when autocomplete is called. That means that if the user selected a different category, the new value will not be passed with the query. Here is a patch to the autocomplete code that will fix it. After running the patch, you will be able to pass a function to your .autocomplete call (instead of a string url) and then each time autocomplete runs, the function will be run to create the right params.
to run patch:
1. cd to the directory where your jquery.autocomplete.js file exists
2. copy the patch file to a file called jquery.autocomplete.js.patch (in the above mentioned directory)
3. run patch < jquery.autocomplete.js.patch
to use the patch:
do what bendewey said above, except for you need to make the 1st arg of .autocomplete to be a function that returns the proper query, like this…
$("#suggest4").autocomplete(function() {
var selectedCategory = $('.categories').val();
var query = '';
if (selectedCategory !== 0)
{
query = '?category=' + selectedCategory;
}
return 'search_service.svc' + query; }, {
// options
}
);
Here is the patch (you can download the file below):
--- jquery.autocomplete.js.orig 2010-01-15 11:00:55.000000000 -0700
+++ jquery.autocomplete.js 2010-01-15 11:04:02.000000000 -0700
@@ -14,7 +14,7 @@
$.fn.extend({
autocomplete: function(urlOrData, options) {
- var isUrl = typeof urlOrData == "string";
+ var isUrl = typeof urlOrData == "string" || typeof urlOrData == "function";
options = $.extend({}, $.Autocompleter.defaults, {
url: isUrl ? urlOrData : null,
data: isUrl ? null : urlOrData,
@@ -346,10 +346,14 @@
term = term.toLowerCase();
var data = cache.load(term);
// recieve the cached data
+ var url = options.url;
+ if (typeof url == "function") {
+ url = options.url();
+ }
if (data && data.length) {
success(term, data);
// if an AJAX url has been supplied, try loading the data now
- } else if( (typeof options.url == "string") && (options.url.length > 0) ){
+ } else if( (typeof url == "string") && (url.length > 0) ){
var extraParams = {
timestamp: +new Date()
@@ -364,14 +368,16 @@
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,
- url: options.url,
+ url: url,
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams),
success: function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
- cache.add(term, parsed);
+ if (typeof options.url != "function") {
+ cache.add(term, parsed);
+ }
success(term, parsed);
}
});
You can also download the patch file here: jquery.autocomplete.js.patch
Now, what if you are using this autocomplete from Devbridge? You can almost do it out of the box, here is a code sample.
$("input[name*=phone_number]").each(function(i) {
var prefix = this.id.replace(/\.[^.]*$/, "");
$(this).autocomplete(
{
serviceUrl:baseURL + '/lib/findUsers',
zIndex: 9999,
deferRequestBy: 0, //milliseconds
noCaching: true,
params: {
'area':function() { return $(jq(prefix + ".area_id")).val(); },
'prefix':prefix
},
onSelect: function(value, data){ // NOTE: 'this' is NOT defined correctly here
// do stuff with data
}
}
);
});
You will notice that I included a parameter that isn’t supported, that is the noCaching parameter. I had this working pretty good without it, except if you changed the non-autocomplete field (in this case area code), and you go back to the auto field and fail to find something, that is cached with the query, so when you change the area code, you get stuck because the query field got cached, and auto thinks that it should not try again. That is why I made this tiny patch to this version of autocomplete.
Index: jquery.autocomplete.js
===================================================================
RCS file: /opt/Repository/MobilSense/MobilSentry/Products/MobilSentry/Src/CSS/share/assets/jquery.autocomplete.js,v
retrieving revision 1.1
diff -u -r1.1 jquery.autocomplete.js
--- jquery.autocomplete.js 10 Jan 2010 06:46:45 -0000 1.1
+++ jquery.autocomplete.js 15 Jan 2010 23:20:55 -0000
@@ -230,6 +230,9 @@
},^M
^M
getSuggestions: function(q) {^M
+ if (this.options.noCaching) {^M
+ this.clearCache();^M
+ }^M
var cr, me;^M
cr = this.isLocal ? this.getSuggestionsLocal(q) : this.cachedResponse[q];^M
if (cr && $.isArray(cr.suggestions)) {^M
And you can download it jquery.autocomplete.js.patch.
UPDATE
————————-
Latest patched version of the devbridge autocomplete file… jquery.autocomplete.js
May 13, 2010 at 10:30 pm
thanks for this, its what i have been looking for howevver the patch fails when i run it:
“patching file jquery.autocomplete.js
Hunk #1 FAILED at 14.
Hunk #2 FAILED at 346.
Hunk #3 FAILED at 368.
3 out of 3 hunks FAILED”
Is it possible to provide a patched copy of jquery.autocomplete.js ??
May 14, 2010 at 9:04 am
Dagon,
Yea, I will update the post with my latest patched file from the devbridge people. There was an additional fix that I put in it for IE, but I can’t remember what it was… I don’t have time to comb through cvs to figure it out, but I suppose that you could diff it with their latest. The file will be at the bottom of the post.
thanks for reading!
Eric