Bootstrap3でオートコンプリートを使う

ユーザビリティ向上テーマでオートコンプリート機能は重要だとは考えていましたが、サーバ側への負荷などを考えると二の足を踏んでいました。

今回はリクエストまでの待機時間(入力開始から2秒間は要求を出さない)や入力文字数制限(2文字以上タイプが無いと要求を出さない)といった制限を設けることで悩みを解消しました。

色々とやり方はあるようですが、typeaheadとBloodhoundの組み合わせを使いました。
理由は特にないのですがBootstrap3を使ったケースで調べてたら、このパターンが多いようだったので採用しました。

以下がソースになります。

var bloodhound = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    rateLimitWait: 2000,
    remote: {
        url: "product/get_list.json",
        prepare: function(query, settings){
            settings.type = "POST";
            settings.data = "sess_param=" + sess_param + "&title=" + query;
            return settings;
        },
        filter: function(response){
            return $.map(response.records, function (item) {
                return { title: item.title, id: item.id };
            });
        }
    }
});
bloodhound.initialize();
$('.typeahead').typeahead({
    highlight: true,
    hint: true,
    minLength: 2,
    classNames: {}
}, {
    name:'items',
    displayKey: 'title',
    source: bloodhound.ttAdapter()
}).on("typeahead:selected typeahead:autocomplete", function(e, data) {
    var id = (e.currentTarget.id).split('-');
    return $('#id_products' + '-' + id[1]).val(data.id);
});

typeaheadのminLengthで入力文字数の制限を行います。
また、今回は複数レコードを登録する画面での実装だったため、候補が選択された場合のイベントを定義し、複数存在する名称入力欄のid属性から名称とIDを紐付し、該当するID入力欄にも値を設定しました。

BloodhoundのrateLimitWaitで待機時間を指定します。
外部APIに対してPOSTメソッドでデータを取得する場合は、remote.prepareにリクエストを指定してあげれば良いようです。
なお、リクエストクエリがJSON形式の場合は、併せて以下を指定します。

settings.contentType = "application/json; charset=UTF-8";

あとは、HTMLに以下のような感じでクラス指定すれば、全ての名称入力欄に対してオートコンプリートを実装する事ができました~♪

<input type="text" name="title_product" id="title_product_0" placeholder="Product Title" class="form-control typeahead" />

いやー、これ、使っててメチャ便利やんて思いました。
早く実装してれば良かったかな ^^;

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です