Question

By default, the typeahead plugin makes use of a single data source in order to fetch the results. What I would like is for it to search within multiple fields, so if say, I have:

var items = [
    {'title': 'Acceptable', 'description': 'Good, but not great'}
]

It will search on both the title and description fields, ideally via AJAX.

Is this possible with this plugin?

Was it helpful?

Solution

Typeahead does not support using JSON objects without two tweaks. There are few pull-requests in Github for this, and I have submitted one myself, but, currently, you must manually override select and render. Additionally, you must also override highlighter, matcher, sorter, and updater, but those can done via the options passed into the typeahead.

var typeahead = control.typeahead({ /* ... */ }).data('typeahead');

// manually override select and render
//  (change attr('data-value' ...) to data('value' ...))
//  otherwise both functions are exact copies
typeahead.select = function() {
    var val = this.$menu.find('.active').data('value')
    this.$element.val(this.updater(val)).change()
    return this.hide()
};
typeahead.render = function(items) {
    var that = this

    items = $(items).map(function (i, item) {
        i = $(that.options.item).data('value', item)
        i.find('a').html(that.highlighter(item))
        return i[0]
    });

    items.first().addClass('active')
    this.$menu.html(items)
    return this
};

If you need help with the other ones, then let me know, but the gist of it is:

control.typehead({
    matcher: function (item) {
        var lcQuery = this.query.toLowerCase();
        return ~item.title.toLowerCase().indexOf(lcQuery)
            || ~item.description.toLowerCase().indexOf(lcQuery);
    }
};

I also have a JFiddle example related to the pull request that I made, but the sorting functions do not exist in 2.3.1, or even 3.x without the pull request being accepted, so you will have to override sorter in its entirety to effectively repeat what I did with matcher above (checking both while sorting).

As for the AJAX call, you can override the source method in the passed in options to get AJAX functionality. By not returning to the source call, it assumes that the second parameter, process, will be invoked with results.

control.typehead({
    minLength: 3,
    source: function(query, process) {
        $.ajax({
            url: url + encodeURIComponent(query),
            type: 'GET',
            success: process,
            error: function() { /* ... */ }
        });
    }
});

OTHER TIPS

Typeahead added support for multiple field searching in v10.3 https://github.com/twitter/typeahead.js/pull/811

Usage:
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'description'),

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top