【Ruby on Rails】Hướng dẫn làm chức năng sort với jquery-ui sortable

Ruby on Rails JavaScript jQuery

Posted by Yuto Yasunaga at 2020-09-30 01:12:49 +0900
Cài đặt jQuery và jQuery-ui

yarn add popper.js jquery jquery-ui

config/webpack/environment.js
const { environment } = require('@rails/webpacker')

// Add
const webpack = require('webpack')
environment.plugins.append(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default']
  })
)
// Add

module.exports = environment

app/javascript/packs/application.js
require("jquery")
require("jquery-ui/ui/widgets/sortable")
require("jquery-ui/ui/effects/effect-highlight") // Highlight effect


Giả sử có model là Product, và table products tồn tại column "sort" dạng integer

app/models/product.rb
scope :default_order, -> { order("sort") }

config/routes.rb
resources :products do
  member do
    put :sort
  end
end

app/controllers/products_controller.rb
def index
  @products = Product.all.default_order
end

def sort
  product = Product.find(params[:id])
  product.update_column(:sort, params[:sort])
  Product.where.not(id: product.id).default_order.each_with_index do |other_product, index|
    sort = index
    sort += 1 if sort >= product.sort
    other_product.update_column(:sort, sort)
  end
end

app/views/products/index.html.slim
table.table.table-striped
  thead
    tr
      th Sort
      th Product name
      th Product code
  tbody.sortable
    - @products.each do |product|
      tr data-url=sort_product_path(product)
        td= product.sort
        td= product.name
        td= product.code

app/javascript/src/sortable.js
$(document).on("turbolinks:load", function() {
  $(".sortable").sortable({
    update: function(event, ui) {
      $.ajax({
        dataType: "json",
        url: ui.item.data("url"),
        type: "PUT",
        data: {sort: ui.item.index()}
      });
    },
    // Highlight effect
    stop: function(event, ui) {
      ui.item.children('td').effect('highlight', { color: "#00FF00" }, 500)
    }
  });
});

app/javascript/packs/application.js
require("../src/sortable")

Back