Use different value from JSON data instead of displayKey using Typeahead

user1779796 picture user1779796 · Feb 20, 2014 · Viewed 50.6k times · Source

I have started using Typeahead.js and am struggling to figure out a way of allowing a user to type and search for a company name, once selected input the associated company code.

.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: function(d) {
        return Bloodhound.tokenizers.whitespace(d.code);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    limit: 3,
    prefetch: {
        url: 'javascripts/stockCodes.json',
        filter: function(list) {
            return $.map(list, function(stock) {
                return {
                    code: stock
                };
            });
        }
    }
});

stocks.initialize();

$('.typeahead').typeahead(null, {
    name: 'stocks',
    displayKey: 'code',
    source: stocks.ttAdapter()
});

Currently, this just displays the list of codes when the user types in the input field. However, I would like to know if there is a way to allow them to search on code but once selected, the value in the textbox to be company_name? Is this even possible using this plugin. Any help will be greatly appreciated.

Thanks!

Answer

Esseb picture Esseb · Aug 25, 2014

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 of displayKey wrapped in a p 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.