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

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

ただいまの
回答率

87.92%

【jQuery】フォームで2種類の価格を振り分けて計算したい

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,065

score 12

前提・実現したいこと

メールフォームで商品の予約フォームを作っています。
サイズ違いで 2種類の価格があり、
商品の色ごとにそれぞれ注文できるフォームです。
色が違っても価格はサイズ共通です。

例)
色:赤  サイズ:S / L  数量:1〜4
色:青  サイズ:S / L  数量:1〜4
色:黄  サイズ:S / L  数量:1〜4
色:緑  サイズ:S / L  数量:1〜4
色:紫  サイズ:S / L  数量:1〜4
色:黒  サイズ:S / L  数量:1〜4

色はチェックボックスで選び、
サイズ、数量は、セレクトボックスで選ぶようにしています。

最終的に下記のように表示させたいです。
Sサイズ:合計▲▲枚 × 600円 = ▲,▲▲▲円
Lサイズ:合計▲▲枚 × 900円 = ▲,▲▲▲円
送料:500円
合計 ▲,▲▲▲円

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

商品の合計数と合計金額をサイズごとに集計して表示したいのですが、
Sサイズ / Lサイズ の金額の振り分けができません。

該当のソースコード

<label class="color">
  <input type="checkbox" name="color" value="color01 on" onclick="connecttext('size01',this.checked);"></label>
<select class="parent" id="size01" name="size01" disabled required>
  <option value="" class="msg" disabled selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="L">L:900円</option>
</select>
<select class="children" id="number01" name="number01" disabled required>
  <option value="0" class="msg" selected>0</option>
  <option value="1" data-val="S">1</option>
  <option value="2" data-val="S">2</option>
  <option value="3" data-val="S">3</option>
  <option value="4" data-val="S">4</option>
  <option value="1" data-val="L">1</option>
  <option value="2" data-val="L">2</option>
  <option value="3" data-val="L">3</option>
  <option value="4" data-val="L">4</option>
 </select>
<label class="color">
  <input type="checkbox" name="color" value="color01 on" onclick="connecttext('size02',this.checked);"></label>
<select class="parent" id="size02" name="size02" disabled required>
  <option value="" class="msg" disabled selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="L">L:900円</option>
</select>
<select class="children" id="number02" name="number02" disabled required>
  <option value="0" class="msg" selected>0</option>
  <option value="1" data-val="S">1</option>
  <option value="2" data-val="S">2</option>
  <option value="3" data-val="S">3</option>
  <option value="4" data-val="S">4</option>
  <option value="1" data-val="L">1</option>
  <option value="2" data-val="L">2</option>
  <option value="3" data-val="L">3</option>
  <option value="4" data-val="L">4</option>
</select>
(残り4種類同様です)
$(function() {
  //セレクトボックスが切り替わったら発動
  $('select#number').change(function() {

    //選択したvalue値を変数に格納
    var val = $(this).val();

    //選択したvalue値をp要素に出力
    $('p#fee').text(val);
  });
});
$(function() {
  var $children = $('.children');
  var original = $children.html();

  $('.parent').change(function() {
    var val1 = $(this).val();

    $children.html(original).find('option').each(function() {
      var val2 = $(this).data('val');
      if (val1 != val2) {
        $(this).not('optgroup,.msg').remove();
      }
    });

    if ($(this).val() === '') {
      $children.attr('disabled', 'disabled');
    } else {
      $children.removeAttr('disabled');
    }

  });
});
function connecttext( textid, ischecked ) {
   // チェック状態に合わせて有効・無効を切り替える
   document.getElementById(textid).disabled = !ischecked;
}
$("input[type=checkbox]").click(function(){
    var $count = $("input[type=checkbox]:checked").length;
    var $not = $('input[type=checkbox]').not(':checked')

        //チェックが3つ付いたら、チェックされてないチェックボックスにdisabledを加える
    if($count >= 10) {
        $not.attr("disabled",true);
    }else{
        //3つ以下ならisabledを外す
        $not.attr("disabled",false);
    }
});

試したこと

$(function(){
    var value = 900; 
    var maxNum = 4; 
    var tagInput = $('#number01'); 
    var tagOutput = $('#jsPrice'); 
    tagInput.on('change', function() {
        var str = $(this).val();

        if(num == 0) {
            num = '';
        } else if (num > maxNum) { 
            num = maxNum;
        }
        $(this).val(num);
        if(num != 0) {
            var price = num * value;
            tagOutput.val(price);
        }
    });
});

補足情報

