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

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

ただいまの
回答率

88.92%

テーブルをループを使って表現したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,162

実現したいこと

今のコードだと長くなってしまいそうなので、javascriptでループさせて短くできないか、考えているのですが、なかなかできません。どうすればループをさせる形で表現できるでしょうか?
やりたいことは以下になります。

・テーブルをどんどん下のほうに追加したい
・チェックボックスのON/OFFでselectとinputを変えたい
・selectとinputで選択した値を足し算したい

Webコンテンツやり始めて2週間目。とんでもない初心者ですが、生暖かい目で指摘していただけると幸いです。

該当のソースコード

<table class="table table-striped">
    <thead>
        <tr>
            <th>項目1</th>
            <th class="col-md-1">自由入力<BR>(ON/OFF)</th>
            <th>金額</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>商品1</td>
            <td>            
                <div style="display:inline-flex">
                <form name="ckeckkakunin1" action="">
                    <input type="checkbox" id="chk1" name="chk1" onclick="chkdisp(this,'ans1','ans2')"  onChange="keisan()"/>
                </form>    
                </div>
            </td>
            <td>
                <form class="form-inline" id="ans2" name="selectkakunin1">
                    <div class="form-group">
                        <div class="input-group">
                            <div class="input-group-addon">&yen;</div>
                            <select class="form-control" id="usage1select2" name="selecttest1" onChange="keisan()">
                                <option selected disabled class="text-hide">100</option><option>0</option><option>50</option><option>100</option><option>500</option><option>1000</option><option>10000</option>
                            </select>
                        </div>
                    </div>
                </form>    
                <form class="form-inline" id="ans1" style="display:none;" name="freekakunin1">
                    <div class="form-group">
                        <div class="input-group">
                            <span class="input-group-addon">&yen;</span>
                            <input type="text" class="form-control" placeholder="200" onChange="keisan()" name="free1" />
                        </div>
                    </div>
                </form>

            </td>
        </tr>
        <tr>
            <td>商品2</td>
            <td>            
                <div style="display:inline-flex">
                <form name="ckeckkakunin2" action="">
                    <input type="checkbox" id="chk2" name="chk2" onclick="chkdisp(this,'ans3','ans4')"  onChange="keisan()"/>
                </form>    
                </div>
            </td>
            <td>
                <form class="form-inline" id="ans4" name="selectkakunin2">
                    <div class="form-group">
                        <div class="input-group">
                            <div class="input-group-addon">&yen;</div>
                            <select class="form-control" id="usage1select2" name="selecttest2" onChange="keisan()">
                                <option selected disabled class="text-hide">100</option><option>0</option><option>50</option><option>100</option><option>500</option><option>1000</option><option>10000</option>
                            </select>
                        </div>
                    </div>
                </form>    
                <form class="form-inline" id="ans3" style="display:none;" name="freekakunin2">
                    <div class="form-group">
                        <div class="input-group">
                            <span class="input-group-addon">&yen;</span>
                            <input type="text" class="form-control" placeholder="200" onChange="keisan()" name="free2" >
                        </div>
                    </div>
                </form>

            </td>
        </tr>
        <tr>
            <td>商品3</td>
            <td>            
                <div style="display:inline-flex">
                <form name="ckeckkakunin3" action="">
                    <input type="checkbox" id="chk3" name="chk3" onclick="chkdisp(this,'ans5','ans6')" onChange="keisan()"/>
                </form>    
                </div>
            </td>
            <td>
                <form class="form-inline" id="ans6" name="selectkakunin3">
                    <div class="form-group">
                        <div class="input-group">
                            <div class="input-group-addon">&yen;</div>
                            <select class="form-control" id="usage1select2" name="selecttest3" onChange="keisan()">
                                <option selected disabled class="text-hide">100</option><option>0</option><option>50</option><option>100</option><option>500</option><option>1000</option><option>10000</option>
                            </select>
                        </div>
                    </div>
                </form>    
                <form class="form-inline" id="ans5" style="display:none;" name="freekakunin3">
                    <div class="form-group">
                        <div class="input-group">
                            <span class="input-group-addon">&yen;</span>
                            <input type="text" class="form-control" placeholder="200" onChange="keisan()" name="free3" >
                        </div>
                    </div>
                </form>                
            </td>
        </tr>
    </tbody>    
</table>
<form action="#" name="form1">
    <tr>
        <td align="right"><strong>合計</strong></td>
        <td><input type="text" name="field_total" size="8" value="0"></td>
    </tr>
</form>
<script type="text/javascript">

