Copy Code code as follows:
Jquery.autocomplete = function (input, options) {
Create a link to self
var me = this;
Create JQuery object for INPUT element
var $input = $ (input). attr ("AutoComplete", "off");
Apply Inputclass If necessary
if (Options.inputclass) $input. addclass (Options.inputclass);
Create Results
var results = document.createelement ("div");
Create JQuery Object for results
var $results = $ (results);
$results. Hide (). addclass (Options.resultsclass). CSS ("position", "absolute");
if (Options.width > 0) $results. CSS ("width", options.width);
Add to BODY Element
$ ("Body"). Append (results);
Input.autocompleter = Me;
var timeout = null;
var prev = "";
var active =-1;
var cache = {};
var keyb = false;
var hasfocus = false;
var lastkeypresscode = null;
Flush Cache
function Flushcache () {
cache = {};
Cache.data = {};
cache.length = 0;
};
Flush Cache
Flushcache ();
If there is a data array supplied
if (options.data!= null) {
var Sfirstchar = "", Stmatchsets = {}, row = [];
No URL is specified, we need to adjust the cache length to make sure it fits the local data store
if (typeof options.url!= "string") Options.cachelength = 1;
Loop through the array and create a lookup structure
for (var i = 0; i < options.data.length; i++) {
If row is a string, make an array otherwise just reference the array
Row = ((typeof options.data[i] = = "string")? [Options.data[i]]: options.data[i]);
If the length is zero, don ' t add to List
if (Row[0].length > 0) {
Get the The character
Sfirstchar = row[0].substring (0, 1). toLowerCase ();
If no lookup array for this character exists looks it up now
if (!stmatchsets[sfirstchar]) Stmatchsets[sfirstchar] = [];
If the match is a string
Stmatchsets[sfirstchar].push (row);
}
}
Add the data items to the cache
For (var k in stmatchsets) {
Increase the cache size
options.cachelength++;
Add to the cache
Addtocache (k, stmatchsets[k]);
}
}
$input
. KeyDown (function (e) {
Track last key pressed
Lastkeypresscode = E.keycode;
Switch (e.keycode) {
Case://Up
E.preventdefault ();
Moveselect (-1);
Break
Case://Down
E.preventdefault ();
Moveselect (1);
Break
Case 9://Tab
Case://Return
if (Selectcurrent ()) {
Make sure to blur off the current field
$input. Get (0). blur ();
E.preventdefault ();
}
Break
Default
active =-1;
if (timeout) cleartimeout (timeout);
Timeout = settimeout (function () {OnChange ();}, Options.delay);
Break
}
})
. focus (function () {
Track whether the field has focus, we shouldn ' t process any results if the field no longer has focus
Hasfocus = true;
})
. blur (function () {
Track whether the field has focus
Hasfocus = false;
Hideresults ();
})
. Bind ("Input", function () {
@hack: Support for inputing Chinese characters in Firefox
OnChange (0, true);
});
Hideresultsnow ();
function OnChange () {
Ignore if the following keys are pressed: [del] [Shift] [CapsLock]
if (Lastkeypresscode = 46 | | (Lastkeypresscode > 8 && lastkeypresscode < 32)) Return $results. Hide ();
var v = $input. Val ();
if (v = = prev) return;
prev = v;
if (v.length >= options.minchars) {
$input. addclass (Options.loadingclass);
RequestData (v);
} else {
$input. Removeclass (Options.loadingclass);
$results. Hide ();
}
};
function Moveselect (step) {
var lis = $ ("Li", results);
if (!lis) return;
Active + = step;
if (Active < 0) {
active = 0;
else if (active >= lis.size ()) {
active = Lis.size ()-1;
}
Lis.removeclass ("Ac_over");
$ (lis[active]). addclass ("Ac_over");
Weird behaviour in IE
if (lis[active] && lis[active].scrollintoview) {
Lis[active].scrollintoview (FALSE);
// }
};
function Selectcurrent () {
var li = $ ("Li.ac_over", results) [0];
if (!li) {
var $li = $ ("Li", results);
if (options.selectonly) {
if ($li. length = = 1) li = $li [0];
else if (Options.selectfirst) {
Li = $li [0];
}
}
if (LI) {
SelectItem (LI);
return true;
} else {
return false;
}
};
function SelectItem (LI) {
if (!li) {
Li = document.createelement ("Li");
Li.extra = [];
Li.selectvalue = "";
}
var v = $.trim (Li.selectvalue li.selectValue:li.innerHTML);
input.lastselected = v;
prev = v;
$results. HTML ("");
$input. Val (v);
Hideresultsnow ();
if (options.onitemselect) settimeout (function () {Options.onitemselect (LI)}, 1);
};
Selects a portion of the input string
function createselection (start, end) {
Get a reference to the INPUT element
var field = $input. Get (0);
if (Field.createtextrange) {
var selrange = Field.createtextrange ();
Selrange.collapse (TRUE);
Selrange.movestart ("character", start);
Selrange.moveend ("character", end);
Selrange.select ();
else if (Field.setselectionrange) {
Field.setselectionrange (start, end);
} else {
if (Field.selectionstart) {
Field.selectionstart = start;
Field.selectionend = end;
}
}
Field.focus ();
};
Fills in the input box w/the the best match (assumed)
function AutoFill (svalue) {
If the last user key pressed is backspace, don ' t autofill
if (Lastkeypresscode!= 8) {
Fill in the value (keep the case the user has typed)
$input. Val ($input. Val () + svalue.substring (prev.length));
Select the portion of the value not typed by the user (so the next character'll erase)
CreateSelection (Prev.length, svalue.length);
}
};
function Showresults () {
Get the position of the input field right now (in case the DOM is shifted)
var pos = findpos (input);
Either use the specified width, or autocalculate based on form element
var iwidth = (options.width > 0)? Options.width: $input. Width ();
Reposition
$results. CSS ({
Width:parseint (iwidth) + "px",
Top: (Pos.y + input.offsetheight) + "px",
Left:pos.x + "px"
). Show ();
};
function Hideresults () {
if (timeout) cleartimeout (timeout);
Timeout = settimeout (Hideresultsnow, 200);
};
function Hideresultsnow () {
if (timeout) cleartimeout (timeout);
$input. Removeclass (Options.loadingclass);
if ($results. Is (": visible")) {
$results. Hide ();
}
if (Options.mustmatch) {
var v = $input. Val ();
if (v!= input.lastselected) {
SelectItem (NULL);
}
}
};
function Receivedata (q, data) {
if (data) {
$input. Removeclass (Options.loadingclass);
results.innerhtml = "";
If the field no longer has focus or if there are no matches, does not display the drop down
if (!hasfocus | | data.length = = 0) return Hideresultsnow ();
if ($.browser.msie) {
We put a styled iframe behind the calendar so HTML SELECT elements don ' t show through
$results. Append (document.createelement (' iframe '));
}
Results.appendchild (Datatodom (data));
AutoFill in the Complete box w/the the "a" as long as the user hasn ' t entered in more data
if (Options.autofill && ($input. Val (). toLowerCase () = Q.tolowercase ())) AutoFill (data[0][0));
Showresults ();
} else {
Hideresultsnow ();
}
};
function Parsedata (data) {
if (!data) return null;
var parsed = [];
var rows = data.split (Options.lineseparator);
for (var i = 0; i < rows.length; i++) {
var row = $.trim (Rows[i]);
if (row) {
Parsed[parsed.length] = Row.split (options.cellseparator);
}
}
return parsed;
};
function Datatodom (data) {
var ul = document.createelement ("ul");
var num = data.length;
Limited results to a max number
if ((Options.maxitemstoshow > 0) && (options.maxitemstoshow < num)) num = Options.maxitemstoshow;
for (var i = 0; i < num; i++) {
var row = Data[i];
if (!row) continue;
var li = document.createelement ("Li");
if (Options.formatitem) {
li.innerhtml = Options.formatitem (row, I, NUM);
Li.selectvalue = row[0];
} else {
li.innerhtml = row[0];
Li.selectvalue = row[0];
}
var extra = null;
if (Row.length > 1) {
extra = [];
for (var j = 1; j < Row.length; J + +) {
Extra[extra.length] = Row[j];
}
}
Li.extra = extra;
Ul.appendchild (LI);
$ (LI). Hover (
Function () {$ ("Li", ul). Removeclass ("Ac_over"); $ (this). addclass ("Ac_over"); active = $ ("Li", ul). IndexOf ($ (this). (0)); },
Function () {$ (this). Removeclass ("Ac_over");
). Click (function (e) {e.preventdefault (); E.stoppropagation (); SelectItem (This)});
}
return ul;
};
function RequestData (q) {
if (!options.matchcase) q = q.tolowercase ();
var data = Options.cachelength? Loadfromcache (q): null;
Recieve the cached data
if (data) {
Receivedata (q, data);
If an AJAX URL has been supplied, try loading the data now
else if ((typeof Options.url = = "string") && (Options.url.length > 0)) {
$.get (Makeurl (q), function (data) {
data = parsedata (data);
Addtocache (q, data);
Receivedata (q, data);
});
If there ' s been no data found, remove the loading class
} else {
$input. Removeclass (Options.loadingclass);
}
};
function Makeurl (q) {
var url = options.url + "? q=" + Escape (q);
for (var i in Options.extraparams) {
url = + "&" + i + "=" + Escape (Options.extraparams[i]);
}
return URL;
};
function Loadfromcache (q) {
if (!Q) return null;
if (Cache.data[q]) return CACHE.DATA[Q];
if (Options.matchsubset) {
for (var i = q.length-1 i >= options.minchars; i--) {
var qs = q.substr (0, I);
var c = Cache.data[qs];
if (c) {
var csub = [];
for (var j = 0; J < C.length; J + +) {
var x = c[j];
var x0 = x[0];
if (Matchsubset (x0, q)) {
Csub[csub.length] = x;
}
}
return csub;
}
}
}
return null;
};
function Matchsubset (s, sub) {
if (!options.matchcase) s = s.tolowercase ();
var i = S.indexof (sub);
if (i = = 1) return false;
return i = = 0 | | Options.matchcontains;
};
This.flushcache = function () {
Flushcache ();
};
This.setextraparams = function (p) {
Options.extraparams = p;
};
This.findvalue = function () {
var q = $input. val ();
if (!options.matchcase) q = q.tolowercase ();
var data = Options.cachelength? Loadfromcache (q): null;
if (data) {
Findvaluecallback (q, data);
else if ((typeof Options.url = = "string") && (Options.url.length > 0)) {
$.get (Makeurl (q), function (data) {
data = parsedata (data)
Addtocache (q, data);
Findvaluecallback (q, data);
});
} else {
No matches
Findvaluecallback (q, NULL);
}
}
function Findvaluecallback (q, data) {
if (data) $input. Removeclass (Options.loadingclass);
var num = (data)? data.length:0;
var li = null;
for (var i = 0; i < num; i++) {
var row = Data[i];
if (row[0].tolowercase () = = Q.tolowercase ()) {
Li = document.createelement ("Li");
if (Options.formatitem) {
li.innerhtml = Options.formatitem (row, I, NUM);
Li.selectvalue = row[0];
} else {
li.innerhtml = row[0];
Li.selectvalue = row[0];
}
var extra = null;
if (Row.length > 1) {
extra = [];
for (var j = 1; j < Row.length; J + +) {
Extra[extra.length] = Row[j];
}
}
Li.extra = extra;
}
}
if (options.onfindvalue) settimeout (function () {Options.onfindvalue (LI)}, 1);
}
function Addtocache (q, data) {
if (!data | |!q | |!options.cachelength) return;
if (!cache.length | | cache.length > Options.cachelength) {
Flushcache ();
cache.length++;
else if (!cache[q]) {
cache.length++;
}
CACHE.DATA[Q] = data;
};
function Findpos (obj) {
var curleft = Obj.offsetleft | | 0;
var curtop = Obj.offsettop | | 0;
while (obj = obj.offsetparent) {
Curleft + + Obj.offsetleft
Curtop + + Obj.offsettop
}
return {x:curleft, y:curtop};
}
}
JQuery.fn.autocomplete = function (URL, options, data) {
Make sure options exists
options = Options | | {};
Set URL as option
Options.url = URL;
Set some bulk local data
Options.data = ((typeof data = = "Object") && (Data.constructor = = Array))? Data:null;
Set default values for required options
Options.inputclass = Options.inputclass | | "Ac_input";
Options.resultsclass = Options.resultsclass | | "Ac_results";
Options.lineseparator = Options.lineseparator | | "\ n";
Options.cellseparator = Options.cellseparator | | "|";
Options.minchars = Options.minchars | | 1;
Options.delay = Options.delay | | 400;
Options.matchcase = Options.matchcase | | 0;
Options.matchsubset = Options.matchsubset | | 1;
Options.matchcontains = Options.matchcontains | | 0;
Options.cachelength = Options.cachelength | | 1;
Options.mustmatch = Options.mustmatch | | 0;
Options.extraparams = Options.extraparams | | {};
Options.loadingclass = Options.loadingclass | | "Ac_loading";
Options.selectfirst = Options.selectfirst | | False
options.selectonly = Options.selectonly | | False
Options.maxitemstoshow = Options.maxitemstoshow | | -1;
Options.autofill = Options.autofill | | False
Options.width = parseint (options.width, 10) | | 0;
This.each (function () {
var input = this;
New Jquery.autocomplete (input, options);
});
Don ' t break the chain
return this;
}
JQuery.fn.autocompleteArray = function (data, options) {
return This.autocomplete (NULL, options, data);
}
JQuery.fn.indexOf = function (e) {
for (var i = 0; i < this.length; i++) {
if (this[i] = = e) return i;
}
return-1;
};