Typeahead.js - Search in multiple property values

17,277

Solution 1

Typeahead 0.10.3 added "support to object tokenizers for multiple property tokenization."

So, your example becomes

var posts = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'desc'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: data
});

However, I don't think this will work for properties nested inside, that is, the data.category object in your case.

As a side note, if you are using prefetched data, be sure to clear the local storage first, otherwise the new tokenizer won't take effect (Because datumTokenizer is used when adding to the search index, and if data is already present in localStorage, then the search index will not be updated). I was stuck on this for a while!

Solution 2

return Bloodhound.tokenizers.whitespace(data.title) returns an array of strings.

So, instead of returning that value: save it (and your other desired values), then concatenate them and return that value...

x = Bloodhound.tokenizers.whitespace(data.title);
y = Bloodhound.tokenizers.whitespace(data.desc);
z = Bloodhound.tokenizers.whitespace(data.category[i].name);
return x.concat(y).concat(z);

Solution 3

I've implemented a solution here:

http://jsfiddle.net/Fresh/4nnnG/

As you have a local datasource you need to create individual datasets to enable you to match on multiple data properties. e.g.

$('#search-input').typeahead({
    highlight: true
}, {
    name: 'titles',
    displayKey: 'title',
    source: titles.ttAdapter()
}, {
    name: 'descs',
    displayKey: 'desc',
    source: descs.ttAdapter()
}, {
    name: 'cats',
    displayKey: 'name',
    source: cats.ttAdapter()
});
Share:
17,277

Related videos on Youtube

Iladarsda
Author by

Iladarsda

My interest, in this order.. ✔ JavaScript / OO / MV* ✔ AngularJS ✔ NodeJS ✔ Unit Testing ✔ HTML5/CSS3

Updated on October 29, 2020

Comments

  • Iladarsda
    Iladarsda over 3 years

    Please see example below.

    JSFiddle: http://jsfiddle.net/R7UvH/2/

    How do I make typeahead.js (0.10.1) search for matches in more than one property value? Ideally, within whole data (data.title, data.desc and in all data.category[i].name)

     datumTokenizer: function(data) {
         // **search in other property values; e.g. data.title & data.desc etc..**
         return Bloodhound.tokenizers.whitespace(data.title);
     },
    

    Whole example:

    var data = [{
        title: "some title here",
        desc: "some option here",
        category: [{
            name: "category 1",
        }, {
            name: "categoy 2",
        }]
    },
    {
        title: "some title here",
        desc: "some option here",
        category: [{
            name: "category 1",
        }, {
            name: "categoy 2",
        }]
    }];
    
    var posts = new Bloodhound({
        datumTokenizer: function(data) {
            // **search in other property values; e.g. data.title & data.desc etc..**
            return Bloodhound.tokenizers.whitespace(data.title);
        },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        local: data
    });
    posts.initialize();
    
    $('#search-input').typeahead({
        highlight: true
    }, {
        name: 'Pages',
        displayKey: 'title',
        source: posts.ttAdapter(),
        templates: {
            header: '<h3>Pages</h3>'
        }
    });
    
  • Ben Smith
    Ben Smith about 10 years
    @NullSoulException :D
  • Iladarsda
    Iladarsda about 10 years
    @Fresh thanks for taking the time, it is slightly more complicated than I initially presented. I am using multiple sources (which are categorized with headers -exactly the same as per typeahead.js multi source demo twitter.github.io/typeahead.js/examples). Can you point me to an example of the filter usage? Please note that I want to keep the categorization with headers (media, pages, posts). thanks
  • Ben Smith
    Ben Smith about 10 years
    I've been looking into the way filter() and what I thought would help you wouldn't work i.e. build up a list of tokens within the filter. I think you should implement a solution using the way I suggested in my answer, except you'll need to add the categorization headers as you suggested. Hope you find a solution and I'll be interested to see it!
  • Hammad Khan
    Hammad Khan over 9 years
    kept working on @timothy solution for days but it did not work for me. This solution works and is more elegant.
  • Sean Connolly
    Sean Connolly about 8 years
    Great solution, thanks. Side note, you can prevent prefetch caching with prefetch: { cache: false, ... }
  • toddmo
    toddmo about 7 years
    This works, but alert: You must specify the properties in the order they appear in the data's schema; otherwise, it won't work. I think this is a bug in the typeahead since it's astonishing to the user.