SortableJSを使ってデータの並べ替え&保存
あるシステムを拝見した際にtableタグ内に並んでいる項目をドラッグ&ドロップで並べ替えする機能があった。ブラウザからソースを確認するとjQuery UIのSortable機能を使っているっぽい。ただ、jQuery UIを利用しなくてもSortable.jsは個別で利用できるようなので以下に使い方のメモ。
やりたいこと
tableタグ内の項目をドラッグ&ドロップで入れ替えて「変更」等のボタンをクリックすると並び順がMySQLに保存され、保存された並び順で表示される機能を実装したい。
サンプル
https://taitan916.info/sample/sortable/
Sortable.js
以下からダウンロードする。
https://github.com/SortableJS/Sortable
もしくはCDNで以下のように呼び出しても良い。
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
ソース
<?php //MySQL接続 $mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname); $mysqli->set_charset('utf8'); //並び順変更処理 if( $_POST['order'] ){ $data = json_decode($_POST['order'], true); foreach( $data as $key => $val ){ $sql = ' UPDATE sort_table SET `order` = "' . $mysqli->real_escape_string($val) . '" WHERE id = "' . $mysqli->real_escape_string($key) . '" '; $row = $mysqli->query($sql); } //ページリロード防止用 header('Location:./'); exit(); } $sql = ' SELECT * FROM sort_table ORDER BY `order` ASC '; $row = $mysqli->query($sql); while ($rs = $row->fetch_array(MYSQLI_ASSOC)) { $data[$rs['id']] = $rs; } ?> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Sortable サンプル</title> </head> <body> <link href="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"> <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-3.3.1.slim.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script> <script src="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script> <script type="text/javascript" src="//code.jquery.com/jquery-3.5.1.js"></script> <style> td{ cursor: move; } </style> <form action="./" method="post" id="order_form"> <table> <tbody id="sort-table"> <?php foreach( $data as $key => $val ){ ?> <tr class="id_<?php echo $val['id'];?>"> <td><?php echo $val['order'];?></td> <td><?php echo $val['name'];?></td> </tr> <?php } ?> </tbody> </table> <input type="hidden" name="order" class="order" value=""> <input type="submit" class="btn btn-success" value="順番を変更" onClick="return sortCheck();"> </form> <script> //Sortable let table = document.getElementById('sort-table'); Sortable.create(table); //並び順の処理 function sortCheck(){ let data = $('#sort-table > tr'); let query = new Object(); for( let i = 0; i < data.length; i++ ){ //オブジェクトにkey = id / val = 並び順を格納 query[data[i].attributes.class.value.replace('id_', '')] = i + 1; } //データをJSON化してinput="hidden"に格納 $('.order').val(JSON.stringify(query)); //フォーム送信 $('#order_form').submit(); //IEの二重送信防止用 return false; } </script> </body> </html>
query[data[i].attributes.class.value.replace('id_', '')]のところがちょっと気持ち悪いが、綺麗にまとめられなかった。
所感
今まで並び順変更機能を実装する場合、テキストボックス(input type="text")に数値を入力する形で実装していた。そうすると同じ数値を入力していた場合や、数値が入っていない場合はどうするかとか考える必要があったが、Sortable.jsを使うことでその辺りの作業は必要なくなりそう。
とはいえページングありのページだとテキストボックス形式を使うしかなさそう。あと、Sortable.jsの方がUI的に親切に思えるが、こちら側としてはJSを沢山使うとブラウザによって(特にIEは)挙動が異なったりするので、ブラウザ毎のチェックや不具合が発生した際の修正の手間を考えると、どちらの形式でいくのか悩ましいところ。
関連記事
-
エリア→都道府県→路線→駅名を連携する絞り込みセレクトメニューの設置方法
エリア→都道府県→路線→駅名のドリルダウン検索をプルダウン形式で設置したい。以前 ...
-
AjaxFileUploadで処理は実行できてもエラーが返る
AjaxFileUploadでPHPに通信し、サーバー側のPHPで処理は正常に実 ...
-
オリジナルのjQueryプラグインを作成する方法
オリジナルのjQueryプラグインを作ってみたかった。というのも大抵のものはググ ...
-
jQueryにて特定のIDが存在するかチェックし分岐処理する方法
jQueryにて特定のIDが存在するかチェックし分岐処理したいというケースがあっ ...
-
jQueryでAjax通信したデータをPHPで受け取り、zip化したファイルをダウンロードさせる方法
jQueryのAjaxで何らかのデータをPHP側に送信し、PHP側で当該データを ...