jQuery UI

jQueryUI Sortableで並び順を保存する〜Backbone.js、Rails5.1

投稿日:2018年4月8日 更新日:

状況

Backbone.js(Marionette.js)+Rails5.1のアプリで、jQueryUIのsortableでリストの順番を並べ替えたら、その順番を保存する.

RailsCastのやつをやろうとしたら予想外に苦労したのでメモ.

jQuery UI Sortable

Marionette.jsのCollectionViewでリストを表示させている.

まず、子アイテムにdata-idを設定しておく.これは後でsortable(‘toArray’)を使うのに必要.

そして、親リストでsortableを実行する.
onRenderで実行すればOK.
サーバーとの通信は、Backbone.Collectionを通じてにしたいので、まず、collectionを書き換える.
sortable(‘toArray’)は、子アイテムの順番通りに指定したattributeの配列を返す.
デフォルトはidだけど、optionでattributeを指定できる.

Backbone.Collection

次に、collectionの方で通信するメソッドsortSaveを作る.
comparatorを設定して、positionをキーに並べ替えするよう設定しておく.

Rails routes

そして、config/routesでtasks/sortへのpostを登録する.
基本的に、アクションは7つに留めるべき(index、show、new、create、edit、update、destroy)だけど、それだとupdateをたくさん発行することになってしまい、それより1回の通信で更新できた方がいいので、RailsCastの例に従った.

Rails controller

ActiveRecordのupdateをつかう

最後に、Railsのコントローラーにsortメソッドを作る.
StrongParametersでpermitしないといけない.
updateのところが一番はまった.
クラスメソッドのupdateは、ids, attributesを与える.
順番の変更には、割り込みを許したくないので、transactionでくくる.
最後に、全レコードのJSONを返して、更新した後のpositionのデータを返して、Backbone.Collectionをリセットする.

できた!

生SQLをなげる

やっぱりいくつもSQLを実行するのは、その間データベースを専有するのでよろしくない.
なるべく1つのSQL文で実行したい.
調べるとSQLiteなら次のような文を実行すればよいらしい.

そこで、このSQL文を作ってexcuteする.
生SQLをなげるときには、SQLインジェクションに気をつける.

また、全データを返すのも脳がないので、帰ってきたidをBackbone.Collectionの方でうまく処理する.

これが、、、

こうなった!

Rails Model

最後に、新規作成したデータにはpositionがない.
そこで、positionは最終positionの次に付け加えることにする.
RailsCastでは、acts_as_listを使っていたけど、あとで適当にカスタマイズしたいので、メソッドを書いた.

Backboneの方では、collection.createの際にwait: trueオプションを渡さないと、サーバーで保存されたidやpositionがBackbone.collectionに渡されず、undefinedになってしまうので注意.

応用1:まとめて削除

応用でまとめて削除の際も、deleteリクエストがたくさん発行されていたので一個のリクエストにした.

Backbone.Collection

@collection.clear()というメソッドを実装する.

Backbone.Collectionに実装する.

Rails routes

config/routes.rbでtasks/clearを登録

Rails controller

clearメソッドを実装.
まとめて削除した後は、positionが穴開きになる.
このまま、データが新規追加されると、positionが変な並びになってしまう.
そこで、positionを再振りする必要がある.
最初は、Modelでafter_destroyでやってたが、複数削除すると削除ごとに再振りをするのは無駄なので一括削除のときはまとめて再振りとした.
この処理には割り込まれたくないのでtransactionで囲む.

応用2:カンバン風

さらに応用してカンバン風のUIをつくってみた.
移動先のカテゴリに変更した上で、順番を並び替える.

Rails Model

カテゴリ用のカラムを追加する.situation_idというカラムを追加して、別途、Situationというモデルを作った.

Rails Controller

ストロングパラメーターの設定を変更して、situation_idもやり取りできるようにする.

Backbone View

jQueryUIのconnectWithをつかう.
リストにドロップすると、receiveメソッドが発火する.
ドロップされたアイテムは、ui.item
データの並びは、sortable(‘toArray’)で全部の並び順を取得する.
そして、update_situationという新しいメソッドを書く.
データの通信は全部Collectionを通して行う.

ここで注意するのが、もとのリストとドロップ先のリストでupdateイベントもおきる.
リスト間のドラッグ・アンド・ドロップのときはupdateメソッドを使わないようにした.

Backbone Collection

ajax通信.
situation_idを新しいドロップ先のidにしたうえで、全データの並び順をアップデートする.

Rails routes

/:idとかが入るのはcollectionではなく、member

Rails Controller

update_situationのメソッドを書く.

-jQuery UI
-, , ,

執筆者:

関連記事

no image

jQuery uiで作った将棋をHerokuにアップ

mysterious-depths-3658.herokuapp.com/ ここのひな形を利用させてもらいました docs.komagata.org/4571 使い方は、 [crayon-5ba5b1 …

FullCalendarのagendaViewでselectの場所がずれる問題

  By: Ben Piddington 前回 Rails3.2でGoogle Calendarライクなカレンダーを使う〜fullcalendar-rails   gemは最新の1 …

Backbone.jsからjQuery UIのDialogを使う例

Backbone.js楽しくなってきた 部品ごとのクラスをつくって、それに飾りとイベントをつけて、あとは上位部品から呼び出してくっつけるだけ jQuery UIのダイアログの場合は、公式のサンプルだと …

Rails3.2でフォームの順番をjQuery UI sortableで並べ替えてSubmit~acts_as_list

jQuery UI Buttonsetの選択状態を変えたり、色を変えたり

  目次1 jQuery UI Buttonsの設定(Radioボタン)2 チェック状態を変えるには3 ボタンの色を変えるには4 チェックした要素のvalueを取得するには jQuery U …