给AmazeUI-TagsInput组件添加自动提示typeahead功能

AmazeUI-TagsInput 插件

使用 AmazeUI 有一段时间了,各方面都挺满意的,相比 Bootstrap 对国人来说确实更加友好,他们之间具体的区别可以参考 https://www.5icool.org/a/201501/a9836.html 这篇对几种前端骨架型框架介绍的文章。

在使用 AmazeUI 的设计 JBlog 后台的过程中,有一个功能是添加文章,其中关于文章标签的交互我是用了他的插件 「AmazeUI-TagsInput」,效果是这样的:

TagsInput本身很好实现,在添加完相应的资源(包括一个JS和一个CSS)后,直接在需要美化的 <input> 标签中打上 data-am-tagsinput 属性即可。

typeahead.js 自动提示插件

已经使用 TagsInput 插件的 input 标签呈现了比较美观的「标签感」,我还想让它更智能一些,就像上图一样输入一个字符(包括中文),能够在下方自动提醒之前输入过的标签。
这时候需要使用 jQuery 的 typeahead.js 插件,这个跟 bootstrap一样,也是 twitter 开发的,专门对输入框组进行下拉提示,配置性很强,其中封装了一个匪夷所思的对象叫做 Bloodhound(中文名叫做:猎犬,挺有意思的),在 AmazeUI TagsInput 的文档中也是用了这个 Bloodhound 对象来实现自动化提示,但是我没有用,感觉挺重量级的,自己写ajax获取了服务器上的tags标签列表,自己写mach函数适配了。
我们先来看看官方的示例:

var citynames = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  prefetch: {
    url: 'js/citynames.json',
    filter: function(list) {
      return $.map(list, function(cityname) {
        return { name: cityname }; });
    }
  }
});
citynames.initialize();
$('#input-sg').tagsinput({
  typeaheadjs: {
    name: 'citynames',
    displayKey: 'name',
    valueKey: 'name',
    source: citynames.ttAdapter()
  }
});

函数中的 url 指向服务器后台的资源文件,返回json格式就可以,用 springMVC + freemarker 做起来很简单,但在前台我用这个「猎犬」对象试了很多次并没有成功。顺便提一下,手动使用tagsinput()函数的时候,别忘了移除<input>标签上的data-am-tagsinput属性,要不然tagsinput()函数是不起作用的,这也是我试错了很久发现的。
随后我放弃了「猎犬」对象,虽然在 typeahead.js 官方文档中提到强烈建议使用这个对象,但我觉得不仅不好用,还将本来很简单的业务逻辑又封装得有点复杂了,索性放弃,参考 typeahead.js examples 页面的源代码,使用第一种最直观原始的方式加载智能提示数据。
事实证明,即使是官方示例,我们也有可能用不起来,继续参考了一片文章: https://www.codesec.net/view/445202.html 才顺利使用,最终的代码如下:

//定义一个匹配判断函数
var substringMatcher = function(strs) {
    return function findMatches(q, cb) {
    //传入的q是键盘输入的字符,传入的cb一个处理数组的函数
        var matches, substringRegex;
        matches = [];
        substrRegex = new RegExp(q,"i");
        $.each(strs, function(i, str) {
            if (substrRegex.test(str)){
                matches.push({"title" : str});
            }
        });
        cb(matches);
    };
};
//使用ajax获取json数据,并给标签增加智能提醒功能
$.get("${rc.contextPath}/tags/admin/list", function(result){
    if(result.resultCode == 0){
        $("#input-sg").tagsinput({
            typeaheadjs : {
                  name : "tagsHint",
                displayKey : "title",
                valueKey : "title",
                source : substringMatcher(result.data)
            }
        });
    }
}, "json");

这样就实现了一开始的动画所显示的效果了。

丁丁生于 1987.07.01 ,30岁,英文ID:newflydd

  • 现居住地 江苏 ● 泰州 ● 姜堰
  • 创建了 Jblog 开源博客系统
  • 坚持十余年的 独立博客 作者
  • 大学本科毕业后就职于 中国电信江苏泰州分公司,前两年从事Oracle数据库DBA工作,两年后公司精简技术人员,被安排到农村担任支局长(其本质是搞销售),于2016年因志向不合从国企辞职,在小城镇找了一份程序员的工作。
  • Git OSChina 上积极参与开源社区