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

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

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

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

4回答

12689閲覧

JSでテーブルの縦計算をしたいのですが色々とわかりません。

退会済みユーザー

退会済みユーザー

総合スコア0

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

HTML

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

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

1クリップ

投稿2017/07/04 13:52

###前提・実現したいこと
◆HTMLで家計簿を作る◆

JSでテーブルの縦計算をしたいです。

・1ページ内に1月から12月分のテーブルを表示させてすべて入力可能
・入力値マイナスにも対応
・収入の合計を表示
・出費の合計を表示
・収入ー出費=合計の残高を一つ下のセルに表示
・個人貯金残高の右のセルに、個人貯金の右に入力した値を表示
・共通貯金残高の右のセルに、共通貯金の右に入力した値を表示
・個人貯金残高と共通貯金残高を足したものを合計貯金残高の右に表示
・入力した値と計算後出力された値が1以下の場合フォントカラーを赤にする
・1月の「個人、共通、合計貯金残高」を2月以降のテーブルの「個人、共通貯金」を2月以降のテーブルの「個人、共通、合計貯金残高」に足して表示する
・「文字」「サンプル」と表示されている箇所は計算しない
・入力、出力された数値をカンマ区切り表示する
・数値を入力する欄に入力されなかった場合「0」を表示する
・あわよくば数値を入力後ボタンを押さずに自動計算される挙動を追加(例:数値を入力後エンターを押すと計算する等)
・合計値が表示されるばしょは入力できないようにする
・localStorageを使って入力値を保存

###現在の状況・発生している問題
・ボタンを押すことで計算され出力される
・横計算になっている。(tr列を計算している)
・文字を入力する列と数値を入力する列の分別ができていない
・計算ボタンを押すと下から5列目の「残高」の箇所に計算結果が出てしまう
・2月以降のテーブルを表示してしまうとテーブルに入力できなくなってしまう

###該当のソースコード

js

1<script type="text/javascript"> 2 /*** 入力できるテーブル<table>セルの初期設定 ***/ 3 var flg = 0; // 入力値判定フラッグ 4 window.onload = function() { 5 var myTbl = document.getElementById('editTbl'); // ID名から要素を参照<table id="ID名"> 6 var len = editTbl.rows[1].cells.length; // 列数, セルへの参照はrowsのcellsコレクション 7 var Td = myTbl.getElementsByTagName('td'); // myTbl内の td要素のリスト(NodeList) 8 for (var i = 0; i < Td.length; i++) { // <td>をループ 9 Td[i].setAttribute('id', 'td' + i); // ID名を設定 10 Td[i].onclick = function() { 11 if (flg == 1) { 12 return 13 } // 半角数値でなければ 14 eDit(this.id); // onclickで 'eDit'を実行 15 } 16 } 17 18 function eDit(id) { // クリックしたセルに 入力領域作成 19 cellNum = document.getElementById(id).cellIndex; // 何列目か 20 if (len - 4 == cellNum) { 21 alert('この列は入力できません。'); 22 return 23 } // もし最後の列なら 24 var Td = document.getElementsByTagName('td'); 25 var Spn = document.createElement('span'); // span要素 生成 26 Spn.setAttribute('contenteditable', 'true') // contenteditable属性を付加 27 Spn.setAttribute('id', 'Spn' + id); //ID名を付加 28 Td[id].innerHTML = ""; // Td[id]の中を空に 29 Td[id].appendChild(Spn); // SpnをTd[id]に追加 これで入力可能になる 30 Spn.focus(); // カーソルを合わせる 31 Spn.onblur = function() { 32 bLur(id); // フォーカスが外れたら 33 } 34 } 35 36 function bLur(id) { 37 var Spn = document.getElementById('Spn' + id); 38 var str = Spn.innerText; 39 str = Spn.textContent; // Spn の値 40 if (str.match(/[^0-9 . -]|[¥s]+/) || str == "") { 41 flg = 1; // 入力チェック 42 } // 半角数値でなければ 再入力 43 flg = 0; 44 Td[id].innerHTML = str; // Td[id]に Spnの値を入れる 45 } 46 } 47 /*** 入力できるテーブル<table>,セルの初期設定 ここまで ***/ 48 49 /* 各行のセルの合計値 算出 */ 50 function calcTbl() { 51 var myTbl = document.getElementById('editTbl'); 52 for (var i = 2; i < myTbl.rows.length; i++) { // <tr>をループ(1行目は,見出し行でスキップ) 53 var num = 0; // セルの値 格納変数 54 var total = 0; // セルの合計値 格納変数 55 for (var j = 0; j < myTbl.rows[i].cells.length - 1; j++) { // tr[i]行目のセルの数 56 num = myTbl.rows[i].cells[j].innerHTML; // tr[i]番目行のtd[j] 番目セルの値,取得 57 num = parseFloat(num); // 数値に変換 58 59 num = num * 1000; // 小数点問題 (-20.2+20=0.1999~)のような現象を回避 60 total += num; // 合計値 61 } 62 total = total / 1000; 63 myTbl.rows[i].cells[j].innerHTML = total; // 行の末尾のセルに合計値 64 myTbl.rows[i].cells[j].style.color = "#cc00ff"; 65 } 66 } 67 </script>

