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は)挙動が異なったりするので、ブラウザ毎のチェックや不具合が発生した際の修正の手間を考えると、どちらの形式でいくのか悩ましいところ。
関連記事
-
-
jQueryで電話番号チェック
やりたかったことはjavascriptかjQueryで 電話番号のバリデート。 ...
-
-
jQueryのloadメソッドでファイル(ページ)を呼び出す
サイト内でヘッダーやフッター等共通のパーツはそれぞれ別ファイルに分けてPHPのi ...
-
-
jQselectableでセレクトボックスをリッチにする
入力フォームみたいなもので元々はテキストボックス内に 都道府県を入れてもらうとい ...
-
-
jQueryでUNIXタイムスタンプの取得
jQueryでUNIXタイムスタンプを取得したい場合、 $.now()だけで取得 ...
-
-
「input type="number"」のテキストボックスを桁数制限且つ半角数値のみ入力可にする方法
「input type="number"」のテキストボックスに対して「2桁まで」 ...