javascriptautocompletetypeahead.jstwitter-typeahead

Update or change typeahead data


I'm using this typeahead library: http://twitter.github.io/typeahead.js/

I managed to create a sample same as they have on their page with having local values.

$( document ).ready(function() {
  var globalResults = ["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 Dakota","North Carolina","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"];

  var substringMatcher = function(strs) {
    return function findMatches(q, cb) {
      var matches, substringRegex;

      // 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)) {
          matches.push(str);
        }
      });

      cb(matches);
    };
  };

  $('#search-input').typeahead({
    hint: true,
    highlight: true,
    minLength: 1
  },
  {
    name: 'globalResults',
    source: substringMatcher(globalResults)
  });
});

The problem is when I update the globalResults, the typeahead still shows the same old results Alambama, Alaska...

I'm trying to update them this way, but it doesn't work:

globalResults = results;
var autocomplete = $('#search-input').data('typeahead');
autocomplete.source = globalResults;

Results are retrieved from a server in a string array. I debugged it and it contained the new data and it did copy them into globalResultes and updated it. But somehow this line does nothing:

autocomplete.source = globalResults;

Where might be the problem for which the source for typeahead is not updating?

My html looks like this:

<span style="position: relative; display: inline-block;" class="twitter-typeahead">
            <input type="text" spellcheck="true" class="form-control typeahead tt-input" placeholder="Search for science, search for data ..." id="search-input" autocomplete="off"></input>
</span>

Solution

  • The only way I was able to update the datasource used is by using BloodhoundJS with TypeaheadJS.

    I initialize a local source:

    var globalResults = ["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 Dakota", "North Carolina", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"];
    

    and an alternative local source:

    var otherResults = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
    

    I create a bloodhound instance and set it to a local data source:

    var states = new Bloodhound({
      datumTokenizer: Bloodhound.tokenizers.whitespace,
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      local: globalResults
    });
    

    I create a method to switch between the sources. In this case I use a button and on click, make the change:

    $(document).on('click', '#changeSource', function() {
        console.log('change the data');
      states.clear();
      states.local = otherResults;
      states.initialize(true);
    });
    

    This will work for remote data as well.

    Here is a fiddle demonstration.