(function($){
$.tools = $.tools || {version: '1.2'};
$.tools.suggest = {};
$.tools.suggest.defaults = {
url : null,
params : null,
delay : 100,
cache : true,
formId : '#search_form',
focus:null
}
$.tools.suggest.borderKey = {
UP: 38,
DOWN: 40,
TAB: 9,
ESC: 27,
ENTER:13
}
$.fn.suggest=function(options,fn){
var options,key = $.tools.suggest.borderKey;
if($.isFunction(options)){
fn=options;
options = $.extend({}, $.tools.suggest.defaults, key);
}else{
options = $.extend({}, $.tools.suggest.defaults, key, options);
}
return this.each(function(){
var
self = $(this),
url = options.url,
params = options.params,
searchUrl = null,
searchtimer = 0,
delay = options.delay,
cache = options.cache,
formobj = $(options.formId),
focus = options.focus,
rebox = $('<ul />').attr("id","suggest"),
htmlLi = null,
litop = null,
lileft = null,
liwth = null,
tip = false,
val = null,
rlen = null,
UP = options.UP,
DOWN = options.DOWN,
TAB = options.TAB,
ESC = options.ESC,
ENTER = options.ENTER,
index = -1,
choseKey = null,
backval = null,
hidden = false,
locksuggest = false,
timer = null
;
/* 初始化 */
if(focus){
self.trigger('focus');
}
/* 初始化绑定事件 */
self.bind("focus",function(){
backval = (backval=$.trim(self.val()))==''?null:backval; /* 触发焦点时初始化backval的值 */
getQueue();
})
.bind("blur",function(){
clearQueue();
hideResult();
})
.bind("keydown",function(e){
switch (e.keyCode){
case UP:
clearQueue();
if($('#suggest').css('display') == 'none'){
reSet();
return false;
}
index--;
if(index<0){
index=Math.abs(rlen)-1;
}
changeSelect(index);
e.preventDefault();
break;
case DOWN:
clearQueue();
if($('#suggest').css('display') == 'none'){
reSet();
return false;
}
index++;
if(index>=rlen){
index=0;
}
changeSelect(index);
e.preventDefault();
break;
case TAB:
clearQueue();
hideResult();
break;
case ESC:
clearQueue();
hideResult();
e.preventDefault();
break;
case ENTER:
clearQueue();
break;
default:
getQueue();
break;
}
});
// 获取关键词
function getKey(){
val = $.trim(self.val());
if(!!val && val!=backval){ /* 关键词不为空且关键词不重复 */
backval = val;
if(cache && !!$.tools.suggest[val]){ /* 如不需要缓存结果,设cache为false */
index = -1;
rlen = $.tools.suggest[val][1];
appendSuggest($.tools.suggest[val][0]);
}else{
$.tools.suggest[val] = ["",0];
searchurl = url+'?'+$.param(params);
getResult(searchurl);
}
}
if(!!!val && !hidden){
hideResult(); /* 如果关键词为空并且层没有隐藏则隐藏提示层 */
}
}
/* 获取提示数据 */
function getResult(searchurl){
$.ajax({
type: "GET",
url: searchurl,
cache: true,
dataType: "jsonp",
jsonpCallback: "$.fn.suggest.suggetCallback"
});
}
/* 插入提示数据 */
function appendSuggest(result){
locksuggest = hidden = false;
/* 如果检索结果为空,隐藏提示层反之则输出 */
if(!!result){
if(!tip){
litop = self.offset().top+self.outerHeight()-1;
lileft = self.offset().left;
liwth = self.outerWidth()-2;
rebox.css({'position':'absolute','top':litop,'left':lileft,'width':liwth}).html(result).appendTo('body').show();
tip = true;
}else{
rebox.html(result).show();
}
rebox.find('li').bind('mouseover',function(){
locksuggest = true; /* 锁定提示层 */
index = $(this).index();
changeSelect(index,false);
})
.bind('click',function(){
changeSelect(index);
searchSubmit();
});
rebox.bind('mouseout',function(){
locksuggest = false; /* 解锁提示层 */
});
}else{
rebox.hide();
}
}
/* JSONP 回调函数 */
$.fn.suggest.suggetCallback = function(tmp){
var data = tmp,
htmltemp = '',
htmllen = data.total,
inputWord = data.kw;
if(htmllen > 0){
$.each(data.list,function(i,n){
if(n.word != inputWord){
htmltemp += '<li data-value="'+n.word+'">'+n.word+'</li>';
}
});
htmltemp = htmltemp.toLocaleLowerCase();
var regex = eval("/\>"+inputWord+"/g");
htmltemp = htmltemp.replace(regex,"><b>"+inputWord+"</b>");
$.tools.suggest[inputWord]=[htmltemp,htmllen];
}
if(self.val() == inputWord){
rlen = htmllen;
index = -1;
appendSuggest(htmltemp);
}
}
/* 创建队列 */
function getQueue(){
var n = $(document).queue("suggest");
if(n.length < 1){
$(document).queue("suggest",getQueue);
getKey();
timer = setTimeout((function(){
$(document).dequeue("suggest");
}),delay);
}
}
/* 清除队列 */
function clearQueue(){
$(document).clearQueue("suggest");
clearTimeout(timer);
}
/* 变更选项 */
function changeSelect(index,v){
v=v==false?false:true;
var obj = rebox.find('li').eq(index);
rebox.find('li.mo').removeClass('mo');
obj.addClass("mo");
if(v){
choseKey = backval = obj.attr("data-value");
self.val(choseKey);
}
}
/* 重置层 */
function reSet(){
if(!!self.val()){
index = -1;
$('#suggest').css('display','block');
rebox.find('li.mo').removeClass('mo');
rlen = rebox.find('li').size(); /* 根据html结构重新计算提示结果长度 */
}
}
/* 隐藏结果层 */
function hideResult(){
if(!locksuggest){
choseKey = backval = null;
hidden = true;
rebox.hide();
}
}
/* 提交表单 */
function searchSubmit(){
self.val(choseKey);
clearQueue();
hideResult();
formobj.submit();
}
});
}
})(jQuery);