Reputation: 9611
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?
Upvotes: 4
Views: 2435
Reputation: 550
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'),
Upvotes: 0
Reputation: 22332
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() { /* ... */ }
});
}
});
Upvotes: 2