javascript(jQuery)でテーブルのrowspanを動的に設定・変更する
テーブルをソートした時にtdのrowspanの数字を自動的に書き換えれる様にしなさいという事でしたので、その覚え書きです。
「縦のセルの連結はなくてもいいんじゃないですか?」「ヤダ!!」っていうやりとりがあったのです。はい。
まあ、割と使い方が限定される感じですが、これをベースに色々できるかも。と思っとります。はい。
どうゆう事?なのでサンプルです。
以下にデモを用意してます。
一番右のセルが縦に繋がってるのです。はい。
その数が変わっても繋がってるのです。はい。
種類 | 名前 | 生息地 |
---|
コード
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<form name="testform" id="testform"> <select name="testselect" id="testselect"> <option>選択してください</option> <option value="a">俳優</option> <option value="s">歌手</option> </select> </form> <table id="testtable"> <thead> <tr> <th>種類</th> <th>名前</th> <th>生息地</th> </tr> </thead> <tbody id="tblbody"> </tbody> </table> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#testform { margin: 1em; } #testform select { padding: 0.5em; } #testtable { border-collapse: collapse; } #testtable tr td, #testtable tr th { border: 1px solid #ccc; padding: 0.4em; } |
Javascript(jQuery)
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 |
tableData = [{ "type": "俳優", "typeID": "a", "name": "ヴィンディーゼル", "habitat": "ハリウッド", "habiID": "h" }, { "type": "俳優", "typeID": "a", "name": "ロバートデニーロ", "habitat": "ハリウッド", "habiID": "h" }, { "type": "俳優", "typeID": "a", "name": "アンジェリーナジョリー", "habitat": "ハリウッド", "habiID": "h" }, { "type": "歌手", "typeID": "s", "name": "マドンナ", "habitat": "ハリウッド", "habiID": "h" }, { "type": "歌手", "typeID": "s", "name": "かわいい人", "habitat": "ハリウッド", "habiID": "h" }, { "type": "俳優", "typeID": "a", "name": "竹中直人", "habitat": "日本", "habiID": "n" }, { "type": "俳優", "typeID": "a", "name": "世界を釣る人", "habitat": "日本", "habiID": "n" }, { "type": "歌手", "typeID": "s", "name": "ブルーハーツ", "habitat": "日本", "habiID": "n" }, { "type": "歌手", "typeID": "s", "name": "muro", "habitat": "日本", "habiID": "n" }]; (function($) { //テーブル書き出し関数 function tblPrint() { $('#tblbody').empty(); Object.keys(tableData).forEach(function(key) { $('#tblbody').append('<tr class="' + tableData[key].typeID + '"><td>' + tableData[key].type + '</td><td>' + tableData[key].name + '<td class="' + tableData[key].habiID + '">' + tableData[key].habitat + '</td></tr>'); }); } //ロウスパン付与関数 function rowspanAdd() { a = []; $('#testtable tr td:last-child').each(function(i, habiclass) { var habiClass = $(this).attr('class'); a.push(habiClass); }); //重複してるやつの取り出し var counts = []; for (var i = 0; i < a.length; i++) { var key = a[i]; counts[key] = (counts[key]) ? counts[key] + 1 : 1; } //ロウスパン付与 Object.keys(counts).forEach(function(key) { var iClass = '.' + key; if ($('#testtable tr td').hasClass(key)) { $(iClass).not(':first').css('display', 'none'); $(iClass).eq(0).attr('rowspan', counts[key]); } }); } tblPrint(); rowspanAdd() //絞り込み $('#testselect').on('change', function() { var SeLeCt = $(this).val(); var selectClass = '.' + SeLeCt; if (SeLeCt === "選択してください") { tblPrint(); rowspanAdd(); } else { tblPrint(); $('#testtable tbody tr').not(selectClass).remove(); rowspanAdd(); } }); })(jQuery); |
解説
tableDataはJSON形式の配列です。はい。
1 2 3 4 5 6 |
function tblPrint() { $('#tblbody').empty(); Object.keys(tableData).forEach(function(key) { $('#tblbody').append('<tr class="' + tableData[key].typeID + '"><td>' + tableData[key].type + '</td><td>' + tableData[key].name + '<td class="' + tableData[key].habiID + '">' + tableData[key].habitat + '</td></tr>'); }); } |
んで、☝がそれをテーブルに書き出す関数です。はい。
class名で判断するので、繋げたい一番右のセルにclassを振ってます(繋げたいやつは同じclassです)。はい。
次からが本題です。はい。
1 2 3 4 5 |
a = []; $('#testtable tr td:last-child').each(function(i, habiclass) { var habiClass = $(this).attr('class'); a.push(habiClass); }); |
☝で、一番右のセルのclassを全部取ってきて、aという配列に入れてます。はい。
1 2 3 4 5 |
var counts = []; for (var i = 0; i < a.length; i++) { var key = a[i]; counts[key] = (counts[key]) ? counts[key] + 1 : 1; } |
☝で、同じclassの数をカウントしてます。はい。
これは「JavaScriptで配列の重複している項目の数をカウントする」
を参考にさせて頂きました。はい。
世の中には賢い人がいるもんですね。はい。
keyにはとってきたclass名が入ってます。
なので、class名があれば+1をして、なければ1をcounts配列のkeyに代入するんですね。はい。
賢いですね。はじめ見た時「んっ?」てなりました。はい。
ありがとうございます。
1 2 3 4 5 6 7 |
Object.keys(counts).forEach(function(key) { var iClass = '.' + key; if ($('#testtable tr td').hasClass(key)) { $(iClass).not(':first').css('display', 'none'); $(iClass).eq(0).attr('rowspan', counts[key]); } }); |
☝で、classなので「.」を付けて、そのclassのあるセルの一番目以外を消して、
一番目にrowspan=”数えた数”を入れてます。はい。
いや~しかし~使う事~あるんでしょうか~
そして~説明~下手ですね~
すみません~
もっと~上手いこと~
もっと~自動な感じで~
できそうな~気がするん~で~すが~
思い~つかない~ので~
思い~ついたら~修正~しますね~
てか~教えて~ください~ね~
あっ
ちなみに、JSONデータはエクセルから書き出せるマクロを書いてくれてる
素晴らしい方がいらっしゃいましたので、リンクしときます。はい。
ExcelのテーブルをJSON形式に変換するマクロ
サンプル動きませんよ
失礼しました。
wpのエディターが変わってエラーが出ていたようです。
修正しました