[Rails] Implementation of drag and drop function (with effect)

Target

ezgif.com-video-to-gif.gif

Development environment

・ Ruby: 2.5.7 Rails: 5.2.4 ・ Vagrant: 2.2.7 -VirtualBox: 6.1 ・ OS: macOS Catalina

Premise

The following has been implemented.

Slim introductionIntroduction of Bootstrap3Implementation of posting function

Implementation

1. Introduce Gem

Gemfile


#Postscript
gem 'jquery-ui-rails'
gem 'ranked-model'

jquery-ui-rails ➡︎ Make jQuery UI available.

gem 'ranked-model' ➡︎ Make it possible to manage the order of books.

3. Add column

Terminal


$ rails g migration AddRowOrderToBooks row_order:integer

Terminal


$ bundle

schema.rb


create_table "books", force: :cascade do |t|
  t.integer "user_id"
  t.string "title"
  t.text "body"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "row_order"
end

4. Edit the model

Allow ranked-model to be used in Book models.

book.rb


#Postscript
include RankedModel
ranks :row_order

5. Edit controller

** ① Edit ʻindex action` **

books_controller.rb


#Change before
@books = Book.all

#After change
@books = Book.rank(:row_order)

** ② Add row_order_position to the strong parameter. ** **

The column name is row_order, but here it is described as row_order_position for the purpose of using Gem.

books_controller.rb


def book_params
  params.require(:book).permit(:title, :body, :row_order_position)
end

** ③ Add sort action **

books_controller.rb


def sort
  book = Book.find(params[:book_id])
  book.update(book_params)
  render body: nil
end

render body: nil ➡︎ Perform only actions, do not call views.

6. Edit the routing

route.rb


#Change before
resources :books

#After change
resources :books do
  put :sort
end

7. Edit view

slim:books/index.html.slim


/ 「table-Grant a class called "sortable"
table.table.table-bordered.table-sortable
  thead
    tr
      th
        |Contributor
      th
        |title
      th
        |Text
      th

  tbody
    - @books.each do |book|
      /Assign a class to the tr tag and set the data
      tr.item(data = { model_name: book.class.name.underscore, update_url: book_sort_path(book) })
        td
          = link_to book.user  do
            = book.user.name
        td
          = link_to book.title, book_path(book)
        td
          = book.body
        td
          -if book.user == current_user
            = link_to 'Delete', book, method: :delete, data: { confirm: '本当にDeleteしてもよろしいですか?' }, class: 'btn-sm btn-danger'

model_name: book.class.name.underscore ➡︎ "book" corresponds to each block variable.

8. Edit ʻapplication.js`

application.js


//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require jquery
//= require jquery-ui/widgets/sortable //Postscript
//= require jquery-ui/effects/effect-highlight //Postscript
//= require bootstrap-sprockets
//= require_tree .

//= require jquery-ui/widgets/sortable ➡︎ Enable jQuery UI

//= require jquery-ui/effects/effect-highlight ➡︎ Enable drag and drop effects

9. Create / edit JavaScript file

Terminal


$ touch app/assets/javascripts/table_sort.js

table_sort.js


$('.table-sortable').sortable({
  axis: 'y',
  items: '.item',

  //Send order data to controller with Ajax
  update(e, ui) {
    let item = ui.item;
    let item_data = item.data();
    let params = { _method: 'put' };
    params[item_data.model_name] = { row_order_position: item.index() };
    $.ajax({
      type: 'POST',
      url: item_data.update_url,
      dataType: 'json',
      data: params,
    });
  },

  //Adjust drag width to table
  start(e, ui) {
    let cells, tableWidth, widthForEachCell;
    tableWidth = $(this).width();
    cells = ui.item.children('td');
    widthForEachCell = tableWidth / cells.length + 'px';
    return cells.css('width', widthForEachCell);
  },

  //Add effect
  stop(e, ui) {
    return ui.item.children('td').effect('highlight');
  },
});

10. Change the cursor design

application.scss


//Postscript
.table-sortable {
  tr.item {
    cursor: row-resize;
  }
}

Recommended Posts

[Rails] Implementation of drag and drop function (with effect)
[Rails 6] Implementation of search function
[Rails] Implementation of category function
Login function implementation with rails
[Rails] Implementation of tutorial function
[Rails] Implementation of like function
[Rails] Implementation of CSV import function
[Rails] Implementation of image preview function
[Rails] About implementation of like function
[Rails] Implementation of user withdrawal function
[Rails] Implementation of CSV export function
Drag and drop files with JavaFX
Rails Addition of easy and easy login function
[Rails] Implementation of coupon function (with automatic deletion function using batch processing)
Rails [For beginners] Implementation of comment function
[Rails 6] Implementation of SNS (Twitter) sharing function
[Vue.js] Implementation of menu function Implementation version rails6
[Rails] Implementation of tag function using acts-as-taggable-on and tag input completion function using tag-it
[Ruby on rails] Implementation of like function
[Vue.js] Implementation of menu function Vue.js introduction rails6
Implementation of Ruby on Rails login function (Session)
[Rails 6] Implementation of inquiry function using Action Mailer
[Rails] Implementation of image enlargement function using lightbox2
[Rails] Implementation of retweet function in SNS application
Implementation of search function
Rails search function implementation
Implementation of pagination function
Ruby on Rails <2021> Implementation of simple login function (form_with)
Implementation of Ruby on Rails login function (devise edition)
Rails CRUD function implementation ② (edited and detailed this time)
[Ruby on Rails] Implementation of tagging function/tag filtering function
[Rails] Implementation of multi-layer category function using ancestry "Preparation"
[Rails] Implementation of multi-layer category function using ancestry "seed"
[Rails] Implementation of SNS authentication (Twitter, Facebook, Google) function
Rails fuzzy search function implementation
Introduced graph function with rails
Implementation of sequential search function
Implementation of like function (Ajax)
Implementation of image preview function
Implementation of XLPagerTabStrip with TabBarController
Implementation of category pull-down function
[Rails 6] Pagination function implementation (kaminari)
[Rails] Implementation of multi-layer category function using ancestry "Editing form"
[Rails] Implementation of automatic address input using jpostal and jp_prefecture
[Swift] You can concatenate cells with Drag & Drop of UITableView
[Rails] Implementation of multi-layer category function using ancestry "Creation form"
Rails sorting function implementation (displayed in order of number of like)
[Rails] Implementation of tagging function using intermediate table (without Gem)
Implement login function simply with name and password in Rails (3)
Building a bulletin board API with authentication authorization with Rails 6 Validation and test implementation of # 4 post
Build a bulletin board API with authentication and authorization with Rails # 18 ・ Implementation of final user controller
[Rails] Implementation of new registration function in wizard format using devise
[Rails] Implementation of user logic deletion
Comparison of WEB application development with Rails and Java Servlet + JSP
[Rails] Implementation of multi-layer category function using ancestry "I tried to make a window with Bootstrap 3"
Implemented mail sending function with rails
Kaminari --Added pagination function of Rails
Create pagination function with Rails Kaminari
[Rails] [jQuery] Asynchronous like function implementation using remote: true and js.erb
[Rails 6] Implementation of new registration function by SNS authentication (Facebook, Google)
[Rails] Implementation of many-to-many category functions