[RUBY] Creating an autocomplete feature using acts-as-taggable-on and Tagit.js

Complete system

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

Development environment

ubuntu(WSL)
Rails 6.0.2
Ruby 2.5.1

Advance preparation

--Creating a tag function --Creating a posting function (CRUD) Please refer to here for creating the tag function.

Introduction of Tagit

Execute the following command and place it in vendor / assets. If you don't have vendor / assets, create one yourself.

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

Since Jqury is used, please add jqury-ui-rails to the Gemfile.

Gemfile.


gem 'ransack'
gem 'acts-as-taggable-on', '~> 6.0'
gem 'jquery-ui-rails' #add to

Add the following to ʻapplication.js and ʻapplication.scss to load Tagit and JquryUi. I will put them all for the time being.

application.js


//= require jquery #add to
//= require rails-ujs #add to
//= require popper
//= require turbolinks #add to
//= require_tree . #add to
//= require bootstrap
//= require activestorage
//= require jquery-ui/widgets/autocomplete #add to
//= require tag-it #add to

application.scss


/*
 *= require_tree . #add to
 *= require jquery.tagit #add to
 *= require tagit.ui-zendesk #add to
 *= require_self #add to
*/

Make a text box. Add an arbitrary id in the form_for block. If you add id to f.text_field, two text fields will be created, so add id to .form-group.

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
    //Tag input / save display
    //= f.text_field :tag_list, value: @micropost.tag_list.join(","), class: "form-control"

Call tagit

assets/javascripts/microposts.js


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

Save tag

Currently, the name attribute is the same, so enable singleField and change the name attribute. Add it to the microposts.js I wrote earlier.

assets/javascripts/microposts.js


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

The input field is <input type =" hidden "style =" display: none; "value =" Ruby, Python "name =" micropost [tag_list] "> Add : tag_list to the controller parameters.

app/controllers/microposts_controller.rb


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

Display tags on the edit screen

Pass from rails to javascript using gon. Add the following to the Gemfile

Gemfile.


gem 'gon'

Add the following to the view.

views/layouts/application.html.slim


    //= include_gon(:init => true) #Sometimes it works here
    = Gon::Base.render_data
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'

Gets the tags contained in the post.

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

Added by createTag of Tag-it. Add it to the microposts.js I wrote earlier.

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;
  }
});

You should now see the existing tags on the edit screen.

Auto Complete

Get all the tags in the tag list.

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

Pass gon to ʻavailableTags`. The omitted part is the same as before.

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,
  });
abridgement

I think you can do this.

in conclusion

If you make a mistake, please make an edit request or comment.

References

-Create tagging function with acts-as-taggable-on and jQUery Tag-it

Recommended Posts

Creating an autocomplete feature using acts-as-taggable-on and Tagit.js
Creating an SSL certificate using Let's Encrypt and setting up Nginx on Ubuntu 20
[Java] Creating an Excel file using Apache POI
A memorandum for creating an extended logger using org.slf4j.Logger