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

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

Answers (9)

Slavi Cvetanov
Slavi Cvetanov

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

You need to use the option minLength: 0

Note:

There's a pull request which solved this issue

Upvotes: 14

NinjaKC
NinjaKC

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

Jonathan Lidbeck
Jonathan Lidbeck

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

vanval
vanval

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

Scottie
Scottie

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

Josh Dean
Josh Dean

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

Robert
Robert

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

Snekse
Snekse

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

Related Questions