Twitter Typeahead.js: show all options when click/focus

29,226

Solution 1

You need to use the option minLength: 0

Note:

There's a pull request which solved this issue

Solution 2

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) ...

Solution 3

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.

Solution 4

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
    });

Solution 5

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.

Share:
29,226
César García Tapia
Author by

César García Tapia

I'm a developer and Open Source activist located in Madrid, Spain.

Updated on May 21, 2021

Comments

  • César García Tapia
    César García Tapia almost 3 years

    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?

  • yvesonline
    yvesonline over 9 years
    Nice, it's working, but you missed var in front of val and query.
  • Steve L
    Steve L over 9 years
    This did not work for me on 0.10.5. I get the following error: TypeError: $element.data(...) is undefined
  • Robert
    Robert over 9 years
    @SteveL, Yes - it look likes they've changed things quite a lot in 0.10.5. I tried modifying the minLength property using the new version, but it doesn't seem to work. Here is a fiddle where you can see my feeble attempts: jsfiddle.net/zL9uxm45
  • roberttdev
    roberttdev over 9 years
    As of today (10/31/14), the library still does not perform the requested behavior when passed minLength: 0 (although it will if you type something and then backspace so that there is no longer any input). Scottie's solution above works, however.
  • stawek
    stawek over 9 years
    This is valid solution. To make it work on input click you need to combine this with stackoverflow.com/a/24665299/449009 (above). Side note : line 450 means get method from SearchIndex class. Shame that there is need for source hacking to get such basic functionality, they are working on it like a turtles..
  • BraMKJ
    BraMKJ about 9 years
    The minLength: 0 option seems to partially work. If you click in an input field you can see all available results by pressing the down arrow on your keyboard. Would be nice though if did this on focus.
  • Johny Bravo
    Johny Bravo over 7 years
    This is just perfect. Works very well with version 0.11.1
  • fperet
    fperet over 6 years
    Somehow this isn't working when you have "remote" option for Bloodhound. nflTeams search runs, remote query is executed, data fetched but it doesn't appear as typehints. Any clue how to solve that?
  • fperet
    fperet over 6 years
    And I've found a solution by myself. Bloodhound search had 3 params: q, sync and async, so you just need to add async for middleman function and also search inside it.