勉強したことのメモ

webプログラマが勉強したことのメモ。

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は)挙動が異なったりするので、ブラウザ毎のチェックや不具合が発生した際の修正の手間を考えると、どちらの形式でいくのか悩ましいところ。

 - PHP, jQuery, MySQL, JavaScript

  関連記事

体重管理をPHPで

体重とBMIを管理する画面をPHPで作ってみようと思った。 ソースは下記の通り。 ...

jQueryプラグインの作成

面白そうだったのでメモ。 ■参考サイト http://www.entacl.in ...

エックスサーバーでMySQLのサイズに注意

エックスサーバーで自動更新のログをMySQLに保存するようなシステムを動かしてい ...

特定のサイトからのリクエストのみ受け付けて処理する方法

指定したサイトからのリクエストのみ受け付けて処理したいという状況があった。その他 ...

javascriptで月末日を取得

以前、PHPで月末日を取得したけれども javascriptで月末日を扱いたいケ ...

日付と時間のピッカー

ここだとbootstrap使用だけど、他に良さそうなものがあったのでメモ。 ■参 ...

jQueryでコンテンツのスライド

jQueryもしくはJavaScriptでリンクを押すと 右から左にコンテンツを ...

GoogleスプレッドシートとPHPの連携

GoogleスプレッドシートとPHPプログラムを連携させたいという案件をたまに見 ...

画像アップロード前の時点で画像が選択されているか確認

やりたかった事は、フォーム内で画像をアップロードする際、 ちゃんと画像がローカル ...

要素の点滅

やりたかった事はaタグ内で囲まれている部分を点滅。 <blink>だ ...