js脚本:
/**
* jquery.autocomplete.js
* Copyright (c) Dylan Verheul <dylan.verheul@gmail.com>
* MIT license
* http://code.google.com/p/jquery-autocomplete/
*/
(function ($) {
/**
* Autocompleter Object
* @param {jQuery} $elem jQuery object with one input tag
* @param {Object=} options Settings
* @constructor
*/
$.Autocompleter = function ($elem, options) {
/**
* Cached data
* @type Object
* @private
*/
this.cacheData_ = {};
/**
* Number of cached data items
* @type number
* @private
*/
this.cacheLength_ = 0;
/**
* Class name to mark selected item
* @type string
* @private
*/
this.selectClass_ = 'jquery-autocomplete-selected-item';
/**
* Handler to activation timeout
* @type ?number
* @private
*/
this.keyTimeout_ = null;
/**
* Last key pressed in the input field (store for behavior)
* @type ?number
* @private
*/
this.lastKeyPressed_ = null;
/**
* Last value processed by the autocompleter
* @type ?string
* @private
*/
this.lastProcessedValue_ = null;
/**
* Last value selected by the user
* @type ?string
* @private
*/
this.lastSelectedValue_ = null;
/**
* Is this autocompleter active?
* @type boolean
* @private
*/
this.active_ = false;
/**
* Is it OK to finish on blur?
* @type boolean
* @private
*/
this.finishOnBlur_ = true;
/**
* Assert parameters
*/
if (!$elem || !($elem instanceof $) || $elem.length !== 1 || $elem.get(0).tagName.toUpperCase() !== 'INPUT') {
alert('Invalid parameter for jquery.Autocompleter, jQuery object with one element with INPUT tag expected');
return;
}
/**
* Init and sanitize options
*/
if (typeof options === 'string') {
this.options = { url: options };
} else {
this.options = options;
}
this.options.maxCacheLength = parseInt(this.options.maxCacheLength, 10);
if (isNaN(this.options.maxCacheLength) || this.options.maxCacheLength < 1) {
this.options.maxCacheLength = 1;
}
this.options.minChars = parseInt(this.options.minChars, 10);
if (isNaN(this.options.minChars) || this.options.minChars < 1) {
this.options.minChars = 1;
}
/**
* Init DOM elements repository
*/
this.dom = {};
/**
* Store the input element we're attached to in the repository, add class
*/
this.dom.$elem = $elem;
if (this.options.inputClass) {
this.dom.$elem.addClass(this.options.inputClass);
}
/**
* Create DOM element to hold results
*/
this.dom.$results = $('<div></div>').hide();
if (this.options.resultsClass) {
this.dom.$results.addClass(this.options.resultsClass);
}
this.dom.$results.css({
position: 'absolute'
});
$('body').append(this.dom.$results);
/**
* Shortcut to self
*/
var self = this;
/**
* Attach keyboard monitoring to $elem
*/
$elem.keydown(function (e) {
self.lastKeyPressed_ = e.keyCode;
switch (self.lastKeyPressed_) {
case 38: // up
e.preventDefault();
if (self.active_) {
self.focusPrev();
} else {
self.activate();
}
return false;
break;
case 40: // down
e.preventDefault();
if (self.active_) {
self.focusNext();
} else {
self.activate();
}
return false;
break;
case 9: // tab
case 13: // return
if (self.active_) {
e.preventDefault();
self.selectCurrent();
return false;
}
break;
case 27: // escape
if (self.active_) {
e.preventDefault();
self.finish();
return false;
}
break;
default:
self.activate();
}
});
$elem.blur(function () {
if (self.finishOnBlur_) {
setTimeout(function () { self.finish(); }, 200);
}
});
};
$.Autocompleter.prototype.position = function () {
var offset = this.dom.$elem.offset();
this.dom.$results.css({
top: offset.top + this.dom.$elem.outerHeight(),
left: offset.left
});
};
$.Autocompleter.prototype.cacheRead = function (filter) {
var filterLength, searchLength, search, maxPos, pos;
if (this.options.useCache) {
filter = String(filter);
filterLength = filter.length;
if (this.options.matchSubset) {
searchLength = 1;
} else {
searchLength = filterLength;
}
while (searchLength <= filterLength) {
if (this.options.matchInside) {
maxPos = filterLength - searchLength;
} else {
maxPos = 0;
}
pos = 0;
while (pos <= maxPos) {
search = filter.substr(0, searchLength);
if (this.cacheData_[search] !== undefined) {
return this.cacheData_[search];
}
pos++;
}
searchLength++;
}
}
return false;
};
$.Autocompleter.prototype.cacheWrite = function (filter, data) {
if (this.options.useCache) {
if (this.cacheLength_ >= this.options.maxCacheLength) {
this.cacheFlush();
}
filter = String(filter);
if (this.cacheData_[filter] !== undefined) {
this.cacheLength_++;
}
return this.cacheData_[filter] = data;
}
return false;
};
$.Autocompleter.prototype.cacheFlush = function () {
this.cacheData_ = {};
this.cacheLength_ = 0;
};
$.Autocompleter.prototype.callHook = function (hook, data) {
var f = this.options[hook];
if (f && $.isFunction(f)) {
return f(data, this);
}
return false;
};
$.Autocompleter.prototype.activate = function () {
var self = this;
var activateNow = function () {
self.activateNow();
};
var delay = parseInt(this.options.delay, 10);
if (isNaN(delay) || delay <= 0) {
delay = 250;
}
if (this.keyTimeout_) {
clearTimeout(this.keyTimeout_);
}
this.keyTimeout_ = setTimeout(activateNow, delay);
};
$.Autocompleter.prototype.activateNow = function () {
var value = this.dom.$elem.val();
if (value !== this.lastProcessedValue_ && value !== this.lastSelectedValue_) {
if (value.length >= this.options.minChars) {
this.active_ = true;
this.lastProcessedValue_ = value;
this.fetchData(value);
}
}
};
$.Autocompleter.prototype.fetchData = function (value) {
if (this.options.data) {
this.filterAndShowResults(this.options.data, value);
} else {
var self = this;
this.fetchRemoteData(value, function (remoteData) {
self.filterAndShowResults(remoteData, value);
});
}
};
$.Autocompleter.prototype.refreshParames = function () {
}
$.Autocompleter.prototype.fetchRemoteData = function (filter, callback) {
var data = this.cacheRead(filter);
if (data) {
callback(data);
} else {
var self = this;
this.dom.$elem.addClass(this.options.loadingClass);
var ajaxCallback = function (data) {
var parsed = false;
if (data !== false) {
parsed = self.parseRemoteData(data);
self.cacheWrite(filter, parsed);
}
self.dom.$elem.removeClass(self.options.loadingClass);
callback(parsed);
};
$.ajax({
url: this.makeUrl(filter),
success: ajaxCallback,
error: function () {
ajaxCallback(false);
}
});
}
};
$.Autocompleter.prototype.setExtraParam = function (name, value) {
var index = $.trim(String(name));
if (index) {
if (!this.options.extraParams) {
this.options.extraParams = {};
}
if (this.options.extraParams[index] !== value) {
this.options.extraParams[index] = value;
this.cacheFlush();
}
}
};
$.Autocompleter.prototype.makeUrl = function (param) {
this.refreshParames();
var self = this;
var paramName = this.options.paramName || 'q';
var url = this.options.url;
var params = $.extend({}, this.options.extraParams);
// If options.paramName === false, append query to url
// instead of using a GET parameter
if (this.options.paramName === false) {
url += encodeURIComponent(param);
} else {
params[paramName] = param;
}
var urlAppend = [];
$.each(params, function (index, value) {
urlAppend.push(self.makeUrlParam(index, value));
});
if (urlAppend.length) {
url += url.indexOf('?') == -1 ? '?' : '&';
url += urlAppend.join('&');
}
return url;
};
$.Autocompleter.prototype.makeUrlParam = function (name, value) {
return String(name) + '=' + encodeURIComponent(value);
}
$.Autocompleter.prototype.parseRemoteData = function (remoteData) {
var results = [];
var text = String(remoteData).replace('\r\n', '\n');
var i, j, data, line, lines = text.split('\n');
var value;
for (i = 0; i < lines.length; i++) {
line = lines[i].split('|');
data = [];
for (j = 0; j < line.length; j++) {
data.push(unescape(line[j]));
}
value = data.shift();
results.push({ value: unescape(value), data: data });
}
return results;
};
$.Autocompleter.prototype.filterAndShowResults = function (results, filter) {
this.showResults(this.filterResults(results, filter), filter);
};
$.Autocompleter.prototype.filterResults = function (results, filter) {
var filtered = [];
var value, data, i, result, type, include;
var regex, pattern, attributes = '';
var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
for (i = 0; i < results.length; i++) {
result = results[i];
type = typeof result;
if (type === 'string') {
value = result;
data = {};
} else if ($.isArray(result)) {
value = result[0];
data = result.slice(1);
} else if (type === 'object') {
value = result.value;
data = result.data;
}
value = String(value);
if (value > '') {
if (typeof data !== 'object') {
data = {};
}
include = !this.options.filterResults;
if (!include) {
pattern = String(filter);
pattern = pattern.replace(specials, '\\{1}');
if (!this.options.matchInside) {
pattern = '^' + pattern;
}
if (!this.options.matchCase) {
attributes = 'i';
}
regex = new RegExp(pattern, attributes);
include = regex.test(value);
}
if (include) {
filtered.push({ value: value, data: data });
}
}
}
if (this.options.sortResults) {
filtered = this.sortResults(filtered, filter);
}
if (this.options.maxItemsToShow > 0 && this.options.maxItemsToShow < filtered.length) {
filtered.length = this.options.maxItemsToShow;
}
return filtered;
};
$.Autocompleter.prototype.sortResults = function (results, filter) {
var self = this;
var sortFunction = this.options.sortFunction;
if (!$.isFunction(sortFunction)) {
sortFunction = function (a, b, f) {
return self.sortValueAlpha(a, b, f);
};
}
results.sort(function (a, b) {
return sortFunction(a, b, filter);
});
return results;
};
$.Autocompleter.prototype.sortValueAlpha = function (a, b, filter) {
a = String(a.value);
b = String(b.value);
if (!this.options.matchCase) {
a = a.toLowerCase();
b = b.toLowerCase();
}
if (a > b) {
return 1;
}
if (a < b) {
return -1;
}
return 0;
};
$.Autocompleter.prototype.showResults = function (results, filter) {
var self = this;
var $ul = $('<ul></ul>');
var i, result, $li, extraWidth, first = false, $first = false;
var numResults = results.length;
for (i = 0; i < numResults; i++) {
result = results[i];
$li = $('<li>' + this.showResult(result.value, result.data) + '</li>');
$li.data('value', result.value);
$li.data('data', result.data);
$li.click(function () {
var $this = $(this);
self.selectItem($this);
}).mousedown(function () {
self.finishOnBlur_ = false;
}).mouseup(function () {
self.finishOnBlur_ = true;
});
$ul.append($li);
if (first === false) {
first = String(result.value);
$first = $li;
$li.addClass(this.options.firstItemClass);
}
if (i == numResults - 1) {
$li.addClass(this.options.lastItemClass);
}
}
// Alway recalculate position before showing since window size or
// input element location may have changed. This fixes #14
this.position();
this.dom.$results.html($ul).show();
extraWidth = this.dom.$results.outerWidth() - this.dom.$results.width();
this.dom.$results.width(this.dom.$elem.outerWidth() - extraWidth);
$('li', this.dom.$results).hover(
function () { self.focusItem(this); },
function () { /* void */ }
);
if (this.autoFill(first, filter)) {
this.focusItem($first);
}
};
$.Autocompleter.prototype.showResult = function (value, data) {
if ($.isFunction(this.options.showResult)) {
return this.options.showResult(value, data);
} else {
return value;
}
};
$.Autocompleter.prototype.autoFill = function (value, filter) {
var lcValue, lcFilter, valueLength, filterLength;
if (this.options.autoFill && this.lastKeyPressed_ != 8) {
lcValue = String(value).toLowerCase();
lcFilter = String(filter).toLowerCase();
valueLength = value.length;
filterLength = filter.length;
if (lcValue.substr(0, filterLength) === lcFilter) {
this.dom.$elem.val(value);
this.selectRange(filterLength, valueLength);
return true;
}
}
return false;
};
$.Autocompleter.prototype.focusNext = function () {
this.focusMove(+1);
};
$.Autocompleter.prototype.focusPrev = function () {
this.focusMove(-1);
};
$.Autocompleter.prototype.focusMove = function (modifier) {
var i, $items = $('li', this.dom.$results);
modifier = parseInt(modifier, 10);
for (var i = 0; i < $items.length; i++) {
if ($($items[i]).hasClass(this.selectClass_)) {
this.focusItem(i + modifier);
return;
}
}
this.focusItem(0);
};
$.Autocompleter.prototype.focusItem = function (item) {
var $item, $items = $('li', this.dom.$results);
if ($items.length) {
$items.removeClass(this.selectClass_).removeClass(this.options.selectClass);
if (typeof item === 'number') {
item = parseInt(item, 10);
if (item < 0) {
item = 0;
} else if (item >= $items.length) {
item = $items.length - 1;
}
$item = $($items[item]);
} else {
$item = $(item);
}
if ($item) {
$item.addClass(this.selectClass_).addClass(this.options.selectClass);
}
}
};
$.Autocompleter.prototype.selectCurrent = function () {
var $item = $('li.' + this.selectClass_, this.dom.$results);
if ($item.length == 1) {
this.selectItem($item);
} else {
this.finish();
}
};
$.Autocompleter.prototype.selectItem = function ($li) {
var value = $li.data('value');
var data = $li.data('data');
var displayValue = this.displayValue(value, data);
this.lastProcessedValue_ = displayValue;
this.lastSelectedValue_ = displayValue;
this.dom.$elem.val(displayValue).focus();
this.setCaret(displayValue.length);
this.callHook('onItemSelect', { value: value, data: data });
this.finish();
};
$.Autocompleter.prototype.displayValue = function (value, data) {
if ($.isFunction(this.options.displayValue)) {
return this.options.displayValue(value, data);
} else {
return value;
}
};
$.Autocompleter.prototype.finish = function () {
if (this.keyTimeout_) {
clearTimeout(this.keyTimeout_);
}
if (this.dom.$elem.val() !== this.lastSelectedValue_) {
if (this.options.mustMatch) {
this.dom.$elem.val('');
}
this.callHook('onNoMatch');
}
this.dom.$results.hide();
this.lastKeyPressed_ = null;
this.lastProcessedValue_ = null;
if (this.active_) {
this.callHook('onFinish');
}
this.active_ = false;
};
$.Autocompleter.prototype.selectRange = function (start, end) {
var input = this.dom.$elem.get(0);
if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(start, end);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
};
$.Autocompleter.prototype.setCaret = function (pos) {
this.selectRange(pos, pos);
};
/**
* autocomplete plugin
*/
$.fn.autocomplete = function (options) {
if (typeof options === 'string') {
options = {
url: options
};
}
var o = $.extend({}, $.fn.autocomplete.defaults, options);
return this.each(function () {
var $this = $(this);
var ac = new $.Autocompleter($this, o);
$this.data('autocompleter', ac);
});
};
/**
* Default options for autocomplete plugin
*/
$.fn.autocomplete.defaults = {
paramName: 'q',
minChars: 1,
loadingClass: 'acLoading',
resultsClass: 'acResults',
inputClass: 'acInput',
selectClass: 'acSelect',
mustMatch: false,
matchCase: false,
matchInside: true,
matchSubset: true,
useCache: true,
maxCacheLength: 10,
autoFill: false,
filterResults: true,
sortResults: true,
sortFunction: false,
onItemSelect: false,
onNoMatch: false,
maxItemsToShow: -1
};
})($);
css 样式:
.acInput {
width: 200px;
}
.acResults {
padding: 0px;
border: 1px solid WindowFrame;
background-color: Window;
overflow: hidden;
z-index:10000;
}
.acResults ul {
width: 100%;
list-style-position: outside;
list-style: none;
padding: 0;
margin: 0;
}
.acResults li {
margin: 0px;
padding: 2px 5px;
cursor: pointer;
display: block;
width: 100%;
font: menu;
font-size: 12px;
overflow: hidden;
}
.acLoading {
background : url('indicator.gif') right center no-repeat;
}
.acSelect {
background-color: Highlight;
color: HighlightText;
}
用法解释:
客户端
<input id="input_customer" type="text">
//事件绑定
$("#input_customer").autocomplete({
url: "../Service/CustomerService.ashx?t=" + new Date(),
extraParams: { callback: "GetOrderCustomerNameByKeyWord", _Param: "1" },
minChars: 2, //定义输入多少字符时开始发送请求
//选中某一项时执行的事件
onItemSelect: function (item, data) {
$("#hidden_customerID").val($.trim(item.data[0]));
}
});
//请求发送前参数重载
$("#input_customername").data('autocompleter').refreshParames = function () {
this.options.extraParams._Param="2";
}
服务端
StringBuilder bs=new StringBuilder();
sb.AppendFormat("{0}|{1}\r\n",data1,data2);