JQuery UI Autocomplete(自动补全)功能在input前端设计中非常有用,最近一个项目正好用到,仔细研究了下组合框(combobox)的自动补全部分,官方地址是:https://jqueryui.com/autocomplete/#combobox。 官方的功能需要一个额外下拉按钮才能显示全部option选项,有些画蛇添足。我的需求是,只要点击输入框,就要显示全部的option选项,并且在输入框里面同时能实现搜索,下面是改进版的功能:
- 官方 combobox 自动补全的全部功能(除了下拉的按钮)
- 自动存储input的值,刷新后保存选择值。注意,要使用存储功能,必须设置 select 的 name 属性
- 点击输入框显示全部备选项(不需要下拉按钮)
- 设置了option value则选择结果为value,否则为标签内HTML内容
- 匹配元素 class,可以设置任意多输入框
不多说,直接上源码:
<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<title>jQuery UI 自动完成(Autocomplete) - 组合框(Combobox)</title>
<link rel=stylesheet href=http://lib.sinaapp.com/js/jquery-ui/1.10.2/themes/smoothness/jquery-ui.min.css>
<script src=http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js></script>
<script src=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() {
var select = this.element,
option = select.children( option ),
selectName = select.attr(name),
have = false;
// 如果设置了select 的name属性,则检查保存数据与页面option是否匹配
if (selectName){
var localValue = localStorage.getItem(selectName);
option.each(function(){
var itemValue = $(this).val();
if (itemValue === localValue)
{
$(this).attr(selected, selected);
have = true;
return false;
}
});
// 如果没有,则新建一个option标签
if ( !have )
{
$( <option> ).appendTo( select )
.val( localValue )
.text( localValue )
.attr(selected, selected);
}
}
// option selected 标签的值
var selected = select.children( :selected ),
value = selected.val();
// 增加 input 标签,并设置属性
this.input = $( <input> )
.appendTo( this.wrapper )
.val( value )
.attr({ title: })
.addClass( custom-combobox-input ui-widget ui-widget-content ui-state-default ui-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() {
var input = 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 ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), i ),
option = this.element.children( option );
response( option.map(function() {
var text = $( this ).text(),
val = $( this ).val();
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
label: text,
value: val,
option: this
};
}));
},
// 选择之后执行这里
_removeIfInvalid: function( event, ui ) {
var selectName = 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;
return false;
}
});
// 如果检测通过,则保存数据并中断执行
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 class=ui-widget>
<label>您喜欢的编程语言:</label>
<!-- 注意,如果要保存数据,必须设置select的name属性,多个select时name属性应该是相互不一样的 -->
<select class=combobox name=lang>
<option value=>请选择...</option>
<option value=ActionScript>ActionScript</option>
<option value=AppleScript>AppleScript</option>
<!-- 如果不设置value,则会返回option标签中的内容 -->
<option>Asp</option>
<option value=BASIC>BASIC</option>
<option value=C>C</option>
<!-- 如果value值和HTML内容不同,点选后会返回value值; -->
<option value=CPP>C++</option>
<option value=Clojure>Clojure</option>
<option value=COBOL>COBOL</option>
<option value=ColdFusion>ColdFusion</option>
<option value=Erlang>Erlang</option>
<option value=Fortran>Fortran</option>
<option value=Groovy>Groovy</option>
<option value=Haskell>Haskell</option>
<option value=Java>Java</option>
<option value=JavaScript>JavaScript</option>
<option value=Lisp>Lisp</option>
<option value=Perl>Perl</option>
<option value=PHP>PHP</option>
<option value=Python>Python</option>
<option value=Ruby>Ruby</option>
<option value=Scala>Scala</option>
<option value=Scheme>Scheme</option>
</select>
</div>
</body>
</html>
因为Jquery、Jquery UI和Jquery UI CSS直接使用新浪SAE,所以保存以上代码成一个html文件,然后直接打开就可以看到效果了,如下图:
在输入框里面输入任何内容,然后鼠标点击页面的其他任意位置,这个值就会保存起来了(在本地 localStorage 中)。刷新页面,还是原来保存的内容。YES。。