html

1<!DOCTYPE html> 2<html lang=""> 3<head> 4 <meta charset="UTF-8"> 5 <title>javascriptで入力,計算できるテーブル(表)</title> 6 <style type="text/css"> 7 /*テーブルCSS Firefox でborderが表示されなかったりする事の対策を込みで。*/ 8 9 #editTbl { 10 border-collapse: separate; 11 /* 枠線の表示方法 間隔をあけて表示 */ 12 border-spacing: 0; 13 /* 隣合うセルのボーダーにできた隙間の幅を指定 */ 14 border-top: 1px solid #b0c4de; 15 /* 枠線 borderプロパティ: 太さ 種類 色 */ 16 border-right: 1px solid #b0c4de; 17 } 18 #editTbl th, 19 td { 20 height: 25px; 21 width: 75px; 22 border-bottom: 1px solid #b0c4de; 23 border-left: 1px solid #b0c4de; 24 } 25 #editTbl th { 26 color: #000; 27 background: #d7ffd7; 28 } 29 #editTbl td { 30 text-align: right; 31 } 32 #editTbl p { 33 margin: 0; 34 /* contenteditable属性 IE対策 */ 35 } 36 #editTbl span { 37 padding-left: 1px; 38 /* firefoxキャレット位置調整 */ 39 color: #f02406; 40 } 41 </style> 42</head> 43<body> 44 <!--テーブル1月--> 45 <table id="editTbl"> 46 <tr> 47 <th colspan="6">1月</th> 48 </tr> 49 <tr> 50 <th colspan="2">収入</th> 51 <th colspan="2">出費</th> 52 <th colspan="1">備考</th> 53 </tr> 54 <tr> 55 <td>文字</td> 56 <td></td> 57 <td>文字</td> 58 <td></td> 59 <td>サンプル</td> 60 </tr> 61 <tr> 62 <td>文字</td> 63 <td></td> 64 <td>文字</td> 65 <td></td> 66 <td>サンプル</td> 67 </tr> 68 <tr> 69 <td>文字</td> 70 <td></td> 71 <td>文字</td> 72 <td></td> 73 <td>サンプル</td> 74 </tr> 75 <tr> 76 <td>文字</td> 77 <td></td> 78 <td>文字</td> 79 <td></td> 80 <td>サンプル</td> 81 </tr> 82 <tr> 83 <td>文字</td> 84 <td></td> 85 <td>文字</td> 86 <td></td> 87 <td>サンプル</td> 88 </tr> 89 <tr> 90 <td>文字</td> 91 <td></td> 92 <td>文字</td> 93 <td></td> 94 <td>サンプル</td> 95 </tr> 96 <tr> 97 <td>文字</td> 98 <td></td> 99 <td>文字</td> 100 <td></td> 101 <td>サンプル</td> 102 </tr> 103 <tr> 104 <td>文字</td> 105 <td></td> 106 <td>文字</td> 107 <td></td> 108 <td>サンプル</td> 109 </tr> 110 <tr> 111 <td>文字</td> 112 <td></td> 113 <td>文字</td> 114 <td></td> 115 <td>サンプル</td> 116 </tr> 117 <tr> 118 <td>文字</td> 119 <td></td> 120 <td>文字</td> 121 <td></td> 122 <td>サンプル</td> 123 </tr> 124 <tr> 125 <td>文字</td> 126 <td></td> 127 <td>文字</td> 128 <td></td> 129 <td>サンプル</td> 130 </tr> 131 <tr> 132 <td>文字</td> 133 <td></td> 134 <td>個人貯金</td> 135 <td></td> 136 <td>サンプル</td> 137 </tr> 138 <tr> 139 <td>文字</td> 140 <td></td> 141 <td>共通貯金</td> 142 <td></td> 143 <td>サンプル</td> 144 </tr> 145 <tr> 146 <th>合計</th> 147 <td></td> 148 <th>合計</th> 149 <td></td> 150 <td>サンプル</td> 151 </tr> 152 <tr> 153 <th colspan="5">残高</th> 154 </tr> 155 <tr> 156 <td colspan="5"></td> 157 </tr> 158 <tr> 159 <th colspan="3">個人貯金残高</th> 160 <td colspan="2"></td> 161 </tr> 162 <tr> 163 <th colspan="3">共通貯金残高</th> 164 <td colspan="2"></td> 165 </tr> 166 <tr> 167 <th colspan="3">合計貯金残高</th> 168 <td colspan="2"></td> 169 </tr> 170 </table> 171 <p><button type="button" onclick="calcTbl()">計算</button></p> 172 <!--//テーブル1月--> 173</body> 174</html>

