jQuery UI Sortable は並び順を保存しなければ意味がない

jQuery UI はとても便利なライブラリなので使わない手はありません。

ドラッグアンドドロップで要素の並び替えができる Sortable

サンプル1

使い方

必要なJavaScriptファイル

jQuery
jQuery UI

実装

> コーディング


<ul class="sortable">
	
<li>Item 1</li>

	
<li>Item 2</li>

	
<li>Item 3</li>

	
<li>Item 4</li>

	
<li>Item 5</li>

</ul>

> JavaScript

$(function() {
	$( ".sortable" ).sortable();
});

たったこれだけで、ドラッグアンドドロップによる要素の並び替えができるようになります。
オプションやメソッドを設定することでいろいろできます。

リッチなUIって感じですね!

「で?」

ていうか、

「並び替えて、それで??」

ということで、結局は要素を並び替えられるだけではなんの役にも立ちません。

並び順を保存しなければ意味なし!

ということで、保存先としてはクッキーかデータベースの2択になるでしょう。
それぞれについてみていきます。

並び順をクッキーに保存

いわゆる iGoogle や WordPress の管理画面のように、ユーザ選好で要素の配置を決められる UI の実現です。

必要なJavaScriptファイル

jQuery
jQuery UI
jquery.cookie.js

実装

> コーディング


<ul class="sortable">
    
<li id="1">Item 1</li>

    
<li id="2">Item 2</li>

    
<li id="3">Item 3</li>

    
<li id="4">Item 4</li>

    
<li id="5">Item 5</li>

</ul>

> JavaScript

$(function() {
	$(".sortable").sortable();
	$(".sortable").disableSelection();
	$(".sortable").sortable({
		update: function(ev, ui) {
			var updateArray =  $(".sortable").sortable("toArray").join(",");
			$.cookie("sortable", updateArray, {expires: 30});
		}       
	});
	if($.cookie("sortable")) {
		var cookieValue = $.cookie("sortable").split(",").reverse();
		$.each(
			cookieValue,
			function(index, value) {$('#'+value).prependTo(".sortable");}
		);
	}
});

【解説】

sortable の toArray メソッドを指定することで、要素の id をシリアライズして配列として取得できます。
並び替えをしたら並び順をクッキーに保存。再読み込み時にはクッキーを参照して要素を並び替える処理をしています。

サンプル2(並び替えたらリロードしてみてください)

並び順をデータベースに保存

必要なJavaScriptファイル

jQuery
jQuery UI

実装

> index.php

<!DOCTYPE HTML>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>sortable sample</title>
	<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F3.3.1%2Fjquery.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
	<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjqueryui%2F1.12.1%2Fjquery-ui.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
</head>
<body>
	
<form action="" method="post">
		
<ul class="sortable">
		    
<li id="1">Item 1</li>

		    
<li id="2">Item 2</li>

		    
<li id="3">Item 3</li>

		    
<li id="4">Item 4</li>

		    
<li id="5">Item 5</li>

		</ul>

		<input type="hidden" id="result" name="result" />
		<button id="submit">submit</button>
	</form>


	<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%09%24(function()%20%7B%0A%09%20%20%20%20%24(%22.sortable%22).sortable()%3B%0A%09%20%20%20%20%24(%22.sortable%22).disableSelection()%3B%0A%09%20%20%20%20%24(%22%23submit%22).click(function()%20%7B%0A%09%20%20%20%20%20%20%20%20var%20result%20%3D%20%24(%22.sortable%22).sortable(%22toArray%22)%3B%0A%09%20%20%20%20%20%20%20%20%24(%22%23result%22).val(result)%3B%0A%09%20%20%20%20%20%20%20%20%24(%22form%22).submit()%3B%0A%09%20%20%20%20%7D)%3B%0A%09%7D)%3B%0A%09%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
	
	<?php
	// POST値
	$result = $_POST['result'];
	var_dump( $result );
	
	echo '
';
	
	// 配列化
	$result_arr = explode(',', $result);
	var_dump($result_arr);
	
	echo '
';
	
	// シリアル化(これをDBに保存する)
	$serialize = serialize($result_arr);
	var_dump($serialize);
	
	echo '
';
	
	// シリアル化を戻す
	$result_arr = unserialize($serialize);
	var_dump($result_arr)
	?>
	
</body>
</html>

【解説】

サブミットボタンが押下されたら、hiddenのinput要素に、並び順がカンマ区切りで結合された文字列がセットされて、サブミットされます。こんな感じの文字列→ “1,2,3,4,5”

あとは、PHP側でデータを受け取ってデータベースに保存すればOKですね。
カンマ区切りで分割して配列にして、serializeして保存しておくのがおすすめ。

