Edited at

twitter typeaheadはいろいろ改良されていた

More than 5 years have passed since last update.

Bootstrap内にもauto complete機能としてtypeaheadがあるが、日本語の扱いに難があるみたい。

Bootstrap Typeaheadの日本語入力対応 | PLUS

ARKの技術メモ: [Twitter Bootstrap]typeaheadでの日本語入力問題への対策

だが、Bootstrap内とは別にtwitter制作のtypeaheadライブラリがあり、これを使用してみると日本語問題はないっぽい。しかも、機能も強化されている。

twitter/typeahead.js

typeahead.js – examples

そこで、いくつかサンプルを。

なお、この説明に使用しているtypeahead.jsのバージョンは0.9.3になります。

2014年2月5日現在、バージョンは0.10.0となっており、設定が違っているみたいです(コメントありがとうございました)なので、参考までにしてください。


データ埋め込みサンプル

もっとも簡単に、データを直接埋め込むサンプル。

CSSはjharding/typeahead.js-bootstrap.cssから拝借。

<!DOCTYPE html>

<link href="bootstrap.min.css" media="screen" rel="stylesheet" type="text/css" />
<link href="typeahead.js-bootstrap.css" media="screen" rel="stylesheet" type="text/css" />
<div class="container">
<h1>テスト</h1>
<input type="text" class="ta" name="name">
</div>
<script src="jquery.js" type="text/javascript"></script>
<script src="typeahead.js" type="text/javascript"></script>
<script src="sample.js" type="text/javascript"></script>


sample.js

$(function() {

return $('.ta').typeahead({
name: 'names',
local: ["斉藤", "斉木", "大野", "大原"],
limit: 10
});
});

type1.png

・・・動いた


jsonで別ファイルに持つサンプル

以後は、サーバー上でないと動かない。

まず、データファイルはjson形式で別に持つことができる。

[

{
"value":"斉藤",
"tokens":["さいとう","saito"]
},{
"value":"斉木",
"tokens":["さいき","saiki"]
},{
"value":"大野",
"tokens":["おおの","oono"]
},{
"value":"大原",
"tokens":["おおはら","oohara"]
}
]

ここで、

* valueは、実際にテキストボックスに入る値

* tokensは、入力された文字列に反応させたい値を配列で入れる。

上記の例では、「斉藤」は、「さいとう」でも、「saito」でもヒットするように設定している。

これを、サーバー上の適当な場所に保存(ここではルートに保存)


sample.js

$(function() {

return $('.ta').typeahead({
name: 'names',
prefetch: '/sample.json',
limit: 10
});
});

(htmlはそのまま)

type2.png

type3.png

できた。


idもhiddenフィールドとして保存したい

これまでのサンプルのようなユーザーデータで、ユーザーごと名前をテキストボックスに

保存するだけでなく、IDも一緒に保存したいとする。ついでに、部署情報も追加して

テンプレートシステムを利用してみる。テンプレートエンジンは、本家にならって

twitter/hogan.js

を利用してみる。

用意したサンプルのjsonは以下の通り。

[

{
"value":"斉藤",
"id": 1,
"busho": "営業部",
"tokens":["さいとう","saito"]
},{
"value":"斉木",
"id": 2,
"busho": "経理部",
"tokens":["さいき","saiki"]
},{
"value":"大野",
"id": 3,
"busho": "営業部",
"tokens":["おおの","oono"]
},{
"value":"大原",
"id": 4,
"busho": "管理部",
"tokens":["おおはら","oohara"]
}
]

htmlも、以下のように、IDを保持するためのhidden属性のinputを用意する

<input class="ta" name="prefs" type="text" />

<input id="hidden_id" name="id" type="hidden" />

javascript部分も以下のように変更。


sample.js

$(function() {

return $('.ta').typeahead({
name: 'name-busho2',
prefetch: '/sample.json',
template: '<div style="width:10em"><p style="float:right">{{busho}}</p><p>ID:{{id}}</p><p style="font-weight:bold">{{value}}</p></div>',
engine: Hogan
}).on("typeahead:selected typeahead:autocomplete", function(e, datum) {
return $('#hidden_id').val(datum.id);
});
});

ここで、name属性は一応変更(任意の値でいいみたい)。

また、templateではヒットしたものをどのように表示するのか、ここで自由に指定できる。内容は普通のHTMLで、コード中に{{属性の項目名}}で、その項目名を埋め込むことができる(この表記はテンプレートエンジンHoganの表記法)。この自由さがtwitter typeaheadの魅力だと思う。Bootstrapのtypeaheadでもできるにはできたが、面倒だったはず。これで、valueとIDだけでなく、自由に項目を追加、扱うことができる。

実際に選んだあとの処理は、カスタムイベントのtypeahead:selectedtypeahead:autocompleteが定義されているので、そのイベント発生時の処理をon("typeahead~以下に記述する。

functionはeとdatumの2つの引数をとるが、datumに、実際選ばれたオブジェクトの情報が入っている。idはdatum.idでとれるので、あとは普通に所定のものにセットするだけ(部署情報はdatum.bushoなど、ほかの値も自由にとれる)

実際の画面はこんな感じに。

type4.png

firebugでhidden_idを見ると、更新されている。

type5.png


リモートでやり取りしたい

ここまでくると簡単で、javascriptコードの

prefetch: ~

の部分を

remote: "/usr/find/%QUERY"

に変更するとajax通信をする。タイプされた内容は%QUERYの中に入る。なので、単純に

remote: "/usr/find?name=%QUERY"

とすると、params[:name]でタイプされた内容をサーバー側で補足することができる。

もちろん、サーバーからの返事はjsonが無難。

また、上記のremote設定は簡略版で、詳細版はremote部分を

remote: {

url: '/states?q=%WILDCARD',
wildcard: '%WILDCARD',
rateLimitFn: 'throttle',
rateLimitWait: 300, // rateLimitWait or wait? i think i prefer the former
maxConcurrentConnections: 4,
dataType: 'json',
timeout: 2000,
cache: true,
beforeSend: function(jqXhr, settings) { /* set headers, etc. */ },
filter: function(resp) { /* parse suggestions out of response */ }
}

このようなオプションを指定することができる。