I have a TypeAhead/Bloodhound implementation in my frontend, that fetches JSON-data from a Play/Scala-server. Typeahead-version is 0.11.1. The implementation is as follows:
HTML:
<div id="typeahead" class="col-md-8">
<input class="typeahead form-control" type="text" placeholder="Select the user">
</div>
JavaScript:
var engine = new Bloodhound({
datumTokenizer: function (datum) {
var fullName = fullName(datum);
return Bloodhound.tokenizers.whitespace(fullName);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
identify: function(obj) { return obj.id; },
remote: {
url: routes.controllers.Users.index("").url,
cache: false,
replace: function (url, query) {
if (!isEmpty(query)) {
url += encodeURIComponent(query);
}
return url;
},
filter: function (data) {
console.log(data);
return $.map(data, function (user) {
return {
id: user.id,
fullName: viewModel.fullName(user)
};
});
}
}
});
// instantiate the typeahead UI
$('#typeahead .typeahead')
.typeahead({
hint: true,
highlight: true,
minLength: 1,
},
{
name: 'engine',
displayKey: 'fullName',
source: engine
})
function fullName(data) {
if (data === undefined) return "";
else {
var fName = data.firstName === undefined ? "" : data.firstName;
var lName = data.lastName === undefined ? "" : data.lastName;
return fName + ' ' + lName;
}
};
JSON-response the server gives:
[{"firstName":"Test","lastName":"User", "id":1}, ... ]
The server pages the result so that it gives maximum of 5 results, which is supposed to be the default limit for Typeahead/Bloodhound as well.
The problem is that when the server returns 5 results, Typeahead shows 0 results in the overlay. If the server gives 4 results, TypeAhead shows 1 in the overlay. If the server gives 3 results, TypeAhead shows 2 results. For 2 and 1 results it shows the correct number of elements in the overlay. If I remove the page length and the server returns over 10 results, then TypeAhead shows 5 results (the limit). console.log inside the filter shows the correct number of data-results, so they go to Bloodhound at least.
What might be the issue with this code? This TypeAhead-field is the only TypeAhead-field present in this page. I checked the DOM, and TypeAhead generates wrong amount of result-set fields, so it's not a problem with CSS (tried to remove all custom CSS as well).
Thanks for any replies :)
There is an issue on typeahead in the code:
https://github.com/twitter/typeahead.js/issues/1218
You can change the code yourself in the JS as described on the issue page.
Twitter supposedly abandoned the project. Try the maintained fork. It has the issue fixed.
Try initializing engine
with engine.initialize()
; returning suggestion
object at filter
, which should be available at templates
-> suggestion
; initializing engine
at source
with source:engine.ttAdapter()
; returning element as String
at suggestion
, to populate "suggestion" drop down menu . See Typeahead - examples - Custom Templates
var data = [{
"firstName": "Test",
"lastName": "User",
"id": 1
}, {
"firstName": "Test2",
"lastName": "User2",
"id": 2
}, {
"firstName": "Test3",
"lastName": "User3",
"id": 3
}, {
"firstName": "Test4",
"lastName": "User4",
"id": 4
}, {
"firstName": "Test5",
"lastName": "User5",
"id": 5
}];
var engine = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: $.map(data, function(val, key) {
// return `suggestion` object for `templates` `suggestion`
return {value:val.firstName, suggestion:val}
})
});
// initialize `engine`
engine.initialize();
// instantiate the typeahead UI
$("#typeahead .typeahead")
.typeahead({
hint: true,
highlight: true,
minLength: 1,
}, {
name: "engine",
displayKey: "firstName",
templates: {
suggestion: function (data) {
// `suggestion` object passed at `engine`
console.log(data.suggestion);
// return suggestion element to display
var _suggestion = "<div>"
+ data.suggestion.firstName
+ " "
+ data.suggestion.lastName + "</div>";
return _suggestion
}
},
source: engine.ttAdapter()
});
<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>
<div id="typeahead" class="col-md-8">
<input class="typeahead form-control" type="text" placeholder="Select the user">
</div>
If (ike me) you don't want to go into the typeahead source, (for instance because you want to use the min version) you can also set limit very high. You will then have to limit the number of items to put into the list yourself.
$('#typeahead .typeahead')
.typeahead({
hint: true,
highlight: true,
minLength: 1,
},
{
name: 'engine',
displayKey: 'fullName',
source: engine,
limit: 1000
})
来源:https://stackoverflow.com/questions/30125410/typeahead-js-and-bloodhound-showing-an-odd-number-of-results