質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

1503閲覧

JavaScriptで作るhtmlのtableをソート可能にしたい

One_of_Arthur

総合スコア81

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2021/09/15 07:23

編集2021/09/15 08:14

前提・実現したいこと

JavaScriptで組み上げたhtmlのtableで作った表をソート可能にしたいです。
「tablesorter」を使っています。
https://mottie.github.io/tablesorter/docs/

発生している問題・エラーメッセージ

それらしきエラーはコンソールにも出ていません。
表自体は意図通りに作成表示されますが、
表示されるはずの三角マークは無く、その辺りをクリックしても全く無反応です。

historyListDivision関数から、historyListDivisionHeader関数を呼んでいます。

該当のソースコード

html

1 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> 2 3 <!-- ▼▼▼▼▼▼▼ 表のソートをするために要る ▼▼▼▼▼▼▼ --> 4 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js"></script> 5 <style> 6 .tablesorter th{ 7 position: relative; 8 cursor: pointer; 9 text-align: left; 10 } 11 .tablesorter th::before, .tablesorter th::after{ 12 content: ''; 13 position: absolute; 14 z-index: 2; 15 right: 7px; 16 width: 0; 17 height: 0; 18 border: 4px dashed; 19 border-color: #333 transparent; 20 pointer-events: none; 21 } 22 .tablesorter th::before{ 23 border-bottom-style: solid; 24 border-top: none; 25 top: 30%; 26 } 27 .tablesorter th::after{ 28 border-top-style: solid; 29 border-bottom: none; 30 bottom: 30%; 31 } 32 .tablesorter th.tablesorter-headerAsc:after{ 33 border: none; 34 } 35 .tablesorter th.tablesorter-headerAsc:before{ 36 top: 50%; 37 transform: translateY(-50%); 38 -webkit-transform: translateY(-50%); 39 } 40 .tablesorter th.tablesorter-headerDesc:before{ 41 border: none; 42 } 43 .tablesorter th.tablesorter-headerDesc:after{ 44 top: 50%; 45 transform: translateY(-50%); 46 -webkit-transform: translateY(-50%); 47 } 48 .tablesorter th.sorter-false:before, .tablesorter th.sorter-false:after{ 49 border: none; 50 } 51 </style> 52 <!-- ▲▲▲▲▲▲▲ 表のソートをするために要る ▲▲▲▲▲▲▲ -->

javascript

