Sorry, this entry is only available in 日本語.
Tag Archives: ソート
How to Sort Table in Javascript
javascript を使ってテーブルをソートすることになった。ドットインストールを見ると複数項目でソートする方法まで載っている・・・が、これを一般化してどんなテーブルでもソートできるようにするにはどうするか考えてみた。公開されているライブラリもあるんですけどね。
The code is as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
var sortFunctions = (function() { var weekday_names = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; /** * Comparing Strings * Weekday String is compared in order of the weekday. */ var compareString = function(a, b) { a = a.trim(); b = b.trim(); var a_week_index = weekday_names.indexOf(a); var b_week_index = weekday_names.indexOf(b); if (a_week_index >= 0 && b_week_index >= 0) { a = a_week_index; b = b_week_index; } if (a == b) { return 0; } else { if (a > b) { return 1; } else { return -1; } } } /** * 2 つの tr の順序を与えられた order によって比較する * @a * @b * @order_array [[number, order], ...] order は並び順(昇順なら1), number は td の順次(0 から始まる) * @sort_array */ var compareTr = function(a, b, order_array, sort_array) { var a_tds = $(a).find('td'); var b_tds = $(b).find('td'); for (var i = 0; i < sort_array.length; i++) { value = compareString( a_tds.eq(sort_array[i]).text(), b_tds.eq(sort_array[i]).text()); if (value != 0) { return value * order_array[sort_array[i]]; } } return 0; } /** * Generate Order array * @index 変更対象のカラムのindex * @last_index */ var composeOrder = function(index, order_array, sort_array) { // 最後にソート対象になっていた場合は逆順にソートするように設定する。 if (sort_array.length > 0 && index == sort_array[0]) { order_array[index] *= -1; } else { var remove_index = -1; for (var i = 1; i < sort_array.length; i++) { if (sort_array[i] == index) { remove_index = i; break; } } if (remove_index > 0) { sort_array.splice(remove_index, 1); } sort_array.unshift(index); } } /** * Sort rows */ var sortRows = function(rows, order_array, sort_array) { rows.sort(function(a, b) { return compareTr(a, b, order_array, sort_array); }); return rows; } var AscChar = '▼'; var DescChar = '▲'; /** * テーブル行の並び替え * @target_table 並び替え対象のテーブル * @orders 並び替えの順番 * @sort_orders 並び替えの優先順位 */ var _sort = function(order_array, sort_array, start_object) { var target_table = $(start_object).parent().parent().parent(); var head = target_table.find('thead>tr>th'); var rows = target_table.find('tbody>tr'); var index = $(head).index(start_object); if (sort_array.length > 0) { var text = $(head).eq(sort_array[0]).text(); if (order_array[sort_array[0]] > 0) { text = text.replace(AscChar, ''); } else { text = text.replace(DescChar, ''); } $(head).eq(sort_array[0]).text(text); } // ソート順序を決定する。 composeOrder(index, order_array, sort_array); // 並び替える。 var new_rows = sortRows(rows, order_array, sort_array); target_table.children('tbody').empty().append(new_rows); var head_text = ""; if (order_array[sort_array[0]] > 0) { head_text += AscChar; } else { head_text += DescChar; } $(head).eq(sort_array[0]).text( head_text + $(head).eq(sort_array[0]).text()); } return {sort: _sort}; })(); |
The preceding code sorts table rows with sortFunction.sort and shows “▼”/”▲”. sort function receives 3 parameters, order_array, sort_array and clicked th tag (this). 各パラメータについて下に説明を書いた。
- order_array
-
Storing each columns’ order directions, ASC/DESC. If you have 4 columns, it have to be like
[1, 1, 1, 1]
. 1 means ascending, -1 means descending. If the table is not sorted in initial state, it’s OK to set 1.ソートをするときに 昇順・降順 が入れ替わる場合は 該当する値を 1 と -1 で入れ替える。 SQL の order by でいうところの ASC, DESC 。
- sort_array
-
This parameter is array that shows which column is used for sorting. If the table is sorted with first and second column, and sorted with first column primarily, then the parameter have to be
[0, 1]
. If the table is not sorted, the parameter have to be[]
.最後にソートされた列の index は 配列の先頭に追加する。 This is like column order in order by clause of SQL.
- this (th)
This enables us to detect which column is clicked.
Issues
- 並べ替えられるオブジェクトに対して $(object).click() のようにしてイベントを記述している場合、並べ替え後に同じことをやる必要がある。
- 列の表示名に ▲(▼) を使用すると、ソートの際に消える。
- ▲(▼) は 最後にソートした列のみに表示する。
- 昇順・降順のときの大小の比較は Sun, Mon, … , Sat が記述されている場合は 日曜を先頭にして考える。文字列は javascript 上 の >, < で比較する。数値の比較には対応していない。
- table の中には 必ず thead, tbody を記述する。 parent() の数が固定で書かれているため。
order の扱いについては、 order by column_name_1 DESC, column_name_2 ASC のように [[0, -1], [1, 1]] で表すことも考えたが、優先順位と降順・昇順を別にしたほうがわかりやすいのではないかと思って上のようになった。
また、ある列で降順でソートされた後に別の列で昇順でソートした場合、最初にソートした降順は保持されるが、今になって降順・昇順は全列で統一したほうがよいのではないかと思っている。