web-dev-qa-db-ja.com

Typeaheadを使用してdisplayKeyの代わりにJSONデータとは異なる値を使用します

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?このプラグインを使用してこれも可能ですか?どんな助けも大歓迎です。

ありがとう!

29
user1779796

displayKeyは、ユーザーがエントリを選択した後、入力フィールドのドロップダウンリストandに表示するキーを示すために使用されます。

ドロップダウンリストに表示されるエントリを、入力フィールドの結果と異なるdifferentにする場合は、カスタムテンプレートを使用する必要があります。

ドキュメント から:

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が表示されます。

33
Esseb

私は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のドキュメント で説明されているように、先行入力カスタムイベントを使用するだけです。

これが役立つことを願っています(そして、あとで参照するためだけの場合)。

[〜#〜] jsfiddle [〜#〜]

18
Tobse

「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();を呼び出してキャッシュをクリアし、バグを追跡しやすくすることを忘れないでください。

6
bblue

私が正しく読んだ場合、これはあなたが望むものだと思います:

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ファイルの場合と同じように、ローカルをプリフェッチ/リモートに変更する必要があります。

[〜#〜] update [〜#〜]

[〜#〜] fiddle [〜#〜]

4
Tomanow

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

これがお役に立てば幸いです

0
ArtisanBay

同じ問題があった場合、displayまたはdisplayKeyプロパティで動作させることができませんでした。ソースオブジェクトにnameプロパティを追加することで回避しました。

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