Reputation: 3376
I'm using Typeahead.js in an autocomplete text input, and it's great. But I need to activate the dropdown menu with all the available options when the input gets focus. Every possible solution I've seen involves initializing the input with some value, but I need to show all the options.
How could I achieve this?
Upvotes: 30
Views: 30406
Reputation: 11
The easiest way that I achieved this behavior is to set minLinegth to zero and to set the prefetch property. Instead to set local JSON source just put the search url without the query parameter:
let baseUrl = 'some-url.com',
url = baseUrl + '?search=%QUERY';
...
$el.typeahead({
minLength: 0,
highlight: true,
prefetch: baseUrl
}, {
...
});
Upvotes: 1
Reputation: 3376
You need to use the option minLength: 0
Note:
There's a pull request which solved this issue
Upvotes: 14
Reputation: 841
Any answer that says "minLength: 0 is all you need", is NOT TRUE.
"Out Of The Box" Typeahead v0.11.1 'does need' minLength set to 0, but ALSO if you are using the out of the box Bloodhound Engine, then you need to be sure to set
identify: function(obj) { return obj.team; },
on your Bloodhound Object..
You also need a "middle man" function to handle your "empty query", which is where you will tell Bloodhound to cooperate..
function nflTeamsWithDefaults(q, sync) {
if (q === '') {
sync(nflTeams.all()); // This is the only change needed to get 'ALL' items as the defaults
} else {
nflTeams.search(q, sync);
}
}
You can see the FULL EXAMPLE here..
var nflTeams = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('team'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
identify: function(obj) { return obj.team; },
prefetch: '../data/nfl.json'
});
function nflTeamsWithDefaults(q, sync) {
if (q === '') {
sync(nflTeams.all()); // This is the only change needed to get 'ALL' items as the defaults
}
else {
nflTeams.search(q, sync);
}
}
$('#default-suggestions .typeahead').typeahead({
minLength: 0,
highlight: true
},
{
name: 'nfl-teams',
display: 'team',
source: nflTeamsWithDefaults
});
MORE SPECIFICALLY YOU CAN SEE THE OFFICIAL TWITTER TYPEAHEAD DEFAULT SUGGESTION ON FOCUS EXAMPLE AT THE FOLLOWING ADDRESS, WITH THE SIMPLE CHANGE FROM .get() TO .all() (SEE ABOVE OR BELOW)
http://twitter.github.io/typeahead.js/examples/#default-suggestions
... hope this helps someone, as it took me some time to find this information (found it by following all the bug reports & experimenting to find .all() method) ...
Upvotes: 28
Reputation: 1614
In typeahead v.0.11.1, the patch referenced in other answers has been applied. You can achieve this with the option:
minLength: 0
Works on keyboard or mouse focus. No code changes or new events needed.
Upvotes: 1
Reputation: 1027
There is a way to do this now without having to modify the typeahead source file. You have to do two things - set minlength to 0 and also add an event handler for the focus event: In the below example which I copied from the first example on the Twitter page (https://twitter.github.io/typeahead.js/examples/) - make sure the location to typeahead.js and jquery-ui.js is correct.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="typeahead.js"></script>
<script src="jquery-ui.js"></script>
<script>
$(function(){
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substrRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
// the typeahead jQuery plugin expects suggestions to a
// JavaScript object, refer to typeahead docs for more info
matches.push({ value: str });
}
});
cb(matches);
};
};
var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];
$('.typeahead').typeahead({
hint: true,
highlight: true,
minLength: 0
},
{
name: 'states',
displayKey: 'value',
source: substringMatcher(states)
});
$('.typeahead').on( 'focus', function() {
if($(this).val() === '') // you can also check for minLength
$(this).data().ttTypeahead.input.trigger('queryChanged', '');
});
});
</script>
</head>
<body>
<input class="typeahead" type="text" placeholder="States of USA">
</div>
</body>
</html>
Verified this works with 0.10.5. Note: Found this does not work with the Bloodhound search engine since the queryTokenizer for Bloodhound expects a character.
Upvotes: 3
Reputation: 111
I made a quick modification to 10.2 that made "the basics" example found here display on focus.
i changed the mixin _onFocus (line 1459) FROM:
_onFocused: function onFocused() {
this.isActivated = true;
this.dropdown.open();
},
TO:
_onFocused: function onFocused() {
this.isActivated = true;
var val = this.input.getInputValue();
var query = Input.normalizeQuery(val);
this.dropdown.update(query);
this.dropdown.open();
},
It's hardly official but it got the job done.
Upvotes: 11
Reputation: 1593
Using 0.10.4
To return all results for blank query add the following at line 450 of bloodhound.js
if (query == "") { return that.datums; }
To trigger the match on focus trigger the key down event on your input when focused
$(input_element).on("click", function () {
ev = $.Event("keydown")
ev.keyCode = ev.which = 40
$(this).trigger(ev)
return true
});
Upvotes: 3
Reputation: 1507
There's an easier way to do this now without modifying the source. It might be that the source has changed since this was originally answered, but I thought it worth putting here just in case.
After creating the typeahead:
var $element = $('#myTextElement');
$element.typeahead({ source: ['Billy', 'Brenda', 'Brian', 'Bobby'] });
Simply set the minLength to 0:
$element.data('typeahead').options.minLength = 0;
The minLength options is forced to 1 when the typeahead is created, but you can set it after creation and it works perfectly.
Upvotes: 2
Reputation: 15799
Another option is to use the non-public APIs of Typeahead. The full Typeahead object is available through jQuery's data
method.
var _typeaheadElem = $('#myInput').find('.typeahead');
var _typeahead = _typeaheadElem.data('ttTypeahead');
_typeaheadElem.focus(function() {
/* WARNING: This is hackery abusing non-public Typeahead APIs */
if (_typeaheadElem.val() === "") {
var input = _typeahead.input; //Reference to the TA Input class
//Set the component's current query to something !== input.
input.query = "Recent People";
input._onInput("");
}
});
See more code that works in v0.10.2 http://pastebin.com/adWHFupF
This is linked to PR 719 https://github.com/twitter/typeahead.js/pull/719
Upvotes: 0