function keisan(){
    check1 = document.ckeckkakunin1.chk1.checked;
    check2 = document.ckeckkakunin2.chk2.checked;
    check3 = document.ckeckkakunin3.chk3.checked;
    var price1 = document.selectkakunin1.selecttest1.value;
    var price2 = document.selectkakunin2.selecttest2.value;
    var price3 = document.selectkakunin3.selecttest3.value;

    if (check1 == true) {
        price1 = document.freekakunin1.free1.value;
        if (price1 == ""){
            price1 = 0;
        }else{

        }
    }else{
        price1 = document.selectkakunin1.selecttest1.value;
        if (price1 == ""){
            price1 = 100;
        }else{

        }
    }

    if (check2 == true) {
        price2 = document.freekakunin2.free2.value;
        if (price2 == ""){
            price2 = 0;
        }else{

        }
    }else{
        price2 = document.selectkakunin2.selecttest2.value;
        if (price2 == ""){
            price2 = 100;
        }else{

        }
    }

    if (check3 == true) {
        price3 = document.freekakunin3.free3.value;
        if (price3 == ""){
            price3 = 0;
        }else{

        }
    }else{
        price3 = document.selectkakunin3.selecttest3.value;
        if (price3 == ""){
            price3 = 100;
        }else{

        }
    }

    // 合計を計算
    var total = parseInt(price1) + parseInt(price2) + parseInt(price3);
    document.form1.field_total.value = total; // 合計を表示
    }

    window.onload=keisan();
</script> 

<script type="text/javascript">
function chkdisp( obj,id1,id2 ) {
    if( obj.checked ){
        document.getElementById(id1).style.display = "block";
        document.getElementById(id2).style.display = "none";
    }
    else {
        document.getElementById(id1).style.display = "none";
        document.getElementById(id2).style.display = "block";
    }
}
</script>

考察

<form name="ckeckkakunin?" action="">などを<table>の外側に移動して、for文を使うんだろうと思うもののうまくいかず悩んでいます。
宜しくお願いし致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2016/06/25 13:11

    「index」とありますが、「input」の間違いではないでしょうか。

    キャンセル

  • nakimushitomato

    2016/06/25 15:47

    ご指摘ありがとうございます。indexではなく、inputですね。失礼いたしました。

    キャンセル

回答 2

checkベストアンサー

+1

HTML/CSS/js全て書き直してみました。こういうことをしたいのでしょうか。
変わった書き方(?)で、コメントを付けない不親切なコードですが、こういう書き方も出来るということで。

動くサンプル:https://jsfiddle.net/wx9ba193/3/


少し気になった部分を列挙します。

  1. option要素に selected と disabled を設定されていますが、「選択(selected)しているのに選択できない(disabled)要素」は変ではないでしょうか。
  2. check1からcheck3までの変数がvarで宣言されていないのは付け忘れでしょうか。
  3. tr要素の親要素にform要素を使っている箇所がありますが、HTMLの文法的に間違っています。
    また、別ページへのPOST/GET通信を個別に行う必要が無ければinput/select要素をform要素で個別に囲う必要はありません。ページ内での計算のみであればform要素は無くてもよいです。
  4. parseInt()を使うときは第二引数(基数)まで指定した方がよいです。

【【JavaScript】parseInt()を使うときは第二引数まで指定した方がよい - 03LOG】
http://03log.me/blog/2014-06-11-js-parseint.html


以下参考URL:

【document.querySelector - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/Document/querySelector

【document.querySelectorAll - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/Document/querySelectorAll

【配列ライクなオブジェクトをforEachするときのイディオム - ぷちてく - Petittech】
http://ptech.g.hatena.ne.jp/noromanba/20120521/1337639496

【jQueryを使わずjavascriptだけで書き直した際の記法メモ - Qiita】
http://qiita.com/moriyaman/items/3b3f7878f8ecc2b76372

【window.onloadとjQueryの$(document).ready等の比較】
http://rcmdnk.github.io/blog/2015/07/11/computer-javascript-jquery/


追記:

一応どういう方針で書かれているかをざっくり書いておきます。

方針:

  1. チェックボックスと数値(select要素/input要素)の紐付けはid/nameではなく共通の親要素(tr要素)で行う
  2. 表示/非表示の切り替えは JavaScript で行うのではなく、親要素にクラスを付けることによってCSSで行う
  3. 計算はチェックボックスの状態を表している親要素のクラスと、それに紐付く数値(select要素/input要素)を一括で拾うことで処理する
  4. イベントは伝播(バブリング)するので、親要素(#calculator)で取得し、イベントが起きた要素(e.target)のクラスを見て処理を分岐する
  5. 項目の追加はチェックの付いていない1項目目を複製してtbodyに追加する
    ※ 「チェックの付いていない」という絞込みのため、全てチェックがあると失敗する。この限定をはずしたほうが良いとは思うがなんとなくそのままにした。
  6. 項目番号はCSSの連番付与で処理する

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/27 23:49

    大変親切にご回答いただきありがとうございます。3点目のご指摘など、まさに勉強不足の極み。。。(コメント有無は論外か。。。)
    今、記載頂いた参考URLをみております。一つ一つ紐解きながら精進させていただきます。

    ありがとうございました。

    キャンセル

  • 2016/06/28 00:24

    あと、「変わった書き方」という表現が身に染みますwww失礼しました

    キャンセル

  • 2016/06/28 00:34 編集

    あ、すいません、「コメントを付けない不親切なコード」と「変わった書き方」は自分のコードに対して書いたつもりでした。

    nakimushitomatoさんの書き方はJavaScriptの入門書などでよくある形なので「一般的」だと思います。

    キャンセル

0

for文で、idタグを連番指定して
.val()でidの値を取得します。

$('#取得したid').html(テーブル行) を追加していく。

どうでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/25 21:16

    ご回答ありがとうございます。ちょっと勉強して考えてみます。

    キャンセル

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

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る