Используйте другое значение из данных JSON вместо displayKey с помощью Typeahead

Я начал использовать Typeahead.js и изо всех сил пытаюсь найти способ, позволяющий пользователю вводить и искать название компании, после выбора ввода соответствующей балансовой единицы.

файл.json:

[{
    "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:

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()
});

В настоящее время это просто отображает список кодов, когда пользователь вводит в поле ввода. Тем не менее, я хотел бы знать, есть ли способ позволить им искать на code но после выбора значение в текстовом поле должно быть company_name? Это возможно даже с помощью этого плагина. Любая помощь будет оценена.

Спасибо!

6 ответов

displayKey используется для указания того, какая клавиша должна отображаться в раскрывающемся списке и в поле ввода после того, как пользователь выбрал запись.

Если вы хотите, чтобы записи, отображаемые в раскрывающемся списке, отличались от того, что заканчивается в поле ввода, вам нужно использовать пользовательский шаблон.

Из документации:

suggestion - Используется для предоставления одного предложения. Если установлено, это должен быть предварительно скомпилированный шаблон. Связанный объект предложения будет служить контекстом. По умолчанию значение displayKey завернутый в p тэг т.е. <p>{{value}}</p>,

Примерно так должно работать:

$('.typeahead').typeahead(null, {
    name: 'stocks',
    displayKey: 'company_name',
    source: stocks.ttAdapter(),
    templates: {
        suggestion: function (stock) {
            return '<p>' + stock.code + '</p>';
        }
    }
});

Представленный шаблон будет использован для показа stock.code в раскрывающемся списке, а stock.company_name будет отображаться в поле ввода после того, как пользователь выберет запись.

Я не JQuery / JavaScript-Гуру. Поэтому я предпочитаю это легкий путь. Просто чтобы понять, что я сделал, когда посмотрю свой код позже...

Благодаря Эрику Саупе я нашел умное решение:

//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);        
    });

Просто используйте пользовательские события typeahead, как описано в документации по github.

Надеюсь, это поможет (и когда это только для моей дальнейшей ссылки).

JSFIDDLE

Вам нужно использовать переменную "displayKey". Смотрите ниже copy-paste из документов typeahead:

displayKey - Для данного объекта предложения определяет его строковое представление. Это будет использоваться при установке значения элемента управления вводом после выбора предложения. Может быть либо ключевой строкой, либо функцией, которая преобразует объект предложения в строку. По умолчанию value,

https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md

Ваш конкретный код будет выглядеть примерно так:

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()
    });

У меня было очень похожее требование на моем собственном сайте, и у меня это работало без проблем. Я не пробовал этот конкретный пример, поэтому дайте мне знать, если он работает.

Не забудьте позвонить stocks.clearPrefetchCache(); очистить кэш, чтобы легче отслеживать ошибки.

Если я читаю правильно, я считаю, что это то, что вы хотите:

var stocksData = [{
    "Facebook": "fb",
}, {
    "Google": "goog",
}, {
    "Yahoo": "yhoo",
}, {
    "Apple": "aapl",
}, {
    "Royal Mail": "rmg.l",
}, ];

var stocks = new Bloodhound({
    datumTokenizer: function (d) {
                  for (var prop in d) {
                      return Bloodhound.tokenizers.whitespace(d[prop]);
                  }

    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    limit: 3,
    local: stocksData,
});

stocks.initialize();

$('input').typeahead(null, {
    name: 'stocks',
    displayKey: function(stocks) {
        for (var prop in stocks) {
            return prop;    
        }
    },
    source: stocks.ttAdapter()
});

Вы, конечно, захотите изменить локальный на prefetch/remote, как это было для файла json.

ОБНОВИТЬ

FIDDLE

Добавьте значение, которое должно отображаться в параметре display:

$(".comp-search").typeahead({
    hint: true,
    highlight: true,
    minLength: 1,
    displayKey: 'company_name',
}, {
    source: engine.ttAdapter(),
    templates: {
        empty: ['<div class="list-group search-results-dropdown"><div class="list-group-item">Nothing found.</div></div>'],
        header: ['<div class="list-group search-results-dropdown">'],
        suggestion: function (data) {
            return '<a href="javascript:void(0);" class="list-group-item">' + data.company_name + '</a>';
        }
    },
    display: function(data) { return data.company_name; }
});

Надеюсь, это полезно

Возникла та же проблема, не удалось заставить его работать со свойством display или displayKey. Обойти это, добавив свойство name к исходным объектам:

            $.each(stocks, function (i, item) {
                item.name = item.company_name;
            });
Другие вопросы по тегам