1 function historyListDivisionHeader(){ 2 var historyListViewBlock = document.getElementById('historyBlock'); 3 document.getElementById('historyBlock').innerHTML = ''; 4 5 var divTag = document.createElement('div'); 6 var historyCountID ='historyCount'; 7 divTag.setAttribute('id', historyCountID); 8 9 historyListViewBlock.appendChild(divTag); 10 11 var divTag = document.createElement('div'); 12 var historyScrollID ='historyScroll'; 13 divTag.setAttribute('id', historyScrollID); 14 divTag.setAttribute('style', 'height: 300px; overflow-y: scroll;'); 15 historyListViewBlock.appendChild(divTag); 16 17 // var historyScrollBlock = document.getElementById(historyScrollID); 18 // var tableTag = document.createElement('table'); 19 var tableTagID ='historyListView-table'; 20 // tableTag.setAttribute('id', tableTagID); 21 // tableTag.setAttribute('class', 'sort-table'); 22 // tableTag.setAttribute('data-sortlist', '[[3,0]]'); 23 // tableTag.setAttribute('border', '1'); 24 // tableTag.setAttribute('style', 'width: 100%; font-size: 90%;'); 25 // historyScrollBlock.appendChild(tableTag); 26 // document.getElementById(historyScrollID).innerHTML = '<table id="' + tableTagID + '"' + 27 document.getElementById(historyScrollID).innerHTML = '<table id="historyListView-table"' + 28 ' class="sort-table" data-sortlist="[[3,0]]"' + 29 ' border="1" style="width: 100%; font-size: 90%;"></table>'; 30 31 var tableTagBlock = document.getElementById(tableTagID); 32 var theadTag = document.createElement('thead'); 33 var theadTagID ='historyListView-thead'; 34 theadTag.setAttribute('id', theadTagID); 35 tableTagBlock.appendChild(theadTag); 36 37 var theadTagBlock = document.getElementById(theadTagID); 38 var trTag = document.createElement('tr'); 39 var trTagID ='historyListView-tr-midashi' 40 trTag.setAttribute('id', trTagID); 41 theadTagBlock.appendChild(trTag); 42 43 var trTagBlock = document.getElementById(trTagID); 44 var thTag = document.createElement('th'); 45 thTag.innerHTML = 'ツイート期間'; 46 trTagBlock.appendChild(thTag); 47 48 var trTagBlock = document.getElementById(trTagID); 49 var thTag = document.createElement('th'); 50 thTag.innerHTML = 'ツイート件数'; 51 trTagBlock.appendChild(thTag); 52 53 var trTagBlock = document.getElementById(trTagID); 54 var thTag = document.createElement('th'); 55 thTag.innerHTML = 'status'; 56 trTagBlock.appendChild(thTag); 57 58 var trTagBlock = document.getElementById(trTagID); 59 var thTag = document.createElement('th'); 60 61 thTag.innerHTML = '読み込み開始日時'; 62 trTagBlock.appendChild(thTag); 63 64 var trTagBlock = document.getElementById(trTagID); 65 var thTag = document.createElement('th'); 66 thTag.innerHTML = '使用時間'; 67 trTagBlock.appendChild(thTag); 68 69 var tableTagBlock = document.getElementById(tableTagID); 70 var tbodyTag = document.createElement('tbody'); 71 var tbodyTagID ='historyListView-tbody' 72 tbodyTag.setAttribute('id', tbodyTagID); 73 tableTagBlock.appendChild(tbodyTag); 74 } 75 76 function historyListDivision(){ //読み込み履歴を作成・表示する 77 twitterID = document.getElementById('twitterIDItem').value //グローバル変数にしている/対象のTwitter ID 78 79 var historyCount = 0; 80 for(let i = 0; i < localStorage.length; i++){ 81 var lskey = localStorage.key(i); 82 let result = lskey.indexOf(prefixHistoryMainData + twitterID); 83 if(result >= 0){ 84 if(historyCount == 0){ 85 historyListDivisionHeader(); 86 } 87 88 var timestampSpanSerial = lskey.replace(prefixHistoryMainData + twitterID + '.', ''); 89 var timestampSpan = timestampSpanSerial.substr( 0, timestampSpanSerial.lastIndexOf('.')); 90 var serial = timestampSpanSerial.replace(timestampSpan + '.', ''); 91 92 var lsStatusKey = prefixHistoryStatus + twitterID + '.' + timestampSpan + '.' + String(serial); 93 var lsStatus = localStorage.getItem(lsStatusKey); //locaStorageから取得 94 var lsStatusObj = JSON.parse(lsStatus); 95 96 var tbodyBlock = document.getElementById('historyListView-tbody'); 97 98 var trTag = document.createElement('tr'); 99 var trTagID ='historyListView-tr-' + String(historyCount); 100 trTag.setAttribute('id', trTagID); 101 tbodyBlock.appendChild(trTag); 102 103 var trTagBlock = document.getElementById(trTagID); 104 var tdTag = document.createElement('td'); 105 tdTag.innerHTML = timestampSpan; 106 trTagBlock.appendChild(tdTag); 107 108 var tdTag = document.createElement('td'); 109 tdTag.setAttribute('style', 'padding-right: 1em; text-align: right;'); 110 tdTag.innerHTML = Number(lsStatusObj.tweetCount); 111 trTagBlock.appendChild(tdTag); 112 113 var tdTag = document.createElement('td'); 114 tdTag.setAttribute('style', 'text-align: center;'); 115 tdTag.innerHTML = lsStatusObj.status; 116 trTagBlock.appendChild(tdTag); 117 118 var tdTag = document.createElement('td'); 119 tdTag.innerHTML = lsStatusObj.startDatetime; 120 trTagBlock.appendChild(tdTag); 121 122 var tdTag = document.createElement('td'); 123 tdTag.innerHTML = lsStatusObj.timeRequired; 124 trTagBlock.appendChild(tdTag); 125 126 historyCount++; 127 document.getElementById('historyCount').innerHTML = historyCount + '件ありました。' 128 } 129 } 130 } 131//省略 132 historyListDivision(); //他の関数内から呼んでいる 133//省略 134 $(function(){ //表のソートをするために要る 135 $('.sort-table').tablesorter({ 136 textExtraction: function(node){ 137 var attr = $(node).attr('data-value'); 138 if(typeof attr !== 'undefined' && attr !== false){ 139 return attr; 140 } 141 return $(node).text(); 142 } 143 }); 144 });

試したこと

最初は、コメントアウトしているようにcreateElementでやってみたところ、動かないので、innerHTMLにしてみましたが同じく動きません。
同じページ内に作ったサンプルコードは正常に動きます。

html

1 <table class="sort-table" data-sortlist="[[3,1]]"> 2 <thead> 3 <tr> 4 <th>番号</th> 5 <th>名前</th> 6 <th>生年月日</th> 7 <th>成績</th> 8 </tr> 9 </thead> 10 <tbody> 11 <tr> 12 <td>1</td> 13 <td>田中太郎</td> 14 <td>8月12日</td> 15 <td>95点</td> 16 </tr> 17<!-- 省略 --> 18 <tr> 19 <td>5</td> 20 <td>東川夏葉</td> 21 <td>1月4日</td> 22 <td>80点</td> 23 </tr> 24 </tbody> 25 </table>

JavaScriptで作成したtableでは使えないのでしょうか?
あるいは、どこか間違っているのでしょうか?
教えて下さい。

補足情報(FW/ツールのバージョンなど)

エディター:Brackets リリース 1.14 ビルド 1.14.2-17770
ブラウザ:Google Chrome バージョン: 93.0.4577.63(Official Build) (x86_64)
OS:macOS Mojave 10.14.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2021/09/15 07:43

プラグイン/ライブラリは公式配布サイトのURLを質問文に追記ください。(URLにはリンクを張ることができます)
Lhankor_Mhy

2021/09/15 07:43

historyListDivision を呼んでいる部分をご提示ください。
Lhankor_Mhy

2021/09/15 08:17 編集

質問の編集を拝読。 どこから呼ばれているのか知りたかったのですが…… どうやら、tablesorterとは関係なく呼ばれているようなので、実行順の問題ではないでしょうか?
One_of_Arthur

2021/09/16 07:38

「実行順の問題」がヒントになりました。 ありがとうございました!
guest

回答2

0

自己解決

アドバイスありがとうございました。
前提の「tablesorter」を使う方法で自己解決しました。

javascript

1 $(function(){ //表のソートをするために要る 2 $('.sort-table').tablesorter({ 3 textExtraction: function(node){ 4 var attr = $(node).attr('data-value'); 5 if(typeof attr !== 'undefined' && attr !== false){ 6 return attr; 7 } 8 return $(node).text(); 9 } 10 }); 11 });

の部分をhistoryListDivision関数内の最後にも記述した所、意図通りに動くようになりました。

投稿2021/09/16 07:37

One_of_Arthur

総合スコア81

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

javascript

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 document.querySelectorAll('.sort-table th').forEach(x=>{ 4 x.addEventListener('click',()=>{ 5 const idx=[...x.parentNode.children].indexOf(x); 6 const tbody=x.closest('table').querySelector('tbody'); 7 [...tbody.querySelectorAll('tr')].sort((x,y)=>{ 8 const tx=x.querySelector(`td:nth-child(${idx+1})`).textContent; 9 const ty=y.querySelector(`td:nth-child(${idx+1})`).textContent; 10 return tx==ty?0:(tx>ty?1:-1); 11 }).forEach(x=>tbody.appendChild(x)); 12 }); 13 }); 14}); 15</script> 16<table class="sort-table"> 17<thead> 18<tr> 19<th>番号</th> 20<th>名前</th> 21<th>生年月日</th> 22<th>成績</th> 23</tr> 24</thead> 25<tbody> 26<tr><td>1</td><td>田中太郎</td><td> 812</td><td> 95</td></tr> 27<tr><td>2</td><td>鈴木一郎</td><td> 33</td><td>100</td></tr> 28<tr><td>3</td><td>佐藤二朗</td><td>1212</td><td> 60</td></tr> 29<tr><td>4</td><td>吉田三郎</td><td> 66</td><td> 75</td></tr> 30<tr><td>5</td><td>東川夏葉</td><td> 14</td><td> 80</td></tr> 31</tbody> 32</table>

昇順/降順切り替え

javascript

1<style> 2.asc:after{ 3 font-size:0.7em; 4content:"▲"; 5} 6.desc:after{ 7 font-size:0.7em; 8content:"▼"; 9} 10</style> 11<script> 12window.addEventListener('DOMContentLoaded', ()=>{ 13 document.querySelector('.sort-table th:first-child').classList.add('asc'); 14 document.querySelectorAll('.sort-table th').forEach(x=>{ 15 x.addEventListener('click',()=>{ 16 let y=document.querySelector('.sort-table th.asc,.sort-table th.desc'); 17 if(x!==y) y?.classList.remove('asc','desc'); 18 x.classList.toggle('desc',x.classList.contains('asc')); 19 x.classList.toggle('asc'); 20 const idx=[...x.parentNode.children].indexOf(x); 21 const tbody=x.closest('table').querySelector('tbody'); 22 [...tbody.querySelectorAll('tr')].sort((y,z)=>{ 23 const ty=y.querySelector(`td:nth-child(${idx+1})`).textContent; 24 const tz=z.querySelector(`td:nth-child(${idx+1})`).textContent; 25 return (ty==tz?0:(ty>tz?1:-1))*(x.classList.contains('asc')?1:-1); 26 }).forEach(x=>tbody.appendChild(x)); 27 }); 28 }); 29}); 30</script> 31<table class="sort-table"> 32<thead> 33<tr> 34<th>番号</th> 35<th>名前</th> 36<th>生年月日</th> 37<th>成績</th> 38</tr> 39</thead> 40<tbody> 41<tr><td>1</td><td>田中太郎</td><td> 812</td><td> 95</td></tr> 42<tr><td>2</td><td>鈴木一郎</td><td> 33</td><td>100</td></tr> 43<tr><td>3</td><td>佐藤二朗</td><td>1212</td><td> 75</td></tr> 44<tr><td>4</td><td>吉田三郎</td><td> 66</td><td> 60</td></tr> 45<tr><td>5</td><td>東川夏葉</td><td> 14</td><td> 80</td></tr> 46</tbody> 47</table>

投稿2021/09/16 00:16

編集2021/09/16 00:46
yambejp

総合スコア114968

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問