第16回 カラムでソートできるテーブルを自作してみる – jQuery入門

2009 年 10 月 15 日 投稿者: naga3

やってきました車輪の再発明シリーズ。今回はテーブルのソートです。自作なんて面倒だ、という方はcsv2tableが高機能で日本語でオススメです。

テーブルソートのデモ

列名をクリックすると、昇順・降順にソートできます。


ソース

trの行は少し省略してあります。実際のソースは以下にあるので必要ならば右クリックで保存してください。
sort_table.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.3");</script>

<script type="text/javascript">
var tds = [
    ["メラ", "  2"],
    ["メラミ", "  6"],

・・・・・・省略・・・・・・

    ["トラマナ", "  2"]
];
$(function() {
    function draw() {
        var tag = '';
        $.each(tds, function(i, val) {
            tag += '<tr><td>'+ val[0] + '</td><td>' + val[1] + '</td></tr>';
        });
        $('table tbody').html(tag);
    }
    $('th').click(function() {
        var arrow = $('span', this);
        var index = $(this).parent().children().index(this);
        if (arrow.html() == '▼') {
            arrow.html('▲');
            tds.sort(function(a, b) { return a[index] < b[index] ? -1 : 1; });
        } else {
            arrow.html('▼');
            tds.sort(function(a, b) { return b[index] < a[index] ? -1 : 1; });
        }
        $(this).siblings().find('span').html('');
        draw();
    });
    draw();
});
</script>
<style type="text/css">
th, td {
    border: 1px solid black;
    padding: 2px;
}
th {
    background-color: #ccc;
    cursor: pointer;
}
</style>
</head>
<body>
<table><thead><tr><th>名前<span></span></th><th>消費MP<span></span></th></tr></thead><tbody></tbody></table>
</body>
</html>

プログラムの解説

テーブルの内容はtdsという2次元配列(正確には2次元配列ではありませんが)に格納しています。

draw関数

tableタグにtds配列の中身から生成したtr, tdタグを付け加えてテーブルを生成している部分です。
$.each(tds, function(i, val) {
$.eachは配列やオブジェクトに対して使うことのできる汎用的な繰り返し関数です。配列tdsに対して要素を先頭から一つずつ取り出し関数の中身が実行されます。そのとき、インデックスがi、値がvalに代入されます。
tag += '<tr><td>'+ val[0] + '</td><td>' + val[1] + '</td></tr>';
テーブル一行分のタグを生成しています。
$('table tbody').html(tag);
全ての行数分のタグを生成した後、tbodyのhtmlとして追加しています。

カラムのクリックイベント

$('th').click(function() {
カラムのth要素がクリックされたときに以下が実行されます。
var arrow = $('span', this);
このように書くと、this(クリックされたth要素)の子要素のspan要素を指定できます。このspan要素の中に昇順・降順を示す矢印が入ります。
var index = $(this).parent().children().index(this);
indexにはクリックされたカラムが左から数えて何番目かが入ります(一番左のカラムが0、次が1・・・)。$(this)はクリックされたth要素なのでparent()で親要素であるtr要素を示し、さらにchildren()でtr要素の子要素、すなわちth要素全てを選択することになります。そしてindex関数によってクリックされた要素が何番目かを調べています。回りくどいやり方ですが、他に良い方法が思いつかなかったので・・・。
arrow.html('▲');
tds.sort(function(a, b) { return a[index] < b[index] ? -1 : 1; });
降順の場合の処理です。JavaScript標準のsort関数に、選択されたカラムの文字列を比較する関数を登録しています。
arrow.html('▼');
tds.sort(function(a, b) { return b[index] < a[index] ? -1 : 1; });
昇順の場合の処理です。降順の逆ですね。
$(this).siblings().find('span').html('');
クリックされた以外のカラムの矢印を消しています。siblings()で兄弟要素、すなわち自分以外のth要素を選択します。

注意点

今回のソート関数は手抜きなので数値の比較ができません。上記ソースでは数値の桁を揃えて誤魔化しています。本来なら配列の値が数値かどうか調べてからソートするのが良いと思います。

この記事へのトラックバックURL

コメントをどうぞ