上記のやり方は結構無理やりだったりするので、こんなめんどくさいことしなくてもこれでいいじゃん、等々もっと簡単な解決法があればご教示願います…。

イメージとして簡単ではありますが形はこうなればと思います。↓
イメージ説明

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

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

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

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

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

guest

回答4

0

修正方針

JavaScript

1var len = editTbl.rows[1].cells.length; // 列数, セルへの参照はrowsのcellsコレクション

querySelectorAll やjQueryのセレクタエンジンはそこそこコストがかかるので、速さを重視するなら rows[i].cells[j] も有りだと思います。
合計値を出力するtd要素ノードの cellIndex を変数に格納し、editTbl.rows[1].cells[cellIndex] で cellIndex を固定すれば、列の合計値を算出できるでしょう。
後述のコードでは、構造上、thead, tbody, tfoot に分けた方が良いと思ったので、HTMLに少し手を入れました。

コード

HTML

1<!--テーブル1月--> 2<table class="calc"> 3 <thead> 4 <tr> 5 <th colspan="6">1月</th> 6 </tr> 7 <tr> 8 <th colspan="2">収入</th> 9 <th colspan="2">出費</th> 10 <th colspan="1">備考</th> 11 </tr> 12 </thead> 13 <tbody> 14 <tr> 15 <td>文字</td> 16 <td><input type="number"></td> 17 <td>文字</td> 18 <td><input type="number"></td> 19 <td>サンプル</td> 20 </tr> 21 <tr> 22 <td>文字</td> 23 <td><input type="number"></td> 24 <td>文字</td> 25 <td><input type="number"></td> 26 <td>サンプル</td> 27 </tr> 28 <tr> 29 <td>文字</td> 30 <td><input type="number"></td> 31 <td>文字</td> 32 <td><input type="number"></td> 33 <td>サンプル</td> 34 </tr> 35 <tr> 36 <td>文字</td> 37 <td><input type="number"></td> 38 <td>文字</td> 39 <td><input type="number"></td> 40 <td>サンプル</td> 41 </tr> 42 <tr> 43 <td>文字</td> 44 <td><input type="number"></td> 45 <td>文字</td> 46 <td><input type="number"></td> 47 <td>サンプル</td> 48 </tr> 49 <tr> 50 <td>文字</td> 51 <td><input type="number"></td> 52 <td>文字</td> 53 <td><input type="number"></td> 54 <td>サンプル</td> 55 </tr> 56 <tr> 57 <td>文字</td> 58 <td><input type="number"></td> 59 <td>文字</td> 60 <td><input type="number"></td> 61 <td>サンプル</td> 62 </tr> 63 <tr> 64 <td>文字</td> 65 <td><input type="number"></td> 66 <td>文字</td> 67 <td><input type="number"></td> 68 <td>サンプル</td> 69 </tr> 70 <tr> 71 <td>文字</td> 72 <td><input type="number"></td> 73 <td>文字</td> 74 <td><input type="number"></td> 75 <td>サンプル</td> 76 </tr> 77 <tr> 78 <td>文字</td> 79 <td><input type="number"></td> 80 <td>文字</td> 81 <td><input type="number"></td> 82 <td>サンプル</td> 83 </tr> 84 <tr> 85 <td>文字</td> 86 <td><input type="number"></td> 87 <td>文字</td> 88 <td><input type="number"></td> 89 <td>サンプル</td> 90 </tr> 91 <tr> 92 <td>文字</td> 93 <td><input type="number"></td> 94 <td>個人貯金</td> 95 <td><input type="number"></td> 96 <td>サンプル</td> 97 </tr> 98 <tr> 99 <td>文字</td> 100 <td><input type="number"></td> 101 <td>共通貯金</td> 102 <td><input type="number"></td> 103 <td>サンプル</td> 104 </tr> 105 </tbody> 106 <tfoot> 107 <tr> 108 <th>合計</th> 109 <td class="sum"><input type="number"></td> 110 <th>合計</th> 111 <td class="sum"><input type="number"></td> 112 <td>サンプル</td> 113 </tr> 114 <tr> 115 <th colspan="5">残高</th> 116 </tr> 117 <tr> 118 <td colspan="5"></td> 119 </tr> 120 <tr> 121 <th colspan="3">個人貯金残高</th> 122 <td colspan="2"></td> 123 </tr> 124 <tr> 125 <th colspan="3">共通貯金残高</th> 126 <td colspan="2"></td> 127 </tr> 128 <tr> 129 <th colspan="3">合計貯金残高</th> 130 <td colspan="2"></td> 131 </tr> 132 </tfoot> 133</table> 134<p><button class="execute-calc" type="button">計算</button></p> 135<!--//テーブル1月--> 136 137<!--テーブル2月--> 138<table class="calc"> 139 <thead> 140 <tr> 141 <th colspan="6">2月</th> 142 </tr> 143 <tr> 144 <th colspan="2">収入</th> 145 <th colspan="2">出費</th> 146 <th colspan="1">備考</th> 147 </tr> 148 </thead> 149 <tbody> 150 <tr> 151 <td>文字</td> 152 <td><input type="number"></td> 153 <td>文字</td> 154 <td><input type="number"></td> 155 <td>サンプル</td> 156 </tr> 157 <tr> 158 <td>文字</td> 159 <td><input type="number"></td> 160 <td>文字</td> 161 <td><input type="number"></td> 162 <td>サンプル</td> 163 </tr> 164 <tr> 165 <td>文字</td> 166 <td><input type="number"></td> 167 <td>文字</td> 168 <td><input type="number"></td> 169 <td>サンプル</td> 170 </tr> 171 <tr> 172 <td>文字</td> 173 <td><input type="number"></td> 174 <td>文字</td> 175 <td><input type="number"></td> 176 <td>サンプル</td> 177 </tr> 178 <tr> 179 <td>文字</td> 180 <td><input type="number"></td> 181 <td>文字</td> 182 <td><input type="number"></td> 183 <td>サンプル</td> 184 </tr> 185 <tr> 186 <td>文字</td> 187 <td><input type="number"></td> 188 <td>文字</td> 189 <td><input type="number"></td> 190 <td>サンプル</td> 191 </tr> 192 <tr> 193 <td>文字</td> 194 <td><input type="number"></td> 195 <td>文字</td> 196 <td><input type="number"></td> 197 <td>サンプル</td> 198 </tr> 199 <tr> 200 <td>文字</td> 201 <td><input type="number"></td> 202 <td>文字</td> 203 <td><input type="number"></td> 204 <td>サンプル</td> 205 </tr> 206 <tr> 207 <td>文字</td> 208 <td><input type="number"></td> 209 <td>文字</td> 210 <td><input type="number"></td> 211 <td>サンプル</td> 212 </tr> 213 <tr> 214 <td>文字</td> 215 <td><input type="number"></td> 216 <td>文字</td> 217 <td><input type="number"></td> 218 <td>サンプル</td> 219 </tr> 220 <tr> 221 <td>文字</td> 222 <td><input type="number"></td> 223 <td>文字</td> 224 <td><input type="number"></td> 225 <td>サンプル</td> 226 </tr> 227 <tr> 228 <td>文字</td> 229 <td><input type="number"></td> 230 <td>個人貯金</td> 231 <td><input type="number"></td> 232 <td>サンプル</td> 233 </tr> 234 <tr> 235 <td>文字</td> 236 <td><input type="number"></td> 237 <td>共通貯金</td> 238 <td><input type="number"></td> 239 <td>サンプル</td> 240 </tr> 241 </tbody> 242 <tfoot> 243 <tr> 244 <th>合計</th> 245 <td class="sum"><input type="number"></td> 246 <th>合計</th> 247 <td class="sum"><input type="number"></td> 248 <td>サンプル</td> 249 </tr> 250 <tr> 251 <th colspan="5">残高</th> 252 </tr> 253 <tr> 254 <td colspan="5"></td> 255 </tr> 256 <tr> 257 <th colspan="3">個人貯金残高</th> 258 <td colspan="2"></td> 259 </tr> 260 <tr> 261 <th colspan="3">共通貯金残高</th> 262 <td colspan="2"></td> 263 </tr> 264 <tr> 265 <th colspan="3">合計貯金残高</th> 266 <td colspan="2"></td> 267 </tr> 268 </tfoot> 269</table> 270<p><button class="execute-calc" type="button">計算</button></p> 271<!--//テーブル2月--> 272 273<script> 274'use strict'; 275(function () { 276 function handleClick (event) { 277 var table = event.target.parentNode.previousElementSibling, 278 sumList = table.getElementsByClassName('sum'); 279 280 for (var i = 0, len = sumList.length, sumCell, sum; i < len; ++i) { 281 sumCell = sumList[i]; 282 sum = 0; 283 284 for (var j = 0, rows = table.tBodies[0].rows, rLen = rows.length, cellIndex = sumCell.cellIndex; j < rLen; ++j) { 285 sum += rows[j].cells[cellIndex].firstChild.valueAsNumber || 0; 286 } 287 288 sumCell.firstChild.value = sum; 289 } 290 } 291 292 function main () { 293 var button = this.document.getElementsByClassName('execute-calc'); 294 295 for (var i = 0, len = button.length; i < len; ++i) { 296 button[i].addEventListener('click', handleClick, false); 297 } 298 } 299 300 main.call(this); 301}.call(this)); 302</script>

