/**自动完成-jQuery插件1.0.2**版权所有(c)2007 Dylan Verheul、Dan G.Switzer、Anjesh Tuladhar、Jörn Zaefferer**MIT和GPL许可证下的双重许可:* http://www.opensource.org/licenses/mit-license.php* http://www.gnu.org/licenses/gpl.html**修订:$Id:jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer$**/;(函数($){$.fn.扩展({自动完成:函数(urlOrData,选项){var isUrl=urlOrData类型==“字符串”;options=$.extend({},$.Autocompleter.defaults{url:是url吗?urlOrData:空,数据:是URL吗?null:urlOrData,延迟:是Url吗?$。自动补全器.默认值.延迟:10,max:选项&&!选项滚动?10 : 150},选项);//如果highlight设置为false,则用do-nothing函数替换它options.highlight=options.hughlight||函数(值){返回值;};//如果未指定formatMatch选项,则使用formatItem实现向后兼容性options.formatMatch=选项.formatMatch||options.formatItem;return this.each(function(){新$。自动补偿器(此,选项);});},结果:函数(处理程序){return this.bind(“result”,handler);},搜索:函数(处理程序){返回this.trigger(“search”,[handler]);},flushCache:函数(){return this.trigger(“flushCache”);},setOptions:函数(选项){返回this.trigger(“setOptions”,[选项]);},unatocomplete:function(){return this.trigger(“unatocomplete”);}});$.自动完成器=功能(输入、选项){var键={向上:38,向下:40,交付日期:46,选项卡:9,返回:13,ESC:27,COMMA:188,页码:33,向下翻页:34,后置空间:8};//为输入元素创建$objectvar$input=$(input).attr(“autocomplete”,“off”).addClass(options.inputClass);var超时;var previousValue=“”;var缓存=$。自动完成器。缓存(选项);var hasFocus=0;var lastKeyPressCode;var配置={鼠标向下选择:false};var选择=$。自动完成器。选择(options,input,selectCurrent,config);var blockSubmit;//使用返回键选择时防止opera中的表单提交$.browser.opera&&$(input.form).bind(“submit.autocomplete”,function(){if(blockSubmit){blockSubmit=false;返回false;}});//只有opera在按下时不会多次触发keydown,其他的根本不使用keypress$input.bind(($.browser.opera?“keypress”:“keydown”)+“.autocomplete”,函数(事件){//按下曲目最后一个键lastKeyPressCode=事件.keyCode;开关(event.keyCode){外壳键。向上:event.proventDefault();if(选择.visible()){select.prev();}其他{onChange(0,true);}断裂;外壳键。向下:event.proventDefault();if(选择.visible()){select.next();}其他{onChange(0,true);}断裂;外壳键。向上翻页:event.proventDefault();if(选择.visible()){select.pageUp();}其他{onChange(0,true);}断裂;外壳键。向下翻页:event.proventDefault();if(选择.visible()){select.pageDown();}其他{onChange(0,true);}断裂;//还匹配分号case options.multiple&&$.trim(options.moltipleSeparator)==“,”&&KEY。逗号:外壳键。选项卡:外壳键。返回:if(selectCurrent()){//停止默认以阻止表单提交,Opera需要特殊处理event.proventDefault();blockSubmit=true;返回false;}断裂;外壳键。紧急停车场:select.hide();断裂;违约:clearTimeout(超时);timeout=setTimeout(onChange,options.delay);断裂;}}).focus(函数(){//跟踪字段是否有焦点,我们不应该处理任何//如果字段不再具有焦点,则返回结果hasFocus++;}).blur(函数(){hasFocus=0;if(!config.mouseDownOnSelect){隐藏结果();}})点击(函数(){//单击聚焦字段时显示selectif(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind(“搜索”,函数(){//TODO为什么不指定两个参数?var fn=(arguments.length>1)?参数[1]:null;函数findValueCallback(q,data){var结果;if(数据和数据长度){for(变量i=0;i<数据长度;i++){if(data[i].result.toLowerCase()==q.到LowerCasE()){结果=数据[i];断裂;}}}if(类型fn==“函数”)fn(结果);else$input.trigger(“结果”,result&&[result.data,result.value]);}$.each(trimWords($input.val()),函数(i,value){请求(value,findValueCallback,find ValueCallbak);});}).bind(“flushCache”,函数(){cache.flush();}).bind(“setOptions”,函数(){$.extend(选项、参数[1]);//如果我们更新了数据,请重新填充if(参数[1]中的“数据”)cache.polpulate();}).bind(“unatocomplete”,函数(){select.unbind();$input.unbind();$(input.form).unbind(“.autocomplete”);}).bind(“输入”,函数(){//需要中文输入吗?参见CRM-6135和http://plugins.jquery.com/node/14682 //但这打破了“延迟”,所以让我们只在中文minChars设置中使用它if(选项.minChars<=1){onChange(0,true);} });函数selectCurrent(){var selected=select.selected();如果(!选中)返回false;var v=选择结果;previousValue=v;if(选项.多个){var words=trimWords($input.val());if(单词长度>1){v=words.slice(0,words.length-1).join(options.multipleSeparator)+options.multipleSeparator+v;}v+=options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger(“结果”,[selected.data,selected.value]);返回true;}函数onChange(垃圾,skipPrevCheck){if(lastKeyPressCode==KEY.DEL){select.hide();回报;}var currentValue=$input.val();if(!skipPrevidCheck&&currentValue==previousValue)回报;previousValue=当前值;currentValue=lastWord(currentValue);if(currentValue.length>=options.minChars){$input.addClass(options.loadingClass);if(!options.matchCase)currentValue=当前值.toLowerCase();请求(currentValue、receiveData、hideResultsNow);}其他{停止加载();select.hide();}};函数trimWords(value){if(!value){返回[“”];}var words=值.split(options.multipleSeparator);var结果=[];$.each(单词、函数(i、值){if($.trim(值))结果[i]=$.trim(值);});返回结果;}函数lastWord(value){if(!选项.多个)收益值;var words=trimWords(值);返回单词[words.length-1];}//使用第一个匹配项填充输入框(假定为最佳匹配项)//q:输入的术语//sValue:第一个匹配结果函数自动填充(q,sValue){//只要用户没有输入更多数据,就在完整的框中自动填充第一个匹配项//如果最后按下的用户键是backspace,则不要自动填充if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLoverCase(()))&&lastKeyPressCode!=关键。退格){//填写值(保留用户键入的案例)$input.val($inpul.val()+sValue.substring(lastWord(previousValue).length));//选择用户未键入的值部分(这样下一个字符将被擦除)$.自动完成器。选择(输入,previousValue.length,previoursValue.lngth+sValue.longth);}};函数hideResults(){clearTimeout(超时);timeout=setTimeout(hideResultsNow,200);};函数hideResultsNow(){var wasVisible=select.visible();select.hide();clearTimeout(超时);停止加载();if(options.mustMatch){//调用搜索并运行回调$输入搜索(函数(结果){//如果找不到值,请清除输入框if(!result){if(选项.多个){var words=trimWords($input.val()).slice(0,-1);$input.val(words.join(options.multipleSeparator)+(words.length?options.multipleSeparator:“”);}其他的$input.val(“”);}});}if(可见)//将光标定位在输入字段的末尾$.自动完成器。选择(input,input.value.length,inpup.value.lenging);};函数receiveData(q,data){if(data&&data.length&&hasFocus){停止加载();选择.显示(数据,q);自动填充(q,数据[0].value);select.show();}其他{hideResultsNow();}};功能请求(期限、成功、失败){if(!options.matchCase)term=term.toLowerCase();var数据=缓存加载(项);//接收缓存的数据if(data&&data.length){成功(术语、数据);//如果提供了AJAX url,请立即尝试加载数据}else if((选项类型.url==“字符串”)&&(选项.url.length>0)){var extraParams={时间戳:+new Date()};$.each(选项.extraParams,函数(键,参数){extraParams[key]=参数类型==“函数”?param():参数;});$.ajax(美元)({//尝试利用ajaxQueue插件中止以前的请求模式:“中止”,//将堕胎限制为此输入端口:“autocomplete”+input.name,数据类型:选项.dataType,url:选项.url,数据:$.extend({s: lastWord(术语),限制:options.max},额外参数),成功:函数(数据){var parsed=options.parse&&options.parse(数据)| | parse(data);cache.add(术语,已解析);成功(术语,解析);}});}其他{//如果出现故障,我们需要清空列表——这可以防止[TAB]键选择最后一个成功的匹配select.emptyList();失效(术语);}};函数解析(数据){解析的变量=[];var行=data.split(“\n”);for(var i=0;i<行长度;i++){var行=$.trim(行[i]);if(行){row=行.split(“|”);已解析[parsed.length]={数据:行,值:行[0],结果:options.formatResult&&options.formatResult(行,行[0])| |行[0]};}}已解析的返回;};函数stopLoading(){$input.removeClass(options.loadingClass);};};$.Autocompleter.defaults={inputClass:“ac_input”,resultsClass:“ac_results”,加载类:“ac_loading”,最小字符数:0,延迟:400,matchCase:false,matchSubset:false,match包含:false,缓存长度:10,最大值:100,mustMatch:false,额外参数:{},选择First:true,formatItem:函数(行){return row[0];},formatMatch:空,自动填充:false,宽度:0,倍数:false,多重分隔符:“,”,突出显示:函数(值、术语){return value.replace(new RegExp(“(?![^&;]+;)(?!<[^<>]*)(”+term.replace(/([\^\$\(\)\[\]\{\}\*.+\?\|\])/gi,“\\$1”)+“)(?![^<>]*>)(?![^&;]+;)”,“gi”),“$1");},滚动:true,滚动高度:300};$.自动完成器。Cache=函数(选项){var数据={};var长度=0;函数matchSubset(s,sub){if(!options.matchCase)s=s.到LowerCase();var i=s.indexOf(子);如果(i==-1)返回false;return i==0||options.matchContains;};函数加法(q,value){if(长度>options.cacheLength){flush();}if(!数据[q]){长度++;}数据[q]=值;}函数populate(){如果(!options.data)返回false;//追踪比赛var stMatchSets={},nullData=0;//没有指定url,我们需要调整缓存长度以确保它适合本地数据存储如果(!options.url)options.cacheLength=1;//跟踪minChars=0的所有选项stMatchSets[“”]=[];//循环遍历数组并创建查找结构for(var i=0,ol=options.data.length;i<ol;i++){var rawValue=选项.data[i];//如果rawValue是字符串,则创建数组,否则只引用数组rawValue=(类型rawValue==“字符串”)?[rawValue]:rawValue;var值=options.formatMatch(rawValue,i+1,options.data.length);if(值===假)继续;var firstChar=value.charAt(0).toLowerCase();//如果不存在此字符的查找数组,请立即查找if(!stMatchSets[firstChar])stMatchSets[firstChar]=[];//如果匹配是字符串var行={value:值,数据:rawValue,结果:options.formatResult&&options.formatResult(rawValue)||value};//将当前匹配项推入集合列表stMatchSets[firstChar].push(行);//跟踪minChars零项if(nullData++<options.max){stMatchSets[“”].push(行);}};//将数据项添加到缓存$.each(stMatchSets,函数(i,值){//增加缓存大小选项.cacheLength++;//添加到缓存添加(i,值);});}//填充任何现有数据setTimeout(填充,25);函数flush(){数据={};长度=0;}返回{冲洗:冲洗,添加:添加,populate:填充,载荷:函数(q){if(!options.cacheLength||!length)返回null;/* *如果处理w/本地数据并匹配Contains,则必须确保*在所有数据集合中循环查找匹配项*/if(!options.url&&options.matchContains){//跟踪所有匹配项var csub=[];//遍历所有数据网格以进行匹配for(数据中的var k){//不搜索stMatchSets[“”](minChars:0)缓存//这样可以防止重复如果(k.长度>0){var c=数据[k];$.each(c,函数(i,x){//如果有匹配项,请将其添加到数组中if(匹配子集(x.value,q)){csub.push(x);}});}} 返回csub;}其他//如果确实存在,请使用它if(数据[q]){返回数据[q];}其他if(options.matchSubset){for(var i=q.length-1;i>=选项.minChars;i--){var c=数据[q.subtr(0,i)];如果(c){var csub=[];$.each(c,函数(i,x){if(匹配子集(x.value,q)){csub[csub.length]=x;}});返回csub;}}}返回null;}};};$.自动完成器。Select=功能(选项、输入、选择、配置){var类别={激活:“ac_over”};var列表项,活动=-1,数据,术语=“”,needsInit=true,元素,列表;//创建结果函数init(){if(!needsUnit)回报;元素=$(“
")隐藏().addClass(options.resultsClass).css(“位置”,“绝对”).appendTo(document.body);innerElement=$(“
").addClass('ac_results-inner').appendTo(元素);列表=$(“