使用与 JSON 数据不同的值,而不是使用 Typeahead 的 displayKey



>我已经开始使用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?使用此插件甚至可以这样做吗?任何帮助将不胜感激。

谢谢!

> displayKey 用于指示用户选择条目后应在下拉列表输入字段中显示哪个键。

如果您希望下拉列表中显示的条目输入字段中的最终条目不同,则需要使用自定义模板。

从文档中:

suggestion – 用于呈现单个建议。如果设置,这必须是 预编译模板。关联的建议对象将用作 上下文。默认为包装在p标签中的displayKey值,即 <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-Guru。所以我更喜欢简单的方法。只是为了了解我稍后查看代码时做了什么......

感谢Eric Saupe,我找到了一个聪明的解决方案:

//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脚本

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

只需使用 github 上的文档中描述的预键入自定义事件即可。

希望,这有所帮助(当它仅供我以后参考时)。

吉斯菲德尔

您需要使用 'displayKey' 变量。请参阅下面的预键入文档中的复制粘贴:

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

您当然希望将本地更改为预取/远程,就像对 json 文件所做的那样。

更新

小提琴

有同样的问题,无法让它与显示或显示键属性一起工作。通过将 name 属性添加到源对象来解决它:

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

添加需要在显示参数中显示的值:

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

希望这是有帮助的

最新更新