色々と調べたのですが、
合計するだけならなんとか出来たのですが、
2種類の価格を振り分けて表示することがどうにもできません。
どなたか、ご教示のほど、お願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2018/12/25 14:06

    現在のJavaScriptコードをご提示ください。

    キャンセル

  • kei344

    2018/12/25 14:14

    コードブロックにはコード/エラーのみを入れるようにしてください。文章はコードブロック外にあるほうが読みやすいです。
    また、ご自身で試されたコードを質問文に追記し、「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを具体的に追記されたほうが回答が望めると思います。

    キャンセル

  • hit-machine

    2018/12/25 14:47

    mts10806 様、kei344 様、
    早速のご返答ありがとうございます。
    kei344 様のおっしゃる通りに書きたいのですが、
    コードに対してどう詰まってるかもよく分かっていない状況です。
    勉強不足でもうしわけございませんが、何卒よろしくお願い致します。

    キャンセル

回答 4

checkベストアンサー

+2

セレクトボックスの

  <option value="S">S:9,000円</option>
<option value="A">L:6,000円</option>

と、表示部分の

Sサイズ:合計▲▲枚 × 600円 = ▲,▲▲▲円
Lサイズ:合計▲▲枚 × 900円 = ▲,▲▲▲円

が、整合性が取れていないような気がしますがこんな感じで

<script>
$(function(){
  $('[name=color]').on('change',function(){
    $(this).closest('label').nextAll('.parent:eq(0),.children:eq(0)').prop('disabled',!$(this).prop('checked'));
  }).trigger('change');
  $(':checkbox,select').on('change click',function(){
    var souryo=500;
    var p_s=600;
    var p_l=900;
    var n_s=0;
    var n_l=0;
    $('.parent:not(:disabled):not(:has(option[value=""]:selected))').each(function(){
      if($(this).val()=="S") n_s+=parseInt($(this).next('.children').val());
      if($(this).val()=="A") n_l+=parseInt($(this).next('.children').val());
    });
    $('.s.maisu').text(n_s);
    $('.l.maisu').text(n_l);
    $('.s.kingaku').text(n_s*p_s);
    $('.l.kingaku').text(n_l*p_l);
    $('.all.kingaku').text(n_s*p_s+n_l*p_l+((n_s>0||n_l>0)?souryo:0));
  }).eq(0).trigger('change');
});
</script>
<label class="color"><input type="checkbox" name="color" value="color01"></label>
<select class="parent" name="size01">
  <option value="" class="msg" selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="A">L:900円</option>
</select>
<select class="children" name="number01">
  <option value="0" class="msg" selected>0</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
 </select><br>
<label class="color"><input type="checkbox" name="color" value="color02"></label>
<select class="parent" name="size02">
  <option value="" class="msg" selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="A">L:900円</option>
</select>
<select class="children" id="number02" name="number02">
  <option value="0" selected>0</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select><br>
<label class="color"><input type="checkbox" name="color" value="color03"></label>
<select class="parent" name="size02">
  <option value="" class="msg" selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="A">L:900円</option>
</select>
<select class="children" id="number02" name="number02">
  <option value="0" selected>0</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select><br>
<label class="color"><input type="checkbox" name="color" value="color04"></label>
<select class="parent" name="size02">
  <option value="" class="msg" selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="A">L:900円</option>
</select>
<select class="children" name="number02">
  <option value="0" selected>0</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select><br>
<label class="color"><input type="checkbox" name="color" value="color05"></label>
<select class="parent" name="size02">
  <option value="" class="msg" selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="A">L:900円</option>
</select>
<select class="children" name="number02">
  <option value="0" selected>0</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select><br>
<label class="color"><input type="checkbox" name="color" value="color06"></label>
<select class="parent" name="size02">
  <option value="" class="msg" selected>サイズを選択</option>
  <option value="S">S:600円</option>
  <option value="A">L:900円</option>
</select>
<select class="children" name="number02">
  <option value="0" selected>0</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>
