人生のプチ美学を教えてください!!

いつもお世話になっております。

こちらの質問と回答を参考にプログラムを付け足して、リストを作る練習をしています。
http://oshiete.goo.ne.jp/qa/8090793.html

テーブル行の先頭に項目名を表示させて、表を分かりやすくしようと思ったのですが、
最後に出力される項目名がそれまでの項目名を上書きしてしまい、
項目名が1個しか表示されないため、テーブルがずれて表示されてしまいます。

50個 金額~~
100個 金額~~
と表示させるためには、どこを手直ししたら良いのか知恵を貸してください。

よろしくお願いします。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitio …
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>innnerHTMLで自動生成された表を出力したい</title>
<style>
h2 { margin-bottom:0; color:#900;}
table{ border:none; font-size:12px;}
table tr th{ padding:5px; width:90px; background:#69F;}
table tr td{ padding:5px; text-align:right; background:#9CF;}

</style>
<script type="text/javascript">
//ラジオボタンのvalue値を取得
var daysRate;
var nouki = document.getElementsByName('nouki');
var price = new Array ( 10, 30, 50 );

function getRate() {
for ( var i = 0; i < nouki.length; i ++ ) {
if ( nouki[i].checked ) {
daysRate = nouki[i].value;
}}return parseFloat(daysRate);}

function calc() {
// 選択されているレートを取得
var rate = getRate();
var list_name= new Array('<h2>表1</h2>','<h2>表2</h2>','<h2>表3</h2');
var table_start= "<div><table><tbody>";
var table_head= '<tr><th>入数</th><th>ヘッダー1</th><th>ヘッダー2</th><th>ヘッダー3</th></tr>';
var table_kosuu= "";
var table_td= "";
var table_end= "</tbody></table></div><hr />";

// priceが増えてもロジックをいじる必要がないようにprice.lengthでループ数を制御
for(var i=50; i<=100; i+=50){
if(i==50){
table_kosuu = '<tr><td>' + i + '個</td>';
for ( var j = 0; j < price.length; j ++ ) {
if(j < price.length-1){
table_td += '<td>¥' + parseInt(price[j]*i) * rate + '</td>';
} else {
table_td += '<td>¥' + parseInt(price[j]*i) * rate + '</td></tr>';
}
}
}
if(i==100){
table_kosuu = '<tr><td>' + i + '個</td>';
for ( var j = 0; j < price.length; j ++ ) {
if(j < price.length-1){
table_td += '<td>¥' + parseInt(price[j]*i) * rate + '</td>';
} else {
table_td += '<td>¥' + parseInt(price[j]*i) * rate + '</td></tr>';
}
}
}
document.getElementById('priceTableOutput').innerHTML = list_name[0] + table_start + table_head + table_kosuu + table_td; + table_end;
}
}
window.onload = function() {
// 読込み後も一度テーブル表示を実行する
calc();
}
</script>
</head>
<body>
再計算ボタンを押すと価格表が再計算されます。<br />
<input type="radio" name="nouki" value="1" checked="checked" />通常配達
<input type="radio" name="nouki" value="1.25" />翌日配達
<input type="radio" name="nouki" value="1.5" />当日配達
<input type="button" value="再計算" onClick="calc()">
<div id="priceTableOutput">innerHTMLで、ここに表を出力</div>
<br />
</body>
</html>

A 回答 (4件)

#1 で DOM に挑戦するとのことでしたので、私も挑戦してみました。


DOMっぽい長ったらしい記述は関数 tagOn に閉じ込めたり、今時のスクリプト記述を利用したりしたので、割とすんなり書けましたが難解になったかと反省しております。

何かの参考になれば幸いです。

<!DOCTYPE html>
<script>addEventListener('load',function(e){ // イマドキの window.onload

function tagOn(p,n,t) {
' '; var e = p.appendChild(document.createElement(n));
' '; if (typeof t == 'string') {
'   '; e.appendChild(document.createTextNode(t)); // 要素配下にテキストを追加
' '; } else if (t instanceof Array) {
'   '; tagOn.apply(this,[e].concat(t)); // 再帰を使って、要素配下に要素を追加
' '; }
' '; return e;
}
function readRadio(radios) {
' '; for (var i = 0; i < radios.length; i++) if (radios[i].checked) return radios[i].value;
' '; return undefined;
}
var PRICES = [ // JSONっぽいデータ構造にして汎用化
{ name:'あれ', price:10 }, { name:'これ', price:30 }, { name:'それ', price:50 }
];
function makeTable(root, rate) {
' '; var t = tagOn(root,'table'); t.border = true;
' '; var h = tagOn(t,'thead');
' '; var hr = tagOn(h,'tr',['th','個数']); // 再帰のおかげで、一行で多重階層が記述できて便利
' '; PRICES.forEach(function(o){ tagOn(hr,'th',o.name) }); // イマドキの for 句
' '; var b = tagOn(t,'tbody');
' '; for (var i = 0; i < 2; i++) {
'   '; var n = (i+1) * 50;
'   '; var f = function(p){ return '¥' + (p * n * rate) }; // ラムダ式っぽい記述
'   '; var br = tagOn(b,'tr',['td', n+'個']);
'   '; PRICES.forEach(function(o){ tagOn(br,'td',f(o.price)) });
' '; }
}
function calc(ev){
' '; if (ev) ev.preventDefault();
' '; var form = document.forms['casio'];
' '; var rate = parseFloat(readRadio(form.elements['nouki']));
' '; var root = document.querySelector('.rateTable'); // jQueryっぽい記述
' '; while (root.firstChild) root.removeChild(root.firstChild); // 追加前に全削除
' '; tagOn(root, 'h2', '表1');
' '; makeTable(root, rate);
}
calc();
document.forms['casio'].addEventListener('submit', calc, false); // HTMLに関数を書かない工夫

},false);</script>

<p> 再計算ボタンを押すと価格表が再計算されます。
<form name=casio>
<p>
<label><input type=radio name=nouki value="1" checked>通常配達</label>
<label><input type=radio name=nouki value="1.25">翌日配達</label>
<label><input type=radio name=nouki value="1.5">当日配達</label>
<button type=submit>再計算</button>
<div class=rateTable></div>
</form>
    • good
    • 0
この回答へのお礼

Ogre7077さんいつもありがとうございます!お返事遅くなりまして、申し訳ないです。
自分の今のレベルだとじっくりと読まないと理解できないところだと感じましたので、
まず先にお礼をさせて頂きます。

自分の調べた方法ではもっとごちゃごちゃとした感じの表が出来上がりそうだったのですが、自分で作っていたものよりはるかにスマートになっておりましたので、DOMの表作成についてはOgre7077さんのアンサーを参考にさせて頂きます。

皆さんのおかげで新しい知識を楽しく身につけることができました。
どうもありがとうございます。

お礼日時:2013/05/21 18:50

レスついているので書くまでもないんですけど、



制御構造が迂遠すぎ... こったアルゴリスム組みたいのなら他で何かで
(趣味で制御構造以外も変更しています)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitio …
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>innnerHTMLで自動生成された表を出力したい</title>
<style>

table{ border:none; font-size:12px;}
table thead tr th{ padding:5px; width:90px; background:#69F;}
table tr td{ padding:5px; text-align:right; background:#9CF;}
table tr th{ padding:5px; width:90px; background:#CCCCCC;}
caption { color: #900; caption-side: left; text-align: left; font-size:large;}

</style>
<script type="text/javascript">
//ラジオボタンのvalue値を取得
var daysRate;
var nouki = document.getElementsByName('nouki');
var price = new Array ( 10, 30, 50 );

function getRate() {
for ( var i = 0; i < nouki.length; i ++ ) {
if ( nouki[i].checked ) { daysRate = nouki[i].value;}
}
return parseFloat(daysRate);
}

function calc() {
// 選択されているレートを取得
var rate = getRate();
var list_name= new Array('表1','<h2>表2</h2>','<h2>表3</h2');
var table_start= "<div><table><caption>";
var table_head= '</caption><thead><tr><th>入数</th><th>ヘッダー1</th><th>ヘッダー2</th><th>ヘッダー3</th></tr></thead><tbody>';
var table_end= "</tbody></table></div><hr />";

var sss = table_start + list_name[0] + table_head;
for(var i=50; i<=100; i+=50){
sss += '<tr><th>' + i + '個</th>';
for ( var j = 0; j < price.length; j ++ ) {
sss += '<td>¥' + parseInt(price[j]*i) * rate + '</td>';
}
sss +='</tr>';
}
sss += table_end;
document.getElementById('priceTableOutput').innerHTML = sss;
}
window.onload = function() {
// 読込み後も一度テーブル表示を実行する
calc();
}
</script>
</head>
<body>
再計算ボタンを押すと価格表が再計算されます。<br />
<input type="radio" name="nouki" value="1" checked="checked" />通常配達
<input type="radio" name="nouki" value="1.25" />翌日配達
<input type="radio" name="nouki" value="1.5" />当日配達
<input type="button" value="再計算" onClick="calc()">
<div id="priceTableOutput">innerHTMLで、ここに表を出力</div>
<br />

</body>
</html>
    • good
    • 0
この回答へのお礼

zousan77さんありがとうございます。お返事が遅くなりました。

出力部分の記述がとてもスッキリしているので、規則性のあるテーブルの場合にすごく参考になります!
規則性のないテーブルの場合を考えてのifでの分岐だったので、その辺り記述しておらず申し訳ないです;

お礼日時:2013/05/21 18:27

回答はすでに出ているようですが…



内容的に選択肢が数種類程度と想像しますので、わざわざ(難しい?)計算をさせなくてもすむ方法としてこんなのはどうでしょうか。
単純に順番が同じものを表示しているだけなので、項目数が変わったり、選択内容によって行数が異なるような場合でもそのままで使えるのではないかと思います。

上述のように、順序だけを利用していますので、inputのvalue値は使用していませんし、スクリプトでの計算も不要になります。


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head><title>sample</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<style type="text/css">
table{ border:none; font-size:12px;}
table tr th{ padding:5px; width:90px; background:#69F;}
table tr td{ padding:5px; text-align:right; background:#9CF;}
</style>
</head>

<body>
<div id="hoge">
再計算ボタンを押すと価格表が再計算されます。<br>
<input type="radio" name="nouki" value="1" checked="checked">通常配達
<input type="radio" name="nouki" value="1.25">翌日配達
<input type="radio" name="nouki" value="1.5">当日配達
<input type="button" value="再計算" onClick="calc(this)">
</div>

<table id="fuga">
<thead>
<tr><th>入数</th><th>項目1</th><th>項目2</th></tr>
</thead>
<tbody>
<tr><th>50個</th><td>通常50-1</td><td>通常50-2</td></tr>
<tr><th>100個</th><td>通常100-1</td><td>通常100-2</td></tr>
</tbody>
<tbody>
<tr><th>50個</th><td>翌日50-1</td><td>翌日50-2</td></tr>
<tr><th>100個</th><td>翌日100-1</td><td>翌日100-2</td></tr>
</tbody>
<tbody>
<tr><th>50個</th><td>当日50-1</td><td>当日50-2</td></tr>
<tr><th>100個</th><td>当日100-2</td><td>当日100-2</td></tr>
</tbody>
</table>


<script type="text/javascript">
function calc(){
var i, j;
var elms = document.getElementById("hoge").getElementsByTagName("input");

for(i=0; i<elms.length-1; i++)
if(elms[i].type=="radio" && elms[i].checked) break;

elms = document.getElementById("fuga").getElementsByTagName("tbody");
for(j=0; j<elms.length; j++)
elms[j].style.display = i==j?"":"none";
}
calc();
</script>
</body>
</html>
    • good
    • 0
この回答へのお礼

fujillinさんありがとうございます。
こういうやり方もあるんですね。計算するまでもなく、規模の小さな表組みに使えそうなので、こちらも参考にさせていただきます。

どうもありがとうございます!

お礼日時:2013/05/21 17:34

変数 table_kosuu と table_td の編集方法と、innerHTML に設定するタイミングが間違っています。


直し方としては、以下をお勧めします。

var tableStart = "<table><thead><tr><th>あ<th>い<th>う";
var tableBody = "<tbody>";
var tableEnd = "</table>";
for (...) {
 tableBody += "<tr><td>個数の内容"; // table_kosuu と同じ
 for(...) {
  tableBody += "<td>金額の内容"; // table_td と同じ
 }
 // ここで設定しない
}
対象要素.innerHTML = tableStart + tableBody + tableEnd; // ループ後に設定


余談ではありますが、この様に少々面倒な生成を行うならば innerHTML ではなく DOM を利用することを検討なされてはいかがでしょうか。使い勝手が少々面倒ですが、XHTML 的に間違いのない生成が保障されていますので、結局は一番楽になると思います。
    • good
    • 0
この回答へのお礼

Ogre7077さん、今回もありがとうございます!
お礼が遅くなってしまい、申し訳ないです。

修正箇所の指摘を受け修正を行いalertでプログラムの動きを見たところ、問題なく生成されたのを確認できました。
DOMについても調べてみたところ、innerHTMLよりもDOMを使ったほうが良い場面も多いようでしたので、仰るとおりDOMでの生成にもチャレンジします。
ベストアンサーを差し上げたいところですが、また詰まることがあるかも知れませんので、DOMで作り終えるまでもう少し記事を閉じないでおこうと思います。

お礼日時:2013/05/19 02:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!