如何使用Typeahead和Bloodhound启用多属性搜索?

时间:2015-04-12 20:04:14

标签: jquery html typeahead.js

我想在特殊的typeahead for Bootstrap 3中使用typeahead,以允许用户搜索数据库中的某些内容:

查询结果如下:

[{"id":1,"name":"Viajes Alaniz-Santiago","contact_name":"Carlota Pab\u00f3n","email":"ona22@rosaesteve.es"},{"id":9,"name":"Rodrigo y Alcaraz y Asoc.","contact_name":"Yago Calder\u00f3n","email":"pablo.cuellar@toro.es"},{"id":18,"name":"Global Carbajal","contact_name":"Joel Verduzco","email":"pablo.lucio@santana.es"},{"id":19,"name":"Ocasio de Ni\u00f1o y Flia.","contact_name":"Carlos Ocasio","email":"wposada@global.es"},{"id":24,"name":"Valles y Jaramillo S. de H.","contact_name":"Sra. Carolina P\u00e1ez","email":"plaza.erika@herrero.com.es"},{"id":32,"name":"Centro Est\u00e9vez-Caraballo","contact_name":"Alejandra Marroqu\u00edn","email":"ybravo@espinal.com.es"},{"id":43,"name":"Asociaci\u00f3n Olivas-Carbajal","contact_name":"Angela Anaya","email":"noa63@puig.com"}]

因此,当用户输入QUERY数据库时,它实际上正在查找表格中的namecontact_name字段。例如,在上面的示例中,Car是查询,因此包含contact_name中的结果CarlotaPabón

我正用这样的Bloodhound设置提前打字:

  var engine = new Bloodhound({
    name: 'contact_name',
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name','contact_name'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: '/search/providers?query=%QUERY'
  });

  engine.initialize();

  $("#providersSearchInput").typeahead({
    source: engine.ttAdapter(),
    minLength: 3,
    items: 15,
  });

我认为datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name','contact_name')会成功as this answer suggests,但它不起作用。

我该如何设置?我如何获得selected object,当我在contact_name中显示匹配并且用户选择CarlotaPabón时,我想获得{"id":1,"name":"Viajes Alaniz-Santiago","contact_name":"Carlota Pab\u00f3n","email":"ona22@rosaesteve.es"}作为选定对象。

编辑,我也尝试过:

有更多基准不起作用:

var name = new Bloodhound({
      datumTokenizer: function (data) {
          return Bloodhound.tokenizers.whitespace(data.name);
      },
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      remote: '/search/providers?query=%QUERY'
  });

  var contact_name = new Bloodhound({
      datumTokenizer: function (data) {

          return Bloodhound.tokenizers.whitespace(data.contact_name);
      },
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      remote: '/search/providers?query=%QUERY'
  });

  name.initialize(); contact_name.initialize();

  $("#providersSearchInput").typeahead({
    source: name.ttAdapter(),
    minLength: 3,
    items: 15,
  },
  {
    source: contact_name.ttAdapter(),
    minLength: 3,
    items: 15
  });

1 个答案:

答案 0 :(得分:0)

尝试

var engine = new Bloodhound(
  {
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
              url: "/search/providers?query=%QUERY",
              filter: function(results) {
                   return $.map(results, function(data) {
                     return {
                       value:data.contact_name, 
                       suggestion:data
                     };
                   })
                   .concat(
                     $.map(results, function(data) {
                       return {
                         value: data.name,
                         suggestion: data
                       }
                     })
                   )
               }
             }
  }
);

engine.initialize();

$("#providersSearchInput")
.typeahead(
  {
    minLength: 3,
    hint: true,
    highlight: true
  }
, {
    name: "engine",
    displayKey: "value",
    templates: {
      suggestion: function(data) {
        return $("<div />", {
                 "html": data.suggestion.contact_name 
                         + "<br />" 
                         + "<i class=suggest>" + data.suggestion.name + "</i>"
                         + "<br />" 
                         + "<i class=suggest>" + data.suggestion.email + "</i>"
                         + "<br />"
                })
      }
    },
    source: engine.ttAdapter()
});