<div id="result">
Sサイズ:合計<span class="s maisu">0</span>枚 × 600円 = <span class="s kingaku">0</span><br>
Lサイズ:合計<span class="l maisu">0</span>枚 × 900円 = <span class="l kingaku">0</span><br>
送料:500円<br>
合計:<span class="all kingaku">0</span></div>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/25 16:13

    ご回答ありがとうございます。
    実際に作っているフォームの内容をそのまま出せなかったので、
    ダミーで入れてたら、残ってしまっていました。
    ご指摘ありがとうございます。

    また、ご回答頂いた内容も試してみます。
    後ほどご報告させていただきます。

    キャンセル

  • 2018/12/25 16:45

    ありがとうございます!
    理想通りのものができそうです!
    ちなみに、1つに数まで選択した後、
    別の色でサイズを選択すると、それまでに選択した枚数が0に戻ってしまうのですが、
    全ての親子クラスに同じ.parent .children を使用してるからなのでしょうか?

    キャンセル

  • 2018/12/25 16:52

    >ちなみに、1つに数まで選択した後、
    >別の色でサイズを選択すると、それまでに選択した枚数が0に戻ってしまう

    あれ?そうですか?
    一応こちらではちょこちょこっと動作確認したんですけど
    ブラウザの種類とバージョンとOSはなんでしょう?

    キャンセル

  • 2018/12/25 17:07

    すみませんでした!前に書いていたjsのコードが残っていた様で、
    それを消したら大丈夫でした。
    お手数お掛けしました。
    そして、本当に助かりました!
    ありがとうございました!

    キャンセル

+1

data-valのSがSサイズ、AがLサイズってのでいいんですかね。
以下は動作確認していませんし、ちょっとイケてない書き方感ありますけど、
選択中項目に対して、val()での値取得と、data-valの値取得で振り分けすればいいのではないかという提案です。
※data-valの修正されたようなのでA→Lに変えました

var sizelistS = new Array();
var sizelistL = new Array();

//商品別の繰り返し開始
cost = $("#number02 option:selected").val();
size = $("#number02 option:selected").data("val");
if(size == 'S'){
    sizelistS.push(cost)
}else if(size == 'L'){
    sizelistL.push(cost)
}
//繰り返し終了

//合計値取得 ※reduceに馴染みなければforでもどうぞ
sumS = sizelistS.reduce((a,x) => a+=x,0);
sumL = sizelistL.reduce((a,x) => a+=x,0);

//あとはそれぞれの合計値を設定する

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/25 16:02

    ありがとうございます。
    試してみてまたコメントさせて頂きます。
    今のところ、合計値取得の部分の
    sumS = sizelistS の部分に、parenthesized pattern が表示されていて、
    何だか分からずに詰まっております。

    キャンセル

  • 2018/12/25 16:10 編集

    解析不能エラーですかね。正しくはParsing error: Parenthesized patternかな?
    自分もまだ勉強中のとこですので、解決策の提示ができないですね…。
    したいことは「配列内の合計値の取得」なので大人しくforで回したりする方がよいのかもしれません。
    解決にならなくて申し訳ない
    追記:
    他の方がされているように取得した個数は「文字列」なので、parseIntで「数値」にした方がよいですね。forやforeachで回したりして合計値を算出する時は変換入れて下さい。

    キャンセル

+1

金額の振り分け以前に $('.parent').change(function() {/* 略 */}); が正しく動作していないのでは? .parent が複数あり、.childrenも複数あるため、var original = $children.html();に最初の.childrenの内容しか入っていないのでは。

それぞれまとめてしまって、それをeachで処理するほうが良いのでは。

<div class="select-wrap">
<select class="parent"></select>
<select class="children"></select>
</div>
$( '.select-wrap' ).each( function() {
    var $parent = $( '.parent', this );
    var $children = $( '.children', this );
    /* 略 */
} );

【.each() | jQuery API Documentation】
https://api.jquery.com/each/

計算についても同じです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/25 15:59

    ご回答ありがとうございます。
    色もすべて表示させておかなければならないんです。
    仕様としては、
    「6色(実際はもっとあります)全て予約できるけど、サイズはどちらかしか選べない」
    というフォームにしたいです。

    キャンセル

  • 2018/12/25 16:03

    どちらにせよ最初のselect要素以外の書き換えに失敗していますよ、という回答です。

    キャンセル

+1

  var cnt = { "S": 0, "L": 0 };
  $('[name="color"]:checked').parent().find('+ select:not(:disabled) + select.children option[data-val]:selected').each(function(index, element) {
     cnt[$(element).attr('data-val')] += parseInt($(element).val(), 10);
  });
  console.log(cnt);

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/25 16:09

    質問は計算ということなので、インターフェースの制御バグについては考慮していません。

    キャンセル

  • 2018/12/25 16:15

    ご回答ありがとうございます。
    すみません、あまり知識がないもので、
    頂いた内容で出力しましたが、反映されませんでした。
    もう少し試してみます。

    キャンセル

  • 2018/12/26 15:02

    計算のみなので、画面への出力は自分で試してみてください

    キャンセル

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

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

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