LoginSignup
4
1

Stimulusを使ってドラッグアンドドロップ機能を実装する

Posted at

はじめに

以下の記事を参考に、Stimulusを使ってドラッグアンドドロップでの並び替え機能実装を学びました。
https://maful.web.id/posts/build-drag-and-drop-with-rails-hotwire/

その際詰まったり、理解が難しかったことをまとめておきます。

並び替え機能実装の要点

まず、並び替え機能を実現するには(Rails7以前からも存在していた)ranked-modelというgemが必要です。

ranked-modelとは

並び順を持つモデルインスタンスを作る際に必要な機能を提供してくれるgemです。

使い方

必要なカラムをモデルに追加します。

ターミナル
rails g migration AddRowOrderToDucks row_order:integer
rails db:migrate

以下のようにモデルにincludeして使います。並び順に必要なカラムも指定します。

モデルクラス
class Duck < ActiveRecord::Base

  include RankedModel
  ranks :row_order

end

並び順の変更は以下のように行います。

@duck.update row_order_position: 0

非同期で並び替えたい時は、以下のようなajaxリクエストを期待しています。

$.ajax({
  type: 'PUT',
  url: '/ducks',
  dataType: 'json',
  data: { duck: { row_order_position: 0 } },  // or whatever your new position is
});

このようなリクエストを、Stimulusから送る形にすれば良いということです。

@rails/request.jsとは

Ruby on Rails 7で導入されたJavaScriptライブラリの一つで、AJAXリクエストを簡単に行うための機能を提供します。このライブラリは、Railsアプリケーションで必要とされるヘッダー(例えば、X-CSRF-Token)をデフォルトで送信するロジックをカプセル化しています。これにより、JavaScriptでのAJAXリクエストの作成をシンプルにできます。

stimulusのコントローラでは以下のようにリクエストを書いています。

sortable_controller.js
  onEnd(evt) {
    const body = { row_order_position: evt.newIndex }
    patch(evt.item.dataset.sortableUrl, {
      body: JSON.stringify(body),
      responseKind: "turbo-stream",
    })
  }

ここにあるpatch関数が、request.jsで定義されているajaxリクエストのショートハンドです。
レスポンスのデータ形式をturbo-streamで指定できるのが嬉しいですね。

sortablejsとは

ドラッグアンドドロップで要素の順序を変更できる機能を提供するJavaScriptライブラリです。このライブラリは、要素のドラッグアンドドロップ操作に関連する様々なイベントを発火させます。

その中のonEndイベントは、要素のドラッグ操作が終了した時に発火します。

onEnd(evt)関数はこのonEndイベントのハンドラーで、evtはイベントに関連する情報を含むオブジェクトです。このオブジェクトには、ドラッグされた要素、新しいインデックス(evt.newIndex)、元のインデックス、その他のドラッグアンドドロップ操作に関連する情報が含まれています。

このイベントハンドラーは、ドラッグアンドドロップ操作が完了した後にサーバー側にデータを送信するために@rails/request.jsのpatchメソッドを使用しています。これにより、サーバー側のデータがクライアント側の変更に合わせて更新されます。

終わりに

Ajaxを使ってできることについては全てHotWireに置き換えることで、コードを書く量やわかりやすさを向上させることができると感じる良い例でした。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1