您好,欢迎访问一九零五行业门户网

jquery.AutoComplete.js中文修正版(支持firefox)_jquery

复制代码 代码如下:
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 was 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 // 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 first character
sfirstchar = row[0].substring(0, 1).tolowercase();
// if no lookup array for this character exists, look 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 38: // up
e.preventdefault();
moveselect(-1);
break;
case 40: // down
e.preventdefault();
moveselect(1);
break;
case 9: // tab
case 13: // 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 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 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 first match (assumed to be the best match)
function autofill(svalue) {
// if the last user key pressed was 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 will 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, do 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 first match 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 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 for (var i = 0; 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 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).get(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 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 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 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 if (this[i] == e) return i;
}
return -1;
};
其它类似信息

推荐信息