読者です 読者をやめる 読者になる 読者になる

Rails でオートコンプリート機能を実装する

Rails gem

Rails で typeahead ライブラリを使ってオートコンプリート検索を実装する方法です。

twitter/typeahead.js · GitHub

こんな感じ。

f:id:kzy52:20150118101819p:plain

環境

rails-assets-typehead.js 0.10.5

typehead gem を追加する

# Gemfile

# 追加
source 'https://rails-assets.org'
gem 'rails-assets-typehead.js'
$ bundle install

typehead ライブラリを assets に追加する

# app/assets/javascripts/application.js

...
//= require typehead
...

typehead 用のスタイルシートを assets に追加する

https://github.com/bassjobsen/typeahead.js-bootstrap-css

これを使わせてもらう。
ダウンロードしたファイルは vendor/assets/stylesheets/typeaheadjs.css として配置する。

# app/assets/stylesheets/application.css

...
 *= require typeaheadjs
...

絞込結果を返す API を作成する

# app/controllers/movies_controller.rb

class MoviesController < ApplicationController
  def index
    render json: Movie.where(Movie.arel_table[:title].matches("%#{params[:term]}%"))
  end
end

フォームを作成する

# app/views/home/index.html.erb

<%= form_tag('/watchlist') do %>
  <div class="field">
    <%= text_field_tag :movie_id, nil, autofocus: true, class: 'typeahead' %>
    <%= hidden_field_tag :movie_id, nil, class: 'hidden-movie-id' %>
  </div>
<% end %>

オートコンプリート処理を追加する

# app/assets/javascripts/typehead_sample.coffee

$ ->
  engine = new Bloodhound(
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value')
    queryTokenizer: Bloodhound.tokenizers.whitespace
    remote:
      url: '/movies?term=%QUERY' # %QUERY で入力された値を取得できる。
      filter: (movies) ->
        $.map movies, (movie) ->
          id: movie.id
          value: movie.title

  )

  engine.initialize()

  $('.typeahead').typeahead(
    {
      highlight: true
      hint: true
      minLength: 2 # 2文字以上入力されたら絞込開始。
    },
    {
      name: "movies"
      displayKey: 'value'
      source: engine.ttAdapter()
    }
  ).on "typeahead:selected typeahead:autocomplete", (e, item) ->
    $(this).closest(".field").find(".hidden-movie-id").val item.id # 選択後に id を hidden field に設定する。

これで完了。テキストフィールドに「アイ」と入力すると...

f:id:kzy52:20150125225449p:plain

こうなります。いい感じ!

ソースコード

https://github.com/kzy52/typehead-example

参考

http://twitter.github.io/typeahead.js/examples/