【问题标题】:Twitter typeahead.js and a json object for multiple matchesTwitter typeahead.js 和一个用于多个匹配的 json 对象
【发布时间】:2016-04-22 13:54:25
【问题描述】:

我正在编写一个程序,它应该能够根据一些课程参数找到一门大学课程。我有一个包含 1360 个对象的巨大 json 对象,每个对象有大约 20-30 个参数。不过,我只对其中的 3-5 个感兴趣。

我想做的是能够根据课程的编号、姓名、教师姓名或每门课程的描述中包含的一组关键字来找到课程。

无论如何。我试过搞乱twitters typeahead.js,据我所知,你需要解析一个字符串数组,而且看起来只需要1个数组。难道没有一种简单的方法(或其他 javascript 模块)可以做到这一点吗?

我现在的对象是:

var courses = [
    { "number": "<5 digits>", 
      "name": "<course name>", 
      "teacher": "<teacher name>", 
      "keywords": "<string of keywords>" }
    { ... }
    { ... }
    { ... }
    and so forth..
 ];

如前所述,大小为 1360 个对象。

我想得到类似这样的输出:

但是,我希望能够搜索提到的参数(数字、姓名、教师姓名、关键字),并尽可能匹配输入到文本字段中的任何内容。

有人知道如何实现这一目标吗?

【问题讨论】:

  • 您是在处理静态数据还是从某个地方获取它(可能是 ajax 调用)?您是否可以控制数据的返回方式?
  • 数据与页面一起从“本地”json 文件加载。嗯是的。暂时它将保持静止。我计划设置一个 cron-job 以在设定的时刻重新运行我的 python 脚本,以从课程数据库中抓取数据,然后更新文件。

标签: javascript json twitter typeahead.js twitter-typeahead


【解决方案1】:

这很容易,但 不是 typeahead.js。它有231 未解决的问题(在打字时,有些非常严重)并且在 内没有更新。

请改用bootstrap3-typeahead。它得到维护和更新。在进一步阅读之前先看看文档。您没有提供 JSON,因此我在下面的示例中使用了另一个 JSON。

您所要做的就是定义一个matcher 方法,这里是一个非常简单的不区分大小写的方法,它与JSON 项中的所有 属性进行比较:

matcher: function(item) {
  for (var attr in item) {
    if (~item[attr].toString().toLowerCase().indexOf(this.query.toLowerCase())) return true
  }
  return false
}

您可以使用displayText(纯示例)覆盖应在下拉列表中显示的属性/文本:

displayText: function(item) {
  return item.id + ' ' + item.label  + ' ' + item.value
}

如果您想完全覆盖项目的呈现,作为复杂的 HTML,请使用 displayTexthighlighter 的组合,其中每个显示字符串都包含字符串化的 JSON:

displayText: function(item) {
  return JSON.stringify(item) 
},
highlighter: function(item) {
  item = JSON.parse(item)
  return '<span><h4>'+item.value + '</h4>' + item.id  + ' ' + item.label +'</span>'
}

当显示字符串被字符串化时,&lt;input&gt; 必须使用应该是选定值的值属性进行更新:

afterSelect: function(item) {
  this.$element[0].value = item.value
}

完整示例:

$('#example').typeahead( {
  source: json,
  matcher: function(item) {
    for (var attr in item) {
        if (~item[attr].toString().toLowerCase().indexOf(this.query.toLowerCase())) return true
    }
    return false
  },
  displayText: function(item) {
    return JSON.stringify(item)
  },
  highlighter: function(item) {
    item = JSON.parse(item)
    return '<span><h4>'+item.value + '</h4>' + item.id  + ' ' + item.label +'</span>'
  },
  afterSelect: function(item) {
    this.$element[0].value = item.value
  }
})                

演示 -> http://jsfiddle.net/vhme3td1/

【讨论】:

  • 哇,谢谢。这很棒!我会马上试试这个!一旦我得到它的工作,我会接受你的答复作为答案:P
  • @Zeliax,仅供参考 - 已更新答案,忘记包含 afterSelect 以正确将选定值传递给 &lt;input&gt;
  • 忙了一阵子,终于来看看,真是太棒了!非常感谢朋友:P
猜你喜欢
  • 2020-12-22
  • 2023-04-10
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
相关资源
最近更新 更多