Подтвердить что ты не робот

Используйте другое значение из данных 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 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()
});

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

Спасибо!

4b9b3361

Ответ 1

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 будет отображаться в поле ввода после того, как пользователь выберет запись.

Ответ 2

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

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

//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, как описано в docs на github.

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

JSFIDDLE

Ответ 3

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

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();, чтобы очистить кеш к более легким трекам.

Ответ 4

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

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 файл.

UPDATE

FIDDLE

Ответ 5

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

            $.each(stocks, function (i, item) {
                item.name = item.company_name;
            });

Ответ 6

Добавьте значение, которое должно отображаться в параметре 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; }
});

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