jQueryで簡単にドラッグ&ドロップのソートを実装する方法


読む:3分
試す:15分

はじめまして、4月にアシアルへ入社した噂の好青年こと高橋です。
今日はjQuery UIを使ったオシャンティなソートを紹介します。

まずはデモをご覧ください。

「こんなメンド・・・大変そうなUIできるかなぁ?」

心配ご無用!jQueryさんはやってくれます!!

まずは必要なソースを準備します。
下記からそれぞれ最新版をダンロードしてください。
http://jquery.com/download/ (24/7/19時点で ver 1.7.2)
http://jqueryui.com/download (24/7/19時点で ver 1.8.21)

ファイル構造・読み込み等は割愛します。

今回覚えるべき、たったひとつのシンプルなキーワード
「sortable」

まずはHTMLいきます


<table class="table table-striped table-bordered">
    <thead>
        <tr>
            <th>名前</th>
            <th>特徴</th>
        </tr>
    </thead>
    <tbody id="sortable">
        <tr>
            <th>とんこつラーメン</th>
            <td>コッテリ</td>
        </tr>
        <tr>
            <th>塩ラーメン</th>
            <td>うまい</td>
        </tr>
        <tr>
            <th>醤油ラーメン</th>
            <td>イケてる</td>
        </tr>
        <tr>
            <th>二郎</th>
            <td>関内</td>
        </tr>
    </tbody>
</table>

ちょっとこのtbodyのidに注目してください。さっそく出ましたね〜sortable。
tableのclassがごちゃごちゃしてますが、これはTwitter Bootstrap用です。

次にJavaScript ※bodyの閉じタグ前に


$('#sortable').sortable();
$('#sortable').disableSelection();

お〜い、高橋もっと仕事しろ〜。って言われそうですね
デモのJSソースってたったこれだけだったんですね〜。

そしてJSでも鍵になったのはsortableです!

ついでにドラッグできますよ〜!!アピールで


#sortable tr:hover { cursor: move; }

ま・・・また出た・・・ひぃいいい。
とこのようにスタイルを設定してあげると、ユーザがより感知しやすくて良いかと思います。

しかし、これだけではただ並び替えるだけでなんのこっちゃ、という機能ですね。
なので、ソートが実行されたら動的に何か書き換えるなどの操作をする必要があります。

応用編のデモです

HTML


<table class="table table-striped table-bordered">
    <thead>
        <tr>
            <th>順番</th>
            <th>名前</th>
            <th>特徴</th>
        </tr>
    </thead>
    <tbody id="sortable">
        <tr>
            <td class="rank">1</td>
            <th>とんこつラーメン</th>
            <td>コッテリ</td>
        </tr>
        <tr>
            <td class="rank">2</td>
            <th>塩ラーメン</th>
            <td>うまい</td>
        </tr>
        <tr>
            <td class="rank">3</td>
            <th>醤油ラーメン</th>
            <td>イケてる</td>
        </tr>
        <tr>
            <td class="rank">4</td>
            <th>二郎</th>
            <td>関内</td>
        </tr>
    </tbody>
</table>

JS


$('#sortable').sortable();
$('#sortable').disableSelection();
    
$('#sortable').bind('sortstop', function (e, ui) {
    // ソートが完了したら実行される。
    var rows = $('#sortable .rank');
    for (var i = 0, rowTotal = rows.length; i < rowTotal; i += 1) {
        $($('.rank')[i]).text(i + 1);
    }
})

このようにjQuery UIの方でイベントが予め準備されています。
リファレンスを読めば一目瞭然できるでしょう。
http://jqueryui.com/demos/sortable/#events

私がプロダクトで利用したときは「sortstop」イベントをbindしておいて、ソートが完了した瞬間にtbody以下のinput nameを動的に書き換える処理で対応していました。

初のアシアルブログでしたが、お役に立てれば幸いです。

今後もデザイン・UI、フロントエンドをはじめ、バックエンドについて記事を書いていきます。
これからよろしくお願いします!