Comments

  • info intra より:

    はじめまして。
    sortable後に並び順をDBに保存したいのですが、takayoshi 様のようにのところで、配列resultの結果が【$、a、a、a】と、idで指定した変数名がそのまま表示されてしまいます。
    もし可能であれば、githubにupしておりましたサンプルを参考にさせていただきたいのですが、こちらのサイトに掲載することは可能でしょか。
    どうぞよろしくお願いいたします!!

    • hijiri より:

      ちょっと探してみます。

      • info intra より:

        お忙しいところ、ありがとうございます。不躾なお願いにご対応いただき、感謝しております。
        サイトや書籍を参考に勉強しておりますが、実装できず半年経ってしまいました。
        hijiri様の上記の例文のようにに一行ごとにidが振られていないので、どう書いていいか分からずにいます。
        どうか、よろしくお願いいたします。

        • info intra より:

          hijiriさま
          こんにちは。
          あれから色々試して、なんとか並び順をDBに保存することができました!!
          お手数おかけして申し訳ありません。
          どうもありがとうございました。

          • hijiri より:

            よかったです
            事後となりましたが、サンプルを記事内に貼りましたのでご参考にどうぞ

          • info intra より:

            hijiriさま
            ありがとうございます!!
            もちろん、参考にさせていただきます。すごく勉強になります。
            本当にありがとうございました。

  • […] jQuery UI Sortable は並び順を保存しなければ意味がない | hijiriworld Web […]

  • ezjo より:

    こんにちは。わかりやすい解説ありがとうございます!
    ただこちらにあるクッキーに保存するサンプル2ですがリロードすると元に戻ってしまいます。ChromeとIEで確認しました。
    何か原因などわかりますでしょうか?
    もしおわかりになる場合、教えて頂ければと思います。

  • Aussie0907 より:

    IE8で実行すると 、「オブジェクトでサポートされていないプロパティまたはメソッドです(line2)(jquery-1.8.0.min.js)」とエラーが発生してしまいます。ミニマム化されたJSの為、実際何がエラーなのかわからなく困っています。だれかご教授頂けますでしょうか。よろしくお願いします。

  • takayoshi より:

    はじめまして。
    参考にさせて頂いています!
    大変お手数なのですが、データベースに保存する手順をご享受頂けないでしょうか…。
    完全にハマってますm(_ _)m

    • hijiri より:

      返信遅くなりました。
      POSTされるのは “1,2,3,4,5” という値ですので、例えば、PHP側でシリアライズして serialize($result) 配列としてデータベースに保存。テンプレートの出力前に unserialize した変数をもとに並び順を再現します。

      • takayoshi より:

        お忙しい中、お返事を頂きありがとうございました。
        しかし、やはり出来ませんでした…。
        色々やってみたのですが(^^;
        きっと僕の知識が足りてないのが原因だと思います。
        今後も参考にさせて頂き、勉強しようと思います。
        ありがとうございますm(_ _)m

        • hijiri より:

          PHP側でデータは受け取れるはずですなので、データベース保存処理はがんばってみてください!

          • takayoshi より:

            ありがとうございます (> <)
            頑張ります!!

          • takayoshi より:

            何度もすみませんm(_ _)m
            お忙しいとは存じておりますが、お力を貸してくださいませ。

            お手すきでない場合は完全に無視してください。
            自分勝手な事も理解した上での質問ですので…
            ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
            実は$resultをprintしてみたところ、配列が格納されていない事が分かりました。
            データベースからの呼び出しがおかしいのかと思い、ご意見を賜りたかったのです。
            ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
            echo ”;$my_Row = mysql_query(“SELECT * FROM tablesort”,$my_Con);if (!$my_Row){  die(mysql_error());}while($row = mysql_fetch_array($my_Row)){$files = $row[“file”];$no = $row[“no”];header(“Content-type: image/jpg”);echo <<< EOFEOF;}echo ”;echo ”;
            ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
            すごく暇な時にでも見て頂ければ光栄ですm(_ _)m

          • hijiriworld より:

            > takayoshi さん
            POSTされる値は配列ではなく「カンマ区切りの文字列」です。 “1,2,3,4,5”
            配列にしたいのであれば、PHP側でカンマ区切りで分割します。

            一連のサンプルをアップしておきます。

          • takayoshi より:

            感激です(><)
            お忙しい中ありがとうございます!!!
            まさか、見ず知らずの僕にここまでしてくれるなんて…。

            実装完了したら報告させて頂きます!
            m(_ _)m

          • Takayoshi より:

            お久しぶりです!
            以前何度か質問をさせて頂きました「岩嵜」といいます。

            やっと出来ました!!
            本当にありがとうございます。

            何故だか分りませんが、画像を並べ替えようとしていたのですが、テキストを並べ替えるようにしたらちゃんと出来ました★
            画像を呼び出してに入れると変数が入らなかったのです。
            これに気付くのに今までかかっちゃいました(^^;
            将来的には画像でも出来るように頑張ります!

            もぅ感謝の言葉しかみあたりませんが、本当に助かりました!
            ありがとうございます!!
            m(_ _)m

          • hijiriworld より:

            > takayoshi さん
            うまくいったようで良かったです^^

  • sukobuto.com より:

    はじめまして。
    ちょうど探していた内容で、とても参考になりました!ありがとうございます。

    ところで、どうやら jQuery UI が読み込まれていないようで、ソートができなくなっていますよ。。。

hijiri へ返信する コメントをキャンセル