JQuery UI组合框自动补全功能改进版(即时全部显示+input内容保存)
JQueryUIAutocomplete(自动补全)功能在input前端设计中非常有用,最近一个项目正好用到,仔细研究了下组合框(combobox)的自动补全部分,官方地址是:https://jqueryui.com/autocomplete/#combobox。
官方的功能需要一个额外下拉按钮才能显示全部option选项,有些画蛇添足。我的需求是,只要点击输入框,就要显示全部的option选项,并且在输入框里面同时能实现搜索,下面是改进版的功能:
- 官方combobox自动补全的全部功能(除了下拉的按钮)
- 自动存储input的值,刷新后保存选择值。注意,要使用存储功能,必须设置select的name属性
- 点击输入框显示全部备选项(不需要下拉按钮)
- 设置了optionvalue则选择结果为value,否则为标签内HTML内容
- 匹配元素class,可以设置任意多输入框
不多说,直接上源码:
<!doctypehtml> <htmllang="en"> <head> <metacharset="utf-8"> <title>jQueryUI自动完成(Autocomplete)-组合框(Combobox)</title> <linkrel="stylesheet"href="http://lib.sinaapp.com/js/jquery-ui/1.10.2/themes/smoothness/jquery-ui.min.css"> <scriptsrc="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script> <scriptsrc="http://lib.sinaapp.com/js/jquery-ui/1.10.2/jquery-ui.min.js"></script> <script> (function($){ $.widget("custom.combobox",{ _create:function(){ this.wrapper=$("<span>") .addClass("custom-combobox") .insertAfter(this.element); this.element.hide(); this._createAutocomplete(); this._clickShowAll(); }, //自动补全主功能 _createAutocomplete:function(){ varselect=this.element, option=select.children("option"), selectName=select.attr("name"), have=false; //如果设置了select的name属性,则检查保存数据与页面option是否匹配 if(selectName){ varlocalValue=localStorage.getItem(selectName); option.each(function(){ varitemValue=$(this).val(); if(itemValue===localValue) { $(this).attr("selected","selected"); have=true; returnfalse; } }); //如果没有,则新建一个option标签 if(!have) { $("<option>").appendTo(select) .val(localValue) .text(localValue) .attr("selected","selected"); } } //optionselected标签的值 varselected=select.children(":selected"), value=selected.val(); //增加input标签,并设置属性 this.input=$("<input>") .appendTo(this.wrapper) .val(value) .attr({title:""}) .addClass("custom-combobox-inputui-widgetui-widget-contentui-state-defaultui-corner-left") .autocomplete({ delay:0, minLength:0, source:$.proxy(this,"_source") }) .tooltip({ tooltipClass:"ui-state-highlight" }); this._on(this.input,{ autocompleteselect:function(event,ui){ ui.item.option.selected=true; this._trigger("select",event,{ item:ui.item.option }); }, autocompletechange:"_removeIfInvalid" }); }, //点击输入框自动显示所有值 _clickShowAll:function(){ varinput=this.input, wasOpen=false; input .mousedown(function(){ wasOpen=input.autocomplete("widget").is(":visible"); }) .click(function(){ input.focus(); //如果已经可见则关闭 if(wasOpen){ return; } //传递空字符串作为搜索的值,显示所有的结果 input.autocomplete("search",""); }); }, //获取子标签的内容 _source:function(request,response){ varmatcher=newRegExp($.ui.autocomplete.escapeRegex(request.term),"i"), option=this.element.children("option"); response(option.map(function(){ vartext=$(this).text(), val=$(this).val(); if(this.value&&(!request.term||matcher.test(text))) return{ label:text, value:val, option:this }; })); }, //选择之后执行这里 _removeIfInvalid:function(event,ui){ varselectName=this.element.attr("name"), value=this.input.val(), valueLowerCase=value.toLowerCase(), valid=false, //是否进行检测,如果不检测输入内容的合法性,将该值设置为true即可 checkInvalid=false; //保存数据 this.saveData=function(){ //如果设置了select的name属性 if(selectName){ //存储数据到localStorage localStorage.setItem(selectName,value); } } //如果是直接从下拉菜单中选择,或者配置为不进行数据检测,则直接保存数据,并中断执行 if(ui.item||!checkInvalid){ this.saveData(); return; }else{ //搜索一个匹配(不区分大小写) this.element.children("option").each(function(){ if($(this).text().toLowerCase()===valueLowerCase){ this.selected=valid=true; returnfalse; } }); //如果检测通过,则保存数据并中断执行 if(valid){ this.saveData(); return; } //过滤无效的值功能 this.input .val("") .attr("title",value+"未找到任何结果") .tooltip("open"); this.element.val(""); this._delay(function(){ this.input.tooltip("close").attr("title",""); },2500); this.input.data("ui-autocomplete").term=""; //清除存储的数据 localStorage.setItem(selectName,""); } }, _destroy:function(){ this.wrapper.remove(); this.element.show(); } }); })(jQuery); $(function(){ $(".combobox").combobox(); }); </script> </head> <body> <div> <label>您喜欢的编程语言:</label> <!--注意,如果要保存数据,必须设置select的name属性,多个select时name属性应该是相互不一样的--> <selectname="lang"> <optionvalue="">请选择...</option> <optionvalue="ActionScript">ActionScript</option> <optionvalue="AppleScript">AppleScript</option> <!--如果不设置value,则会返回option标签中的内容--> <option>Asp</option> <optionvalue="BASIC">BASIC</option> <optionvalue="C">C</option> <!--如果value值和HTML内容不同,点选后会返回value值;--> <optionvalue="CPP">C++</option> <optionvalue="Clojure">Clojure</option> <optionvalue="COBOL">COBOL</option> <optionvalue="ColdFusion">ColdFusion</option> <optionvalue="Erlang">Erlang</option> <optionvalue="Fortran">Fortran</option> <optionvalue="Groovy">Groovy</option> <optionvalue="Haskell">Haskell</option> <optionvalue="Java">Java</option> <optionvalue="JavaScript">JavaScript</option> <optionvalue="Lisp">Lisp</option> <optionvalue="Perl">Perl</option> <optionvalue="PHP">PHP</option> <optionvalue="Python">Python</option> <optionvalue="Ruby">Ruby</option> <optionvalue="Scala">Scala</option> <optionvalue="Scheme">Scheme</option> </select> </div> </body> </html>
因为Jquery、JqueryUI和JqueryUICSS直接使用新浪SAE,所以保存以上代码成一个html文件,然后直接打开就可以看到效果了,如下图:
在输入框里面输入任何内容,然后鼠标点击页面的其他任意位置,这个值就会保存起来了(在本地 localStorage 中)。刷新页面,还是原来保存的内容。YES。。