UPDATE
Based on the correct answer from @BenSmith (https://stackoverflow.com/users/203371/BenSmith) I was able to find my problem and found out I was no
My answer is nothing new, but just an update for v0.11 of twitter typeahead. As always, redirect your upvotes (if any) to the original answer.
A friendly reminder to everyone who are still using Twitter-Typeahead is to move away from this repository as it is no longer maintained. Instead redirect yourself to corejavascript/typeahead.js which is a fork of the original repository, and the same author (@JakeHarding) maintains this repository.
From v0.10 to v0.11 a few things have changed, and so must the answer. Here is my new code for this newer version.
HTML
<div id="prefetch">
<input class="typeahead" type="text" placeholder="Countries">
</div>
JS
var tags = new Bloodhound({
datumTokenizer: function(datum) {
return Bloodhound.tokenizers.whitespace(datum.name);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'http://www.yourwebsite.com/js/data.json',
cache: false,
transform: function(response) {
return $.map(response, function (tag) {
return {
name: tag.tagName,
id: tag.tagId
}
});
}
}
});
$('#prefetch .typeahead').typeahead({
minLength: 3,
highlight: true
}, {
name: 'tags-dataset',
source: tags,
display: 'name'
});
What has changed:
filter
option under prefetch
. Instead you have to use transform
.displayKey
under typeahead()
function has been changed to simply display
.cache
under transform
option is set to false so that the data source is loaded every time. This is good for testing, but in production server, this option must be disabled if caching of data is required.As an additional note to folks who are trying this example with different data sources with
cache
set to true. You must always runwindow.localStorage.clear();
method in your console to clear the already present local storage so that new data can be retrieved. Failing to do so will result in the old data being used, and you might think why your code is not working.
Here is a working JSFIDDLE example to get you started. A few points to note:
[{"tagId":9,"tagName":"Action"},{"tagId":10,"tagName":"Adventure"},{"tagId":6,"tagName":"Books"},{"tagId":11,"tagName":"Fantasy"},{"tagId":2,"tagName":"Games"},{"tagId":1,"tagName":"Movies"},{"tagId":3,"tagName":"Music"},{"tagId":8,"tagName":"News"},{"tagId":4,"tagName":"Office"},{"tagId":5,"tagName":"Security"},{"tagId":7,"tagName":"TV-Shows"}]
You need to write the filter function so that it creates an array of javascript objects to use as the datums. The following should work (I haven't tested this):
filter: function (response) {
return $.map(response.songs, function (song) {
return {
title: song.title,
artistName: song.artist_name
};
});
}
(an example of the filter function can be found here)
And change your datumtokenizer to:
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.title);
}
also change your displaykey to:
displayKey: 'title'
As this is the key which Typeahead will be using for searching.
As for displaying the song name and artist in the list of suggestons, I suggest you use templating (e.g. Handlebars) for displaying the results. See the "Custom Template" example in Typeahead's examples page. Your suggestion mark-up will then look similar to the following:
suggestion: Handlebars.compile('<p><strong>{{title}}</strong> by {{artistName}}</p>')