Use different value from JSON data instead of displayKey using Typeahead
displayKey
is used to indicate which key should be shown in the dropdown list and in the input field after the user has selected an entry.
If you want the entries shown in the dropdown list to be different from what ends up in the input field you need to use a custom template.
From the documentation:
suggestion
– Used to render a single suggestion. If set, this has to be a precompiled template. The associated suggestion object will serve as the context. Defaults to the value ofdisplayKey
wrapped in ap
tag i.e.<p>{{value}}</p>
.
Something like this should work:
$('.typeahead').typeahead(null, { name: 'stocks', displayKey: 'company_name', source: stocks.ttAdapter(), templates: { suggestion: function (stock) { return '<p>' + stock.code + '</p>'; } }});
The submitted template will be used to show stock.code
in the dropdown list, while stock.company_name
will be shown in the input field after the user selects an entry.
I am no jQuery / JavaScript-Guru. So I prefer it the easy way. Just to understand what I did when I look at my code later...
Thanks to Eric Saupe I found a smart solution:
//JSON FILE[ { "company_name": "Facebook", "code": "fb", }, { "company_name": "Google", "code": "goog", }, { "company_name": "Yahoo", "code": "yhoo", }, { "company_name": "Apple", "code": "aapl", }, { "company_name": "Royal Mail", "code": "rmg.l", }, ]
// JS SCRIPT
var stocks = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('company_name'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: 'javascripts/stockCodes.json' }); stocks.initialize(); $('.typeahead').typeahead( null, { name: 'stocks', displayKey: 'company_name', source: stocks.ttAdapter() }).on('typeahead:selected', function(event, data){ $('.typeahead').val(data.code); });
Just use the typeahead custom events as described in the docs on github.
Hope, this helps (and when it's just for my own later reference).
You need to use the ´displayKey´ variable. See below copy-paste from the typeahead docs:
displayKey – For a given suggestion object, determines the string representation of it. This will be used when setting the value of the input control after a suggestion is selected. Can be either a key string or a function that transforms a suggestion object into a string. Defaults to
value
.
https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md
Your specific code would then be something like this:
var stocks = new Bloodhound({ datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.code); }, queryTokenizer: Bloodhound.tokenizers.whitespace, limit: 3, prefetch: { url: 'javascripts/stockCodes.json', filter: function(list) { // This should not be required, but I have left it incase you still need some sort of filtering on your server response return $.map(list, function(stock) { return { code: stock.code, company_name: stock.company_name }; }); } } }); stocks.initialize(); $('.typeahead').typeahead(null, { name: 'stocks', displayKey: function(stock) { return stock.company_name; }, source: stocks.ttAdapter() });
I had a very similar requirement on my own site, and I had this working with no issue. I have not tried this particular example though, so let me know if it works.
Remember to call stocks.clearPrefetchCache();
to clear your cache to easier track bugs.