LoginSignup
1
1

More than 3 years have passed since last update.

acts-as-taggable-on と Tagit.jsを使ったオートコンプリート機能の作成

Last updated at Posted at 2020-07-16

完成系

スクリーンショット (26).png

開発環境

ubuntu(WSL)
Rails 6.0.2
Ruby 2.5.1

事前準備

  • タグ機能の作成
  • 投稿機能の作成(CRUD) タグ機能の作成に関してはこちらを参考にしてください。

Tagitの導入

下記のコマンドを実行して、vendor/assetsに配置してください。
vendor/assetsがない場合は自分で作ってください。

curl https://raw.githubusercontent.com/aehlke/tag-it/master/js/tag-it.js -o vendor/assets/javascripts/tag-it.js

curl https://raw.githubusercontent.com/aehlke/tag-it/master/css/jquery.tagit.css -o vendor/assets/stylesheets/jquery.tagit.css

curl https://raw.githubusercontent.com/aehlke/tag-it/master/css/tagit.ui-zendesk.css -o vendor/assets/stylesheets/tagit.ui-zendesk.css

Jquryを使うのでjqury-ui-railsをGemfileに追加下ください。

Gemfile.
gem 'ransack'
gem 'acts-as-taggable-on', '~> 6.0'
gem 'jquery-ui-rails' #追加

TagitとJquryUiを読み込むため、application.jsapplication.scssに以下を追加下ください。
とりあえず全て載せておきます。

application.js
//= require jquery #追加
//= require rails-ujs #追加
//= require popper
//= require turbolinks #追加
//= require_tree . #追加
//= require bootstrap
//= require activestorage
//= require jquery-ui/widgets/autocomplete #追加
//= require tag-it #追加
application.scss
/*
 *= require_tree . #追加
 *= require jquery.tagit #追加
 *= require tagit.ui-zendesk #追加
 *= require_self #追加
*/

テキストボックスを作ります。
form_forブロック内に任意のidをつける。
f.text_fieldにidをつけると二つテキストフィールドができてしまうので.form-groupにidをつけています。

views/micropost/_form.html.slim
= form_with model:  micropost, local: true do |f|
  = render 'shared/error_messages', object: f.object

  .form-group id="micropost-tags"
    = f.label :tag
    //タグの入力・保存表示
    //= f.text_field :tag_list, value: @micropost.tag_list.join(","), class: "form-control"

tagitの呼び出し

assets/javascripts/microposts.js
$(document).on('turbolinks:load', function () {
  return $('#micropost-tags').tagit({
  });

タグの保存

現状だとname属性が同じなのでsingleFieldを有効にしてname属性を変更します。
先ほど書いたmicroposts.jsに追加します。

assets/javascripts/microposts.js
$(document).on('turbolinks:load', function () {
  $('#micropost-tags').tagit({
    fieldName: 'micropost[tag_list]',
    singleField: true,
  });

inputフィールドが<input type="hidden" style="display:none;" value="Ruby,Python" name="micropost[tag_list]">
コントローラのパラメータに:tag_listを追加してください。

app/controllers/microposts_controller.rb
 def micropost_params
      params.require(:micropost).permit(:title, :content, { images: [] }, :tag_list)
 end

編集画面でタグの表示をする

gonを使ってrailsからjavascriptに渡します。
Gemfileに以下を追加かしてください

Gemfile.
gem 'gon'

viewに以下を追加してください。

views/layouts/application.html.slim
    //= include_gon(:init => true) #こっちで上手くいく場合もあります
    = Gon::Base.render_data
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'

投稿に含まれているタグを取得します。

app/controllers/microposts_controller.rb
before_action :set_micropost_tags_to_gon, only: [:edit]

def set_micropost_tags_to_gon
     gon.micropost_tags = @micropost.tag_list
end

Tag-itのcreateTagで追加。
先ほど書いたmicroposts.jsに追加します。

assets/javascripts/microposts.js
$(document).on('turbolinks:load', function() {
  var i, len, ref, results, tag;
  $('#micropost-tags').tagit({
    fieldName: 'micropost[tag_list]',
    singleField: true
  });
  if (gon.micropost_tags != null) {
    ref = gon.micropost_tags;
    results = [];
    for (i = 0, len = ref.length; i < len; i++) {
      tag = ref[i];
      results.push($('#micropost-tags').tagit('createTag', tag));
    }
    return results;
  }
});

これで編集画面で既存タグが表示されると思います。

オートコンプリート

タグリストにあるタグを全て取得します。

app/controllers/microposts_controller.rb
 before_action :set_available_tags_to_gon, only: [:edit]

 def set_available_tags_to_gon
      gon.available_tags = Micropost.tags_on(:tags).pluck(:name)
 end

gonをavailableTagsに渡します。
省略の部分は先ほどと同じです。

assets/javascripts/microposts.js
$(document).on('turbolinks:load', function () {
  var i, len, ref, results, tag;
  $('#micropost-tags').tagit({
    fieldName: 'micropost[tag_list]',
    singleField: true,
    availableTags: gon.available_tags,
  });
省略

これでできると思います。

おわりに

間違いがありましたら編集リクエストまたはコメントお願いします。

参考文献

1
1
0

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
1
1