自动填充功能, 是一种良好的用户体验功能。
本来是想用bootstrap typeahead 的,显示效果要比jqueryui 的autocomplete 漂亮,默认带高亮(autocomplete 旧版本有,新版本取消了), 功能也强很多,但是typeahead 版本差异大,typeahead 3都没有带例子,twitter 的版本还需要使用其他的js包, 学习成本高。jqueryui 的autocomplete 直接支持 显示(label)和值(value)分开, typeahead 还需要另外处理,这一点加使用简单让我选择了 autocomplete。
环境:
jQuery UI - v1.12.1 - 2016-09-14
jQuery JavaScript Library v3.3.1
官方例子
http://jqueryui.com/autocomplete/
官方API
http://api.jqueryui.com/autocomplete/
效果
在正式的使用环境中, 我们一般都是搭配AJAX 远程读取数据使用的, 下面的代码是我lin49940通过具体的实践得出来的,总结一下备忘。
一. html, 里面的button 使用了 bootstrap 的样式,input 和 button 之间(/><button)不能换行, 不然他们中间会出现空隙, button 不是必要的,只是我为了实现通过点击按钮让下拉框显示所有项才加入的。
<input type="text" id="re_produte" placeholder="输入生产编号" /><button
type="button" id="dr_bt" class="btn btn-default btn-sm">
<span class="caret"></span>
</button>
二. JS 代码
var dr_lock = 0; //因为我上面的例子多了一个button功能,通过button 出来的下拉框,
//选中项的时候会触发文本框的focus 事件,这样会跟文本框的focus 事件冲突, 导致文
//本框的focus 事件被多次调用,这里设置这个全局变量就是为区别文本框的focus
//是button 触发的还是文本框自己触发的,然后再进行处理
$('#dr_bt').bind('click', function () {//定义按钮的点击事件
dr_lock = 1; //加锁,表示后面触发的文本框的focus 事件是button 引起的
$('#re_produte').autocomplete("search", "");//手动调用查询,
//第二个参数是查询条件,我这是是传空字符串,
//表示查询所有数据,你也可以传"22", 表示查询包含22 的数据。
$('#re_produte').val("");
});
$(function () {
try {
$('#re_produte').autocomplete({
source: function (request, response) {
$.ajax({
url: "/我的后台功能", dataType: "json", type: "get",
data: {
"term": request.term //autocomplete 默认get,传的参数名term
},
success: function (data) {
//这里加判断的代码,数据是否成功,
代码。。。。
//我这里的数据是单纯的字符串列表,需要进行转换
response($.map(data, function (item) {
return {
//里面的正则表达式用于筛选需要高亮的数据,
//myACclass 样式需要自己定于,我自己定的是加粗和红色lin49940
label: item.replace(
new RegExp(
"(?![^&;]+;)(?!<[^<>]*)(" +
$.ui.autocomplete.escapeRegex(request.term) +
")(?![^<>]*>)(?![^&;]+;)", "gi"
), "<span class='myACclass'>$1</span>"),
//label为下拉框显示的标签
value: item //value选中后显示的值
}
}));
}
});
},
//在下拉框的最下面加一项提醒项
response: function (event, ui) {
var link = {
label: '<strong>没匹配到的话,请输入完整的生产编号</strong>',
value: ''
};
ui.content.push(link);
},
//下拉框项被选中触发的事件,准确来说是选中前的事件,如果你return 了,不会
//再执行后面的填充操作, 但是如果你不return, 就会再执行选中赋值操作.
//这里一定要写select 事件, 是因为上面的"提醒项", 不然所有都匹配不上的话,
//因为autoFocus 为true, 回车选中最后一项, 文本框被清空了...
select: function (event, ui) {
if (ui.item.value == "") {
return false;
} else {
//$(this).val(ui.item.value);
//直接调用查询业务的代码,然后return, 如果不想做其他操作,else 代码块可以去掉
//return;
}
},
minLength: 0, //有输入就去查询
autoFocus: true, //自动选中第一项,会触发下拉框的focus事件,
//但是不会填充到文本框
delay: 500 //延迟半秒加载
//如果在这里定义focus:function, 触发的是下拉框的项的focus 事件
}).focus( //这里定义的focus 是文本框的事件
function () {
//button 触发的focus 事件,重置锁,不处理直接返回
if (dr_lock == 1) { dr_lock = 0; return; };
$(this).autocomplete("search");//手动调用查询,没有第二个参数,表示用文本框的输入值
}
)
//新版本没有高亮功能,只能自己定义渲染方式,里面的<div> 必不可少,不然label 直接明文显示
.autocomplete("instance")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append('<div>' + item.label + '</div>')
.appendTo(ul);
};
}catch (e) { }
});
三. 效果
这里再记一些会用到的功能
/**
** 手动调用其他数据源,然后再把数据源还原
**/
//保存原来的数据源
var oldsource = $('#re_produte').autocomplete("option", "source");
//重新指定数据源
$('#re_produte').autocomplete("option", "source", [{ label: "ccc", value: "aaaa" }]);
//手动调用,显示下拉框
$('#re_produte').autocomplete("search", "");
//还原数据源
var oldsource = $('#re_produte').autocomplete("option", "source");
/**
** 读取或修改autocomplete 的配置项,上面的里是source ,这里是minLength,其他配置
** 项同理
**/
//读取
$('#re_produte').autocomplete("option", "minLength")
//修改
$('#re_produte').autocomplete("option", "minLength", 2)
/**
** autocomplete 的当前实例,定义 _renderItem,_renderMenu,_resizeMenu
** 这三个渲染方法需要用到
** .autocomplete("instance")._renderItem = function (ul, item) {。。。}
**/
$('#re_produte').autocomplete("instance");