Stimulusの習作: ドラッグ・アンド・ドロップ(SortableJS版)

外観

前回前々回とHTML ドラッグ&ドロップ APIを直接用いましたが、今回はSortableJSライブラリを用いてリスト項目の入れ替え操作を行います。

環境

macOS 10.15.4
Ruby 2.6.5
Rails 6.0.2.2
Yarn 1.22.4
Node 13.12.0
stimulus@1.1.1
sortablejs@1.10.2

リポジトリ

参照

SortableJS

ライブラリの追加

yarnでSortableJSを追加します。

yarn add sortablejs

HTML

下記の内容で操作対象のリストを生成します。

data-controllerで、項目を操作するStimulusのコントローラと接続する。
data-actionで、送信エラーイベントをコントローラに渡す。
data-idで、SortableJSが項目を識別可能にする。

app/views/books/index.html.erb

<% controller = "drag-item" %>
<% action = 'ajax:error@document->drag-item#onPostError' %>
<%= tag.ul data: { controller: controller, action: action } do %>
 <% @books.each do |book| %>
   <%= tag.li data: { id: book.id } do %>
     <%= book.title %>
   <% end %>
 <% end %>
<% end %>

コントローラ

Sortableをimportする。

Sortableの生成
項目移動のアニメーション速度を150msで設定する。
送信エラー時に呼び出すメソッドを設定する。

app/javascript/controllers/drag_item_controller.js

import Sortable from 'sortablejs'
import Rails from '@rails/ujs'
import { Controller } from 'stimulus'

export default class extends Controller {

 initialize() {
   this.sortable = Sortable.create(this.element, {
     animation: 150,
     onEnd: this.dragend.bind(this),
   })
 }

 dragend(event) {
   const ids = this.sortable.toArray()
   const form = document.getElementById('row-order-form')
   document.getElementById('row_order').value = ids
   Rails.fire(form, 'submit')
 }

 onPostError(event) {
   Turbolinks.visit('/books', 'replace')
 }
}

機能としては以上です。

縦移動に限定したいが…

Limit dragging to axis 165

ライブラリ作成者の方針として、項目移動の方向を限定できないようです。

この記事が気に入ったらサポートをしてみませんか?