2020.01.26

【Rails】JQuery UI オートコンプリートを実装してみました【Javascript】

オートコンプリート実装手順

オートコンプリートってこんな感じのやつです。これから実装手順を書いていきます!

 

 

何番煎じだよって記事内容ですが、なかなか実装できずに超絶苦戦したので、自分なりに改良した実装方法をまとめておきたいと思います。

因みに実装に至るまで色々なgem(rails4-autocomplete, typeahead等々。。)を試してみたのですが、どうにもうまくいかなかったです。はい、単なる知識不足です。すみません。。

参考記事

Rails 5 Auto completeを実装してみた

jQueryUI オートコンプリート機能の実装

gem諸々の初期準備

入れる必要のあるgemは以下2つです。bootstrapが入っていれば追加する必要ないかもですが、一応。

gem 'jquery-ui-rails'
gem 'jquery-rails'
application.js
//= require rails-ujs
//= require bootstrap 
//= require jquery-ui
application.css
*= require jquery-ui

gem入れた後はbundle installを忘れずに。

サジェストをとりあえず表示させてみる

最初は簡単な形でサジェストを効かせてみます。viewファイルを整えたあと、assets/javascripts以下にidol.jsファイルを作成します。

views/idols/idol.html.erb
<%= form_with(model: image, local: true) do |form| %>
  <%= form.label :idolname %>
    <%= form.text_field :idolname, id: :idolname %>
    <%= form.submit %>
<% end %>
assets/javascripts/idol.js
$( function() {
  var places = ['品川','有楽町','浜松町','江戸川'];
  $( '#idolname' ).autocomplete({
      autoFocus: true,  //テキストフィールドの値をフォーカスされたアイテムの値で置き換える
      source: places,  //サジェストのデータを呼び出す
      minLength: 1  //オートコンプリートが動作する文字数を指定
  });
});

 

これだけでひとまずはサジェストが開くと思います。

ただ、オートコンプリートを使う際はサジェスト候補が多い場合がほとんどだと思うのでDBからデータを取得⇒サジェスト表示の方法をやっていきたいと思います。

DBのデータをjsonファイルで表示させる

モデルを作成し、必要なカラムを追加します。今回はカラム名: idolname とします。必要な入れ物を準備できたので、その中にseedでデータを投入していきます。データが入っているか一応dbconsoleで確認してみます。

dbconsole
sqlite> select * from idols;

データが重複して入っている時があるのでその場合は、rails migrate:resetしたのち、再度rails db:seedで入れ直してみてください。データが入ったのを確認したら、次はcontrollerのアクションを追加していきます。

controllers/images_controller.rb
def new
  @idol = Idol.new idols = Idol.all //データを全て取得
  idols = idols.map(&:idolname) //:idolnameを取り出し、戻り値として配列で作成 
  render json: idols.to_json //jsonファイルとして受け渡す 

  respond_to do |format| //respondo_to=指定した形式で返すようにするメソッド
    format.html format.json
  end 
end

jsonファイルが作成されているかURLを開いて確認してみます。

http://localhost:3000/images/new.json

こんな感じで表示されたらOKです!

絞り込みできるようにする

このままだと、まだサジェストの候補を絞り込めないので各ファイルにもうひと手間かけてオートコンプリートを完成させます。

controllers/images_controller.rb
def auto_complete
  idols = Idol.select(:idolname).where("idolname like '%" + params[:term] + "%'").order(:idolname)
  idols = idols.map(&:idolname) render json: idols.to_json 
end

先ほど作成したnewアクションと中身はほとんど同じですが、入力された値( params[:term])をもとにidolnameから探す処理を追加しているっぽい。一致したデータを先ほど同様mapメソッドで配列で取得してjsonファイル形式にしている流れになります。

config/routes.rb
resources :images do
  collection do
    get "auto_complete" 
  end 
end

ルーティングを設定してURLにアクセスできるようにする。

assets/javascripts/idol.js
$( function() {
  $( '#user_name' ).autocomplete({
    autoFocus: true, 
    source: "/images/auto_complete.json",
    minLength: 1 
  });
});

sourceにauto_completeのURLを設定します。

これで完成!早速投稿してみよう!

あれ??サジェストから選んだデータがDBに格納されていない?

はい、このままではフォームから値を受け取れませんでした。自分はここで苦戦しました(- -;)

というわけで、フォームから値を受け取る処理をcreateアクションに追加していきます。

フォームから値を受け取れるようにする

下記行をcreateアクションに追加してください。

controllers/images_contorller.rb
def create
  ・
  ・
  @image.idolname = params[:image][:idolname] //createアクションに追加
  ・ 
  ・ 
end

これは、フォームの値をparamsで受け取り、imageのidolnameカラムに格納する流れになります。rails dbconsoleで値が格納されているか一応確認してみてください。ちゃんとはいっているはず。結構長くなりましたが以上です。お疲れ様でした!

一応完成形

DBにもちゃんと値を格納できてますね!

 

だいぶ冗長的に書いていますが、勉強もといアウトプット含めたものですのであしからず

もっといい方法があれば教えてください!