Bootstrap typeahead使用问题记录及解决方案

简单介绍

Bootstrap typeahead插件是用来完成输入框的自动完成、模糊搜索和建议提示的功能,支持ajax数据加载,类似于jquery的流行插件Autocomplete。

typeahead的使用方式有两种:通过数据属性字段的方式和通过Javascript加载的方式。

1. 通过属性字段的方式

在输入文本框input组件里添加data-provide="typeahead"这个属性字段表示使用typeahead扩展插件:

<input type="text" data-provide="typeahead">

也可以通过设置autocomplete="off"来避免浏览器自己的自动完成功能,防止与插件使用相混。

2. 通过Javascript加载的方式

通过手动的在js中调用typeahead函数:

$(‘.typeahead’).typeahead()

属性选项

具体数据相关的配置通过几个选项字段和函数控制,如下表所示:

名称类型默认值描述

sourcearray, function[ ]提供查询的数据源,可以是一个字符串数组或者一个方法,,该方法有两个参数:query 输入值和 process回调函数,回调函数可以在返回数据源的时候调用,以将数据处理成typeahead能识别的标准数据源。

itemsnumber8显示在下拉菜单中的列表数量的最大值

minLengthnumber1触发autocomplete功能所需的最少输入字符个数

matcherfunctioncase insensitive该方法用来确定一个query怎么匹配一个item,又一个入参item,表示与query匹配的实例,可以使用this.query来引用当前的query参数,如果query匹配成功则返回true。

sorterfunctionexact match, case sensitive, case insensitive该方法用于给数据源排序,有一个入参items,表示typeahead数据源实例,可以使用this.query来引用当前的query参数。

updaterfunctionreturns selected item该方法用于返回选择的搜索项,有一个入参item,表示typeahead数据源中返回的单个实例。

highlighterfunctionhighlights all default matches该方法用于高亮选取最终的选择项,又一个入参item,表示typeahead数据源中返回的单个实例,返回值是一个html。

具体的使用实例可以自行Google或借鉴我最后列出的几个参考资料。

问题记录

这篇文章主要记录自己初次使用typeahead时遇到的难题,以及最终的解决方法,希望能给遇到类似问题的小伙伴们一个有用的参考。

首先,我的业务需求是输入一个话题topic,该话题的数据源是从后台数据库获取的,需要支持模糊搜索(至于左模糊、右模糊还是全模糊,就看查询数据库时的sql语句怎么写了),因此必须使用ajax异步加载的方式获取数据,于是写了下面这样一个ajax函数提供数据源:

source: function (query, process) {return $.ajax({url: ‘/showoff/watermark/fetchTopics’,type: ‘post’,data: {topicName: query},dataType: ‘json’,success: function (result) {process(resultList);}});}

结果是可以行得通的,如下图所示:

2

但这里有个问题:在提交表单时,我们后台需要传入的是话题的id,而不是搜索框里显示的话题name。这里通过typeahead获取的只有name,上面写的ajax函数里从后台传来的数据也只有name列表,该怎么办呢?

不难想到有下面两个解决方案:

在参考资料的帮助下,我看了下typeahead js库里关于上面选项表里几个方法的默认实现,最终得到了解决方案:

按照上面的思路最终实现如下,这里贴上完整的typeahead相关的代码:

typeahead输入框:

<input type="text" id="topicInput" name="topicName" placeholder="请输入话题"autocomplete="off" data-provide="typeahead" />

隐藏的topic id输入框:

<form:hidden id="topicId" name="topicId" path="labelId"/>

最终的typeahead实现js:

<script type="text/javascript">$(‘#topicInput’).typeahead({ source: function (query, process) {return $.ajax({url: ‘/showoff/watermark/fetchTopics’,type: ‘post’,data: {topicName: query},dataType: ‘json’,success: function (result) {// 这里的数据解析根据后台传入格式的不同而不同 if(result.code == "1") {var json = JSON.parse(result.data.data);var resultList = json.topicList.map(function (item) {var aItem = { id: item.id, name: item.displayName };return JSON.stringify(aItem);});return process(resultList);} else {alert(result.msg);}}});},matcher: function (obj) {var item = JSON.parse(obj);return ~item.name.toLowerCase().indexOf(this.query.toLowerCase())},sorter: function (items) {var beginswith = [], caseSensitive = [], caseInsensitive = [], item;while (aItem = items.shift()) {var item = JSON.parse(aItem);if (!item.name.toLowerCase().indexOf(this.query.toLowerCase()))beginswith.push(JSON.stringify(item));else if (~item.name.indexOf(this.query)) caseSensitive.push(JSON.stringify(item));else caseInsensitive.push(JSON.stringify(item));}return beginswith.concat(caseSensitive, caseInsensitive)},highlighter: function (obj) {var item = JSON.parse(obj);var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, ‘\\$&’)return item.name.replace(new RegExp(‘(‘ + query + ‘)’, ‘ig’), function ($1, match) {return ‘<strong>’ + match + ‘</strong>’})},updater: function (obj) {var item = JSON.parse(obj);$(‘#topicId’).attr(‘value’, item.id);return item.name;} })</script>参考资料

版权声明:本文为博主原创文章,未经博主允许不得转载。

年轻是我们唯一拥有权利去编织梦想的时光

Bootstrap typeahead使用问题记录及解决方案

相关文章:

你感兴趣的文章:

标签云: