因工作需要,在网页的输入框实现自动补全功能。本文继续研究,使用 typeahead 实现该功能。
概述
关于 typeahead,笔者找到2个仓库:github.com:twitter/typeahead.js.git
和github.com:bassjobsen/Bootstrap-3-Typeahead.git
。前者测试不成功,因此本文使用后者仓库。
bootstrap 的 typeahead 插件是用来完成输入框的自动完成、模糊搜索和建议提示的功能,支持ajax数据加载,类似于jquery的 autocomplete 插件。
代码
下载源码:
git clone git@github.com:bassjobsen/Bootstrap-3-Typeahead.git
将仓库的文件bootstrap3-typeahead.min.js
放到工程目录,再引入到 html 文件即可。
使用比较简单,如下:
.typeahead(options)
其中,options
主要使用source
和items
两项,items
指定匹配时最多显示的数量(默认为8);source
指定数据源,可直接赋值数组,也可自实现函数。经实验,可有如下的使用方式:
$("#ent").typeahead({
items: 10,
source: theSource
});
或者:
$("#ent").typeahead({
items: 10,
source:
function (query, process) {
...
}// end of function
}); // end of typeahead
在function (query, process)
函数中可通过 ajax 向后台请求数据(数据为数组形式)。其中,query表示当前文本输入框中的字符串,process 是回调函数(返回的数据作为该函数的参数)。具体见下文代码。
前端
引入文件:
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/font-awesome.min.css" rel="stylesheet">
<script src="js/jquery-3.1.1.min.js"></script>
<script src="js/bootstrap3-typeahead.min.js"></script>
<script src="js/bootstrap.min.js"></script>
如果没有引入相应文件,使用typeahead
会提示如下错误信息:
TypeError: $(…).typeahead is not a function
页面代码片段如下:
<div class="input-group">
<span class="input-group-addon">输入节点</span>
<input id="input1" type="text" placeholder="节点代码" class="form-control" name="ent" id="ent" value= "001" /> <br >
<div id="resetInfo1" class="bs-example">
<input id="bt" type="button" class="btn btn-info" onClick="calfee()" value="提交"/>
</div>
js 核心代码如下:
var theSource = [
"广西南宁 001",
"南宁西乡塘 002",
"广西梧州 003",
"梧州岑溪 004"
];
function GetSource() { return theSource; }
nodeList = []
$("#input1").typeahead({
source:
function (query, process) {
if (nodeList.length == 0 )
{
$.ajax({
type: "POST",
contentType: "application/json",
dataType: "json",
url: "/getnodeList",
data: "sta",
success: function (result) {
nodeList = result.data
console.log("got station list ", nodeList.length)
// console.log("result: ", result)
return process(nodeList); // 回调处理
},
error : function(jqXHR, textStatus, errorThrown) {
console.log("error: ", errorThrown)
}
}); // end of ajax
}
else
{
return process(nodeList);
}
}// end of function
}); // end of typeahead
后端
后端使用 golang 的 gin 框架实现。
前面请求的 URL 为getnodeList
,对应的响应函数为GetNodeListHandle
,如下:
func GetNodeListHandle(ctx *gin.Context) {
var nodeList []string
nodeList = append(nodeList, "广西南宁 001")
nodeList = append(nodeList, "南宁西乡塘 002")
nodeList = append(nodeList, "广西梧州 003")
nodeList = append(nodeList, "梧州岑溪 004")
klog.Printf("list: %v\n", len(nodeList))
ctx.JSON(http.StatusOK,
gin.H{
"code": 0,
"msg": "ok",
"data": nodeList,
})
return
}
返回的数据为 json 对象,其中 data 为实际数据,因此前端 js 代码使用result.data
传入process
函数。
效果
输入“南”,可匹配2项,如图:
小结
因为 ajax 请求是异步,本来想着先请求一次后台返回数据,后续直接使用即可,测试发现不行,所以要在$("#input1").typeahead
请求,但该每输入一个字符,即触发一次。实在太频繁,但又没想到好的方法。因此在代码中先判断 nodeList 的长度,如有值,则不请求而是直接使用,否则请求后台,这样能减少请求的次数。因为在应用场合中,服务启动后,输入的数据不会变化,因此不需要实时请求。
至此,输入框自动补全功能暂告一段落。网上有自行实现的版本,但为了省事,无须自制轮子,经对比,发现 typeahead 能较好实现功能,因此在项目中使用。