$(function() {

  var data = [{
    "id": 1,
    "name": "Viajes Alaniz-Santiago",
    "contact_name": "Carlota Pab\u00f3n",
    "email": "ona22@rosaesteve.es"
  }, {
    "id": 9,
    "name": "Rodrigo y Alcaraz y Asoc.",
    "contact_name": "Yago Calder\u00f3n",
    "email": "pablo.cuellar@toro.es"
  }, {
    "id": 18,
    "name": "Global Carbajal",
    "contact_name": "Joel Verduzco",
    "email": "pablo.lucio@santana.es"
  }, {
    "id": 19,
    "name": "Ocasio de Ni\u00f1o y Flia.",
    "contact_name": "Carlos Ocasio",
    "email": "wposada@global.es"
  }, {
    "id": 24,
    "name": "Valles y Jaramillo S. de H.",
    "contact_name": "Sra. Carolina P\u00e1ez",
    "email": "plaza.erika@herrero.com.es"
  }, {
    "id": 32,
    "name": "Centro Est\u00e9vez-Caraballo",
    "contact_name": "Alejandra Marroqu\u00edn",
    "email": "ybravo@espinal.com.es"
  }, {
    "id": 43,
    "name": "Asociaci\u00f3n Olivas-Carbajal",
    "contact_name": "Angela Anaya",
    "email": "noa63@puig.com"
  }];

  var engine = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: $.map(data, function(d) {
      return {
        value: d.contact_name,
        suggestion: d
      }
    }).concat($.map(data, function(d) {
      return {
        value: d.name,
        suggestion: d
      }
    }))
  });
  engine.initialize();

  $("#providersSearchInput").typeahead({
    minLength: 3,
    hint: true,
    highlight: true
  }, {
    name: "engine",
    displayKey: "value",
    templates: {
      suggestion: function(data) {
        return $("<div />", {
          "html": data.suggestion.contact_name 
                  + "<br />" + "<i class=suggest>" + data.suggestion.name + "</i>"
                  + "<br />" + "<i class=suggest>" + data.suggestion.email + "</i>"
                  + "<br />"
        })
      }
    },
    source: engine.ttAdapter()
  });
});
html {
  overflow-y: scroll;
}

.tt-dropdown-menu,
.gist {
  text-align: left;
}
html {
  color: #333333;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 18px;
  line-height: 1.2;
}
.title,
.example-name {
  font-family: Prociono;
}
p {
  margin: 0 0 10px;
}
.title {
  font-size: 64px;
  margin: 20px 0 0;
}
.example {
  padding: 30px 0;
}
.example-name {
  font-size: 32px;
  margin: 20px 0;
}
.demo {
  margin: 50px 0;
  position: relative;
}
.typeahead,
.tt-query,
.tt-hint {
  border: 2px solid #CCCCCC;
  border-radius: 8px 8px 8px 8px;
  font-size: 24px;
  height: 30px;
  line-height: 30px;
  outline: medium none;
  padding: 8px 12px;
  width: 396px;
}
.typeahead {
  background-color: #FFFFFF;
}
.typeahead:focus {
  border: 2px solid #0097CF;
}
.tt-query {
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
}
.tt-hint {
  color: #999999;
}
.tt-dropdown-menu {
  background-color: #FFFFFF;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 8px 8px 8px 8px;
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
  margin-top: 12px;
  padding: 8px 0;
  width: 422px;
}
.tt-suggestion {
  font-size: 18px;
  line-height: 24px;
  padding: 3px 20px;
}
.tt-suggestion.tt-cursor {
  background-color: #0097CF;
  color: #FFFFFF;
}
.tt-suggestion p {
  margin: 0;
}
.gist {
  font-size: 14px;
}
.example-twitter-oss .tt-suggestion {
  padding: 8px 20px;
}
.example-twitter-oss .tt-suggestion + .tt-suggestion {
  border-top: 1px solid #CCCCCC;
}
.example-twitter-oss .repo-language {
  float: right;
  font-style: italic;
}

[class|=suggest] {
  color: navy;
  font-size: 14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>

<input id="providersSearchInput" class="typeahead" type="text" placeholder="search" />