更新履歴

  • 2017/07/05 12:43 複数のtable要素に適用できるようにした

Re: tukapon_ さん

投稿2017/07/05 03:20

編集2017/07/05 03:43
think49

総合スコア18164

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

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

0

質問はもう少し絞り込んだ方がいいと思います。
とりあえず、縦計算についてはdocument.querySelectorAll('table tr td:nth-child(2)')みたいな感じで取得して色々やる方が早いと思いました。

投稿2017/07/05 02:26

Lhankor_Mhy

総合スコア36115

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

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

0

ベストアンサー

エディタブルなテーブルを処理するよりは
入力ですからセルにテキストボックス埋めたほうがよいのではないでしょうか?

HTML

1<style> 2#t1 input{text-align:right} 3</style> 4<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 5<script> 6$(function(){ 7 $('#t1 tbody input').on('change',function(){ 8 var idx=$(this).closest('tr').find('td').index($(this).closest('td')); 9 var sum=0; 10 $(this).closest('tbody').find('tr').each(function(){ 11 var num=parseInt($(this).find('td').eq(idx).find('input').val()); 12 sum+=isNaN(num)?0:num; 13 }); 14 $(this).closest('table').find('tfoot td').eq(idx).find('input').val(sum); 15 }); 16}); 17</script> 18<table id="t1"> 19<tbody> 20<tr><td><input type="text"></td><td><input type="text"></td><td><input type="text"></td></tr> 21<tr><td><input type="text"></td><td><input type="text"></td><td><input type="text"></td></tr> 22<tr><td><input type="text"></td><td><input type="text"></td><td><input type="text"></td></tr> 23<tr><td><input type="text"></td><td><input type="text"></td><td><input type="text"></td></tr> 24<tr><td><input type="text"></td><td><input type="text"></td><td><input type="text"></td></tr> 25<tr><td><input type="text"></td><td><input type="text"></td><td><input type="text"></td></tr> 26</tbody> 27<tfoot> 28<tr><td i><input type="text" value="0"></td><td><input type="text" value="0"></td><td><input type="text" value="0"></td></tr> 29</tfoot> 30</table>

投稿2017/07/05 01:36

yambejp

総合スコア114843

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

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

0

インデックスでセルを特定して計算するのもいいのですが、あらかじめ列ごとにclassをつけておけば取得が楽になるのではないでしょうか?

投稿2017/07/05 00:28

x_x

総合スコア13749

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問