LoginSignup
131
133

More than 5 years have passed since last update.

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

Last updated at Posted at 2013-07-21

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  */ }
  }

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

131
133
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
131
133