[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] Implementation of category function
[Rails] Implementation of tutorial function
[Rails] Implementation of like function
[Rails] Implementation of CSV import function
[Rails] Asynchronous implementation of like 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] Implementation of tag function using acts-as-taggable-on and tag input completion function using tag-it
[Ruby on rails] Implementation of like function
[Rails] Implementation of search function using gem's ransack
Implementation of Ruby on Rails login function (Session)
[Rails] Implementation of image enlargement function using lightbox2
Implementation of search function
Implementation of pagination function
Implementation of Ruby on Rails login function (devise edition)
Rails CRUD function implementation ② (edited and detailed this time)
[Rails] Implementation of multi-layer category function using ancestry "Preparation"
[Rails] Implementation of multi-layer category function using ancestry "seed"
Rails implementation of ajax removal
Rails fuzzy search function implementation
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] Implementation of multi-layer category function using ancestry "Editing form"
[Rails] Implementation of automatic address input using jpostal and jp_prefecture
[Rails] Implementation of multi-layer category function using ancestry "Creation form"
Rails sorting function implementation (displayed in order of number of like)
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
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"
Create pagination function with Rails Kaminari
[Rails] [jQuery] Asynchronous like function implementation using remote: true and js.erb
[Rails] Implementation of many-to-many category functions
[Rails] gem ancestry category function implementation
[Rails] Differences and usage of each_with_index and each.with_index
[Ruby on Rails] Comment function implementation
Default implementation of Object.equals () and Object.hashCode ()
[Rails] Comment function implementation procedure memo
Implementation of like function in Java
[Rails] Implementation procedure of the function to tag posts without gem + the function to narrow down and display posts by tags
[Rails] I will explain the implementation procedure of the follow function using form_with.
Introduction of Sudoku answer application "Sudoku automatic answer" (Android version) and its implementation function
[Rails] Addition of Ruby On Rails comment function
Implementation of user authentication function using devise (2)
Building Rails 6 and PostgreSQL environment with Docker
[Swift 5] Implementation of membership registration with Firebase
[Rails withdrawal] Create a simple withdrawal function with rails
[Ruby on Rails] Follow function implementation: Bidirectional
Implementation of user authentication function using devise (1)