jQuery UI Soatableでソートしたテーブルの並びを保存する方法

jQuery UI Soatableでソートしたテーブルの並びを保存する方法

Posted at April 16,2013 12:03 AM
Tag:[Cookie, jQueryUI, Sortable]

jQuery UI Soatableでソートしたテーブルの並びを保存する方法を紹介します。

jQuery UI

先日「jQuery UIを使ってテーブルをドラッグ&ドロップでソートできるようにする」をエントリーしましたが、実際には並び替えた順序を保持して使いたいケースも少なくないと思います。

ネットで検索するとjQuery UI Soatableの解説はヒットしますが、cookieに保存するまでの記事はみつかりませんでした。

ということで、ここではcookieを利用して並びを保存する方法を紹介します。

1.サンプル

まず、cookieで並び順を保存するテーブルのサンプルを示します。

サンプル
サンプル

テーブルを並び替えたあと、リロードすれば並び順が保持されていることが分かります。

2.解説

サンプルのコード(抜粋)は次のとおりです。赤色部分が「jQuery UIを使ってテーブルをドラッグ&ドロップでソートできるようにする」からの追加箇所になります。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script src="jquery.cookie.js"></script>
<script>
$(function(){
    $('tbody').sortable({
        stop: function( event, ui ) {
            var id = $(this).parent().attr('id');
            var i = 0;
            var cookie = new Array;
            $('#' + id +' tbody tr').each(function(){
                var number = $(this).attr('id');
                cookie[i] = number + ":" + i;
                i++;
            });
            $.cookie(id, cookie.join(','));
        }
    });
    $('tbody').disableSelection();
    var table_name = 'foo';
    var index_cookie = $.cookie(table_name);
    if (index_cookie) {
        var index_hash = new Array();
        $('#' + table_name + ' tbody tr').each(function(){
            var html = $(this).html();
            var number = $(this).attr('id');
            index_hash[number] = html;
        });
        var list = index_cookie.split(',');
        var i = 0;
        $('#' + table_name + ' tbody tr').each(function(){
            var val = (list[i].split(':'))[0];
            $(this).html(index_hash[val]);
            $(this).attr('id', val);
            i++;
        });
    }
});
</script>
<table id="foo">
  <thead>
    <tr>
      <th>Name</th><th>Salary</th>
    </tr>
  </thead>
  <tbody>
    <tr id="0"><td>Bloggs, Fred</td><td>$12000.00</td></tr>
    <tr id="1"><td>Turvey, Kevin</td><td>$191200.00</td></tr>
    <tr id="2"><td>Mbogo, Arnold</td><td>$32010.12</td></tr>
    <tr id="3"><td>Shakespeare, Bill</td><td>$122000.00</td></tr>
    <tr id="4"><td>Shakespeare, Hamnet</td><td>$9000</td></tr>
    <tr id="5"><td>Fitz, Marvin</td><td>$3300</td></tr>
  </tbody>
</table>

このサンプルではjQuery Cookieを使用します。詳細は「jQueryでcookieを簡単に使える「jQuery Cookie」のまとめ」を参考にしてください。

またHTMLで追加したid属性値は、数字から開始するのはたしか禁止的ですが、記事を書く時間がないのと、処理を分かりやすくするためにこのようにしています。

サンプルプログラムですが、まず、stopイベントでcookieに保存する処理から解説します。

        stop: function( event, ui ) {
            var id = $(this).parent().attr('id');
            var i = 0;
            var cookie = new Array;
            $('#' + id +' tbody tr').each(function(){
                var number = $(this).attr('id');
                cookie[i] = number + ":" + i;
                i++;
            });
            $.cookie(id, cookie.join(','));
        }

stopイベントで、ソートが完了した要素の親要素、つまりtable要素のid属性を取得します(cookieのキーにします)。

            var id = $(this).parent().attr('id');

そして並び替えたあとの、tr要素のid属性値を配列に保存します。

            $('#' + id +' tbody tr').each(function(){
                var number = $(this).attr('id');
                cookie[i] = number + ":" + i;
                i++;
            });

保存した配列をカンマ区切りの文字列にしてcookieに保存します。

            $.cookie(id, cookie.join(','));

続いてcookieを読み出して並び替える処理です。これはページ読み込み時に実行される処理です。

    var table_name = 'foo';
    var index_cookie = $.cookie(table_name);
    if (index_cookie) {
        var index_hash = new Array();
        $('#' + table_name + ' tbody tr').each(function(){
            var html = $(this).html();
            var number = $(this).attr('id');
            index_hash[number] = html;
        });
        var list = index_cookie.split(',');
        var i = 0;
        $('#' + table_name + ' tbody tr').each(function(){
            var val = (list[i].split(':'))[0];
            $(this).html(index_hash[val]);
            $(this).attr('id', val);
            i++;
        });
    }

table要素のid属性値をcookieのキーにして、cookieを取得します。

    var table_name = 'foo';
    var index_cookie = $.cookie(table_name);

該当のcookieが存在すれば、現在のtr要素の中身(td要素)とtr要素のid属性値を取得し、tr要素のid属性値をキーにしてハッシュにtd要素を設定します。

    if (index_cookie) {
        var index_hash = new Array();
        $('#' + table_name + ' tbody tr').each(function(){
            var html = $(this).html();
            var number = $(this).attr('id');
            index_hash[number] = html;
        });

さきほど取得したcookieをカンマで分割し、配列listに保存します。

        var list = index_cookie.split(',');

もう一度現在のtr要素を探索し、今度はtr要素の内容に対し、配列listから取得した、並び替えられたtd要素を設定します。また、次の並び替えに対応できるよう、tr要素のid属性値も書き換えておきます。

        var i = 0;
        $('#' + table_name + ' tbody tr').each(function(){
            var val = (list[i].split(':'))[0];
            $(this).html(index_hash[val]);
            $(this).attr('id', val);
            i++;
        });

もっとエレガントな実装方法があると思いますので色々試してみてください。

また、テーブルの行が増減する場合はもうひと工夫必要になると思います。

2013.04.22
サンプルのリンク先が間違っていたので修正しました。

関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)