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。。