简体   繁体   中英

Typeahead.js - prefetch dynamic php generated JSON

I'm using Typeahead.js for my autosuggestions, my code is:

var job_scopes = new Bloodhound({
    datumTokenizer: function(d) {
        return Bloodhound.tokenizers.whitespace(d.value);
    },queryTokenizer: Bloodhound.tokenizers.whitespace,
    limit: 100,
    remote: {
        url: 'http://www.domain.com/json.php?action=job_title&q=%QUERY'
    }
});

job_scopes.initialize();

This works fine, however I would like to change it to prefetch , to be able to use tokens in my JSON and leave returning results based on tokens on Bloodhound.

I cannot simply create static JSON, as I have the suggestion items added to the db all the time.

Is there a way to prefetch the json dynamically?

I've written an example of Typeahead using prefetch . This example retrieves JSON data from a remote source:

http://jsfiddle.net/Fresh/1hrk0qso/

To prefetch the JSON from a remote source, the Bloodhound object was implemented as follows:

var countries = new Bloodhound({
 datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
 queryTokenizer: Bloodhound.tokenizers.whitespace,
 prefetch: {
 url: 'https://cdn.rawgit.com/twitter/typeahead.js/gh-pages/data/countries.json',
  filter: function (countries) {
      return $.map(countries, function (country) {
          return {
              name: country
          };
      });
  }
 }
});

You will replace the URL to a static JSON file (shown in the above code) with a URL which returns your dynamically generated JSON.

The key code here is the "filter" function which maps the flat JSON tokens to an array of Javascript objects which is what Typeahead needs to operate.

From the docs: "While it's possible to get away with it for smaller data sets, prefetched data isn't meant to contain entire data sets. Rather, it should act as a first-level cache for suggestions. If don't keep this warning in mind, you run the risk of hitting local storage limits."

https://github.com/twitter/typeahead.js/blob/master/doc/bloodhound.md#prefetch

I don't know how much data you are retrieving but it might be better to make an ajax call to get the data and then load that into your Bloodhound instance when you get the response.

Here is an example using a jQuery ajax call:

//Let's assume that the data you get back from the server is an array of objects
//data = [{value: 'a'}, {value: 'b'}, {value: 'c'}];

$.get( "http://example.com/your-data", function(data) {
  var bh = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: data
  });

  var dataset = {
    name: "My-dataset-name",
    displayKey: "value",
    source: bh.ttAdapter()
  };

  var ta = $(".typeahead").eq(0).typeahead(
    {
      hint: true
      highlight: true
      minLength: 1
    },
    datasetStates
    );
  ta.on('typeahead:selected', someFunctionToHandleEvent);
});

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM