简单介绍

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()

属性选项

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

名称 类型 默认值 描述
source array, function [ ] 提供查询的数据源,可以是一个字符串数组或者一个方法,该方法有两个参数:query 输入值和 process回调函数,回调函数可以在返回数据源的时候调用,以将数据处理成typeahead能识别的标准数据源。
items number 8 显示在下拉菜单中的列表数量的最大值
minLength number 1 触发autocomplete功能所需的最少输入字符个数
matcher function case insensitive 该方法用来确定一个query怎么匹配一个item,又一个入参item,表示与query匹配的实例,可以使用this.query来引用当前的query参数,如果query匹配成功则返回true。
sorter function exact match, case sensitive, case insensitive 该方法用于给数据源排序,有一个入参items,表示typeahead数据源实例,可以使用this.query来引用当前的query参数。
updater function returns selected item 该方法用于返回选择的搜索项,有一个入参item,表示typeahead数据源中返回的单个实例。
highlighter function highlights 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) {        // 这里省略resultList的处理过程,处理后resultList是一个字符串列表,// 经过process函数处理后成为能被typeahead支持的字符串数组,作为搜索的源return process(resultList);                                           }});
}

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

2

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

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

  1. 在提交的时候直接把话题name传过去,然后在后台处理逻辑里再通过name搜索其对应的id。
  2. 将话题id和name绑定后一起传到页面,然后在话题输入框下面放置一个隐藏的话题id输入框。在搜索时只需要name作为数据源,在选取某个name后,将其对应的id值放到隐藏的id输入框里面。

方案1处理起来很简单,但同时也很low,而且可能因为页面多传了个空格什么的导致数据库搜索失败,容易出错。

方案2看起来挺不错的,可怎么实现呢?如何在选取某个搜索值后做其它的操作?source函数做不到这点。看一下上面选项表中的几个函数,其中有一个updater方法,该方法用来返回最终选取的某个值,顾名思义,我们也可以在方法返回之前做更新动作,比如设置某个输入框的值。但有几个问题:

  • topic id和name如何进行绑定?以对象的方式还是map的方式?
  • 在返回数据源时是只返回name列表用于搜索,还是返回name和id的组合列表?如果只返回name列表,那么在updater函数里是取不到与name对应的id值的;如果返回组合列表,那么搜索时显示的就不仅是name了。
  • 是不是可以在数据源里返回绑定的组合列表,然后自定义搜索匹配方式,item只显示name呢?

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

  • 后台将topic id和topic name以对象列表的形式传过来,到了ajax里进行解析处理,得到一个id和name组合的json字符串数组,通过process函数处理后返回。
  • 重写matcher、sorter、highlighter和updater这四个方法,将原来里面的item实例全部变成item.name实例,表示要通过name进行搜索匹配、高亮和排序,而与id五官。
  • 最后,在updater方法里将topic id的隐藏输入框的值更新为item.id值即可。

按照上面的思路最终实现如下,这里贴上完整的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>

参考资料

  • Javascript · Bootstrap
  • 使用 Bootstrap Typeahead 组件 - 冠军 - 博客园
  • Bootstrap typeahead ajax result format - Example [结果格式的例子引导Typeahead Ajax] - 问题-字节技术
  • typeahead Bloodhound完整例子

Bootstrap typeahead使用问题记录及解决方案相关推荐

  1. Bootstrap typeahead自动补全插件的坑

    ##Bootstrap typeahead 插件的坑 typeahead 自动补全插件, 还是先简单记录一下,如何使用吧: <div class="form-group"&g ...

  2. JS 使用html2canvas实现截图功能的问题记录和解决方案

    JS 使用html2canvas实现截图功能的问题记录和解决方案 参考文章: (1)JS 使用html2canvas实现截图功能的问题记录和解决方案 (2)https://www.cnblogs.co ...

  3. Git之深入解析Rerere重用记录的解决方案

    了解了管理或者维护 Git 仓库.实现代码控制所需的大多数日常命令和工作流程,尝试跟了踪和提交文件的基本操作,并且掌握了暂存区和轻量级地分支及合并的威力.如果想进一步对 Git 深入学习,可以学习一些 ...

  4. Bootstrap——table标签使用横向滚动条解决方案

    官方文档 https://v4.bootcss.com/docs/content/tables/ 解决方案 方法一:原生CSS 给table标签添加CSS属性 table显示滚t动条,要先把table ...

  5. 移动端微信公众号开发中问题记录及解决方案

    1. 关于字体大小.图片大小.块元素大小的确定,目前一种方法,使用rem,rem的计算方式 document.documentElement.style.fontSize = document.doc ...

  6. git大文件记录清除解决方案

    参考: https://blog.csdn.net/Y0W1as5eg37urFdS/article/details/123539994 https://www.manongdao.com/artic ...

  7. 富士胶片电视电影镜头及记录媒体解决方案亮相BIRTV 2018

    北京2018年8月23日电 /美通社/ -- 2018年8月22日,第二十七届北京国际广播电影电视展览会(BIRTV2018)在北京中国国际展览中心盛大开幕.为期4天的展会围绕着"品质融媒体 ...

  8. 第五章 使用 Bootstrap Typeahead 组件(百度下拉效果)

    推荐链接:http://www.cnblogs.com/haogj/p/3376874.html UnderScore官网:http://underscorejs.org/ 参考文档:http://w ...

  9. SpringCloud 2020.x.x工程bootstrap引导配置不生效的解决方案

      关注公众号 风色年代(itfantasycc) 500G Java微服务资料合集送上~ 注意:2020版本以后,添加spring-cloud-context是没有用的,因为官方重构了bootstr ...

最新文章

  1. 学python需要什么基础知识-Python的学习,都需要具备哪些计算机基础知识?
  2. 手动排除fbiytty和vcxlcph病毒的干扰
  3. solr 自定义 dismax查询方式
  4. 海康sip服务器地址_完整SIP/SDP媒体协商概论SDP基础使用要求
  5. 在VC6中使用ADO读取Oracle中的BLOB字段
  6. thinkphp 模板 in
  7. 170308、oracle查看被锁的表和解锁
  8. java创作2019-7-19日报管理系统
  9. Appium原理总结
  10. IAPP视频教程全集
  11. Box plot (箱线图) 解读以及Python实现
  12. Android之——多媒体开发视频格式
  13. python executescript_Python(SQLite)executescript用法(
  14. 大学生创新创业万学答案
  15. 【Unity 02】地形Terrain
  16. 线性回归——简单线性回归、多元线性回归
  17. 前端程序员初步认识 docker
  18. Ubuntu 10.04环境下载编译Android-2.2.1 (froyo) 源代码 1/2
  19. 很有仙气超有创意的单网页视差效果直接可以使用id1091
  20. MySQL的索引(聚簇索引和非聚簇索引)

热门文章

  1. 安卓简单的操作数据库
  2. PTA:7-34 通讯录的录入与显示 (10分)
  3. vue3.0项目的创建
  4. 域名与IP地址的联系与区别
  5. 串口调试助手 安卓版 附下载地址
  6. 单相交流电机为什么需要电容才能正常启动?
  7. ios 上传图片失败 小程序_【报Bug】百度小程序真机IOS无法上传图片
  8. 手机怎么登陆群邮件服务器,139邮箱登陆登录入口 中国移动139手机邮箱注册图文教程...
  9. HDC.Cloud 华为开发者大会2021.04.24 学习记录
  10. Office 365 E3功能