🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
HTML5

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

JavaScript

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

2回答

2834閲覧

買い物カゴのSelectの表示と合計額の算出方法について

Nobu_Nobuta

総合スコア28

HTML5

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

JavaScript

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

1クリップ

投稿2019/10/05 23:48

下記htmlとJavaScriptコードにて、買い物カゴを作成しておりますが、
2点、分からないことがあります。

買い物カゴのイメージ

html

1<body> 2 3 <!-- ******* 商品メニュー始め ******* --> 4 <div class="contents"> 5 6 <div class="item-wrapper item-inner"> 7 <div class="item-left"> 8 </div> 9 <div class="item-right"> 10 <div class="item-name"> 11 <h3> 12 <a href="#" id="nameEver">????????エバーグリーン18</a> 13 </h3> 14 </div> 15 <div class="item-select"> 16 <select class="item" id="itemEver" tabindex="0"> 17 <option value="865" name="500g 865円" selected>500g 865円</option> 18 <option value="1638" name="1kg 1638円">1kg 1638円</option> 19 <option value="6915" name="5kg 6915円">5kg 6915円</option> 20 </select> 21 22 <label for="setEver"> X 23 <select class="set" id="setEver" tabindex="0"> 24 <option value="" selected>0</option> 25 <option value="1">1</option> 26 <option value="2">2</option> 27 <option value="3">3</option> 28 <option value="4">4</option> 29 <option value="5">5</option> 30 </select> 31 セット</label> 32 <button type="button" id="buyEver">カートに入れる</button> 33 </div> 34 </div> 35 </div> 36 37 <div class="item-wrapper item-inner"> 38 <div class="item-left"> 39 </div> 40 <div class="item-right"> 41 <div class="item-name"> 42 <h3> 43 <a href="#" id="nameWashed">????????トイ・スペシャル・ウォッシュド</a> 44 </h3> 45 </div> 46 <div class="item-select"> 47 <select class="item" id="itemWashed" tabindex="0"> 48 <option value="931" name="500g 931円" selected>500g 931円</option> 49 <option value="1764" name="1kg 1764円">1kg 1764円</option> 50 <option value="8035" name="5kg 8035円">5kg 8035円</option> 51 </select> 52 53 <label for="setWashed"> X 54 <select class="set" id="setWashed" tabindex="0"> 55 <option value="" selected>0</option> 56 <option value="1">1</option> 57 <option value="2">2</option> 58 <option value="3">3</option> 59 <option value="4">4</option> 60 <option value="5">5</option> 61 </select> 62 セット</label> 63 64 <button type="button" id="buyWashed">カートに入れる</button> 65 </div> 66 </div> 67 </div> 68 <!-- ******* 商品メニュー終り ******* --> 69 70 <!-- ******* 税別合計始め ******* --> 71 <div class="item-wrapper item-inner"> 72 <table class="cart" border="1" style="border-collapse: collapse"> 73 <thead> 74 <tr> 75 <th colspan="4">買い物カート</th> 76 </tr> 77 <tr> 78 <th>商品名・数量・単価</th> 79 <th>セット</th> 80 <th>小計</th> 81 <th>変更</th> 82 </tr> 83 </thead> 84 <tbody id="todoList"> 85 86 </tbody> 87 <tr> 88 <td colspan="2" class="text-right">税別合計</td> 89 <td class="total-box" id="exTax"></td> 90 <td></td> 91 </tr> 92 </table> 93 </div> 94 <!-- ******* 税別合計終り ******* --> 95 96 </div> 97 <script src="js/main1.js"></script> 98</body>

JavaScript

1'use strict'; { 2 3//○○○○○○○○○○○○○ カート始め ○○○○○○○○○○○○○ 4 5//***** 商品追加開始 ***** 6window.addEventListener('DOMContentLoaded', () => { 7 8 const buyEver = document.getElementById('buyEver'); 9 10 const buyWashed = document.getElementById('buyWashed'); 11 12 13 //***** エバーグリーン ***** 14 buyEver.addEventListener('click', () => { 15 16 const nameEver = document.getElementById('nameEver'); 17 const nameEverText = nameEver.text; 18 19 const itemEver = document.getElementById('itemEver'); 20 const itemEverName = itemEver.name; 21 console.log(itemEver.name); 22 const itemEverValue = itemEver.value; 23 24 //▲▲▲▲ tr エレメントを新規作成(ただ生成するだけ) ▲▲▲▲ 25 const taskElement = document.createElement('tr'); 26 27 28 //---- td 商品名エレメントを新規作成 ---- 29 const goodsElement = document.createElement('td'); 30 goodsElement.classList.add('goods'); 31 const setEver = document.getElementById('setEver'); 32 const setEverValue = setEver.value; 33 34 35 goodsElement.textContent = nameEverText; 36 37 //---- div 数量・単価エレメントを新規作成 ---- 38 const unitElement = document.createElement('div'); 39 unitElement.classList.add('unit'); 40 unitElement.textContent = itemEverName; 41 42 43 //---- td qtyエレメントを新規作成 ---- 44 const qtyElement = document.createElement('td'); 45 qtyElement.classList.add('qty'); 46 if (setEverValue == '') { 47 return false; 48 } else { 49 qtyElement.textContent = setEverValue; 50 } 51 52 //---- td subtotalエレメントを新規作成 ---- 53 const subTotalElement = document.createElement('td'); 54 subTotalElement.classList.add('total-box'); 55 56 const subTotalEver = itemEverValue * setEverValue; 57 58 subTotalElement.textContent = `${subTotalEver}`; 59 60 61 62 63 //---- td removeBtnエレメントを新規作成 ---- 64 const removeBtnElement = document.createElement('td'); 65 removeBtnElement.classList.add('amend'); 66 const removeBtn = createRemoveBtn(); 67 removeBtnElement.appendChild(removeBtn); 68 69 //生成したtrをtodolistにセット 70 todoList.appendChild(taskElement); 71 72 //生成したtdをtrにセット 73 taskElement.appendChild(goodsElement); 74 taskElement.appendChild(qtyElement); 75 taskElement.appendChild(subTotalElement); 76 taskElement.appendChild(removeBtnElement); 77 78 //生成したdivをtdにセット 79 goodsElement.appendChild(unitElement); 80 81 }); 82 83 //***** ウォッシュド ***** 84 buyWashed.addEventListener('click', () => { 85 86 const nameWashed = document.getElementById('nameWashed'); 87 const nameWashedText = nameWashed.text; 88 89 const itemWashed = document.getElementById('itemWashed'); 90 const itemWashedName = itemWashed.name; 91 const itemWashedValue = itemWashed.value; 92 93 //▲▲▲▲ tr エレメントを新規作成(ただ生成するだけ) ▲▲▲▲ 94 const taskElement = document.createElement('tr'); 95 96 97 //---- td 商品名エレメントを新規作成 ---- 98 const goodsElement = document.createElement('td'); 99 goodsElement.classList.add('goods'); 100 const setWashed = document.getElementById('setWashed'); 101 const setWashedValue = setWashed.value; 102 103 104 goodsElement.textContent = nameWashedText; 105 106 //---- div 数量・単価エレメントを新規作成 ---- 107 const unitElement = document.createElement('div'); 108 unitElement.classList.add('unit'); 109 unitElement.textContent = itemWashedName; 110 111 112 //---- td qtyエレメントを新規作成 ---- 113 const qtyElement = document.createElement('td'); 114 qtyElement.classList.add('qty'); 115 if (setWashedValue == '') { 116 return false; 117 } else { 118 qtyElement.textContent = setWashedValue; 119 } 120 121 //---- td subtotalエレメントを新規作成 ---- 122 const subTotalElement = document.createElement('td'); 123 subTotalElement.classList.add('total-box'); 124 125 const subTotalWashed = itemWashedValue * setWashedValue; 126 subTotalElement.textContent = `${subTotalWashed}`; 127 128 //---- td removeBtnエレメントを新規作成 ---- 129 const removeBtnElement = document.createElement('td'); 130 removeBtnElement.classList.add('amend'); 131 const removeBtn = createRemoveBtn(); 132 removeBtnElement.appendChild(removeBtn); 133 134 //生成したtrをtodolistにセット 135 todoList.appendChild(taskElement); 136 137 //生成したtdをtrにセット 138 taskElement.appendChild(goodsElement); 139 taskElement.appendChild(qtyElement); 140 taskElement.appendChild(subTotalElement); 141 taskElement.appendChild(removeBtnElement); 142 143 //生成したdivをtdにセット 144 goodsElement.appendChild(unitElement); 145 146 }); 147 148 149 //---------------------------------------- 150 // removeBtnを生成する関数 151 // [引数] 152 // なし 153 // [戻り値] 154 // removeBtn:タスクを削除するボタン 155 //---------------------------------------- 156 const createRemoveBtn = function() { 157 const removeBtn = document.createElement('button'); 158 removeBtn.textContent = `削除`; 159 160 //●●●● removeBtn押下時のイベントを追加 ●●●● 161 removeBtn.addEventListener('click', (e) => { 162 removeBtn.parentNode.parentNode.parentNode.removeChild(removeBtn.parentNode.parentNode); 163 }); 164 165 return removeBtn; 166 } 167 168 //***** 商品追加終了 ***** 169}); 170 171 172 //***** 税別合計始め ***** 173const exTax = document.getElementById('exTax'); 174 175let totalExTax = 0; 176 177exTax.textContent = `${totalExTax}`; 178 179//***** 税別合計終り ***** 180 181//○○○○○○○○○○○○○ カート終り ○○○○○○○○○○○○○ 182 183 // 'use strict'の終わり 184} 185

質問1:「カートに入れる」を発火点として、
addEventListener内で生成した下記2コードを税別合計に足しこみたいのですが
ローカルスコープからグローバルスコープに取り出す事が出来ず、合計額の算出方法が
分かりません。

   subTotalElement.textContent = ${subTotalEver}円;
subTotalElement.textContent = ${subTotalWashed}円;

質問2:下記のように、カートボタンを押すと押した商品名、セレクトで選択した内容を
表示したいです。

セレクトの内容

   方法として、htmlセレクトタグに
<option value="1638" name="1kg 1638円">1kg 1638円</option>
といった感じで、nameタグを振り、
const itemEver = document.getElementById('itemEver');
const itemEverName = itemEver.name;
として、コンソール表示してみたのですが、undefindでも、nullでもなく、空白でコンソール表示されてしまいます。
console.log(itemEverName);

  結果として、下記、divを生成しても未表示扱いとされてしまいます。

   //---- div 数量・単価エレメントを新規作成 ----
const unitElement = document.createElement('div');
unitElement.classList.add('unit');
unitElement.textContent = itemEverName;

2点、大変恐縮ですが、解決の為のアドバイスを頂ければ幸いです。

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

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

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

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

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

guest

回答2

0

ベストアンサー


質問1: (略)... ローカルスコープからグローバルスコープに取り出す事が出来ず、合計額の算出方法が分かりません。

関数にして、カートに追加の処理の最後に呼ぶようにしました。

★マークがついた部分が追加/変更した部分です

JavaScript

1let totalExTax = 0; // ★ ここはグローバルにした 2 3function addExTax(price) { // ★ これは関数にした 4 //***** 税別合計始め ***** 5 const exTax = document.getElementById('exTax'); 6 7 totalExTax += price; // ★ 合計に追加 8 9 exTax.textContent = `${totalExTax}`; 10 11 //***** 税別合計終り ***** 12 13 //○○○○○○○○○○○○○ カート終り ○○○○○○○○○○○○○ 14}

JavaScript

1 buyEver.addEventListener('click', () => { 2 ... 3 addExTax(subTotalEver); // ★ 最後の行に追加 4 });

JavaScript

1 buyWashed.addEventListener('click', () => { 2 ... 3 addExTax(subTotalWashed); // ★ 最後の行に追加 4 });

質問2:下記のように、カートボタンを押すと押した商品名、セレクトで選択した内容を

表示したいです。

→ ほかの方が既に答えていたので中断

投稿2019/10/06 01:02

編集2019/10/06 01:04
tanishi_a

総合スコア484

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

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

Nobu_Nobuta

2019/10/06 01:28

長文なコードにも関わらず、ご丁寧なご回答ありがとうございました。 後は、削除ボタンを押した時に合計額からマイナスする作業ですが、 頂いた関数を参考にして、何とかトライしてみたいと思います。
tanishi_a

2019/10/06 01:37

削除も考えるとすると、合計値でなく、一覧自体を外に出したほうがスッキリするかもしれません。 試してもないのですが、こんな感じです。 let items = {}; // 追加する関数内では items['商品名1'] = 123; // 削除する関数内では delete items['商品名1']; // 合計する関数内では let sum = 0 for (let [k, v] of Object.entries(items)) { sum += v }
Nobu_Nobuta

2019/10/06 01:56

アドバイスありがとうございます。 ご提示頂いた方法は、計算やappendChild、削除など、共通部分を一つの関数化して、商品のデータをそこに代入するという方法でしょうか? teratailで提示したコードは2( x セレクト3種)アイテム、ですが、実際はもう少しアイテム数あります。 同じ命令文で、id名が違うだけの、無駄に長いコードでスッキリさせたい とは思っているのですが、私のスキル不足で、それが出来ないでおります。 (例えば、'商品名1'に セレクト3種の選択情報と、セット数の選択情報の繁栄のさせ方が分からない。。。。)
tanishi_a

2019/10/06 02:10

> ご提示頂いた方法は、計算やappendChild、削除など、共通部分を一つの関数化して、商品のデータをそこに代入するという方法でしょうか? いいえ。 回答では、「合計値」だけをグローバルにしましたが、 コメントに書いたのは「商品一覧」自体をグローバルにしたほうが 追加/削除/合計 の計算がしやすいかな、という話です。 おっしゃるように共通部分を関数化は したほうが良いと思うので (気にはなっていましたが、質問と関係ないのでスルーしていました)、 次のようなステップでやってみてはどうでしょうか。 ステップ1. EventListener の中身 x2 を関数にする buyEver.addEventListener('click', () => { addCartEver(); }); buyWashed.addEventListener('click', () => { addCartWashed(); }); ステップ2. 関数2つの差になっている部分を引数に抜き出した版の関数を作る buyEver.addEventListener('click', () => { addCart('nameEver', 'itemEver', 'setEver'); }); buyWashed.addEventListener('click', () => { addCart('nameWashed', 'itemWashed', 'setWashed'); }); ステップ3. 削除とかの話はそのあとで
Nobu_Nobuta

2019/10/06 10:40

ご返信遅くなり申し訳ありません。 貴重なアドバイスありがとうございます。 私のスキル不足としている原因の一つに、引数の理解度が薄いというのがあります。 教科書のように、例えばlet name = "中田"とか分かりやすいものであれば良いですが、今回はそうではないので、ステップ2をどのように表現すれば良いか分かりません。 例えば今回のnameEverの場合、どのように抜き出しをすれば良いか教えて頂けると助かります。
tanishi_a

2019/10/06 10:50

次の ■1 から ■2 のように変更する、という意味ですよ。 こうすると関数は1つで、呼び出し側で、引数だけ変えればよくなります。 ■1. 引数なしの関数 function addCartEver() { const name = document.getElementById('nameEver'); const item = document.getElementById('itemEver'); ... } // 呼び出し addCartEver();   ↓ ■2. 引数ありの関数 function addCart(nameID, itemID) { const name = document.getElementById(nameID); const item = document.getElementById(itemID); ... } // 呼び出し addCart('nameEver', 'itemEver');
Nobu_Nobuta

2019/10/06 13:26

ご丁寧なご説明ありがとうございます。 おかげで、ステップ2をクリアする事が出来ました。
Nobu_Nobuta

2019/10/06 13:28

//○○○○○○○○○○○○○ カート始め ○○○○○○○○○○○○○ //***** 商品追加開始 ***** window.addEventListener('DOMContentLoaded', () => { const buyEver = document.getElementById('buyEver'); const buyWashed = document.getElementById('buyWashed'); //***** 商品追加関数始め ***** function addCart(nameID, itemID, setID) { const name = document.getElementById(nameID); const item = document.getElementById(itemID); const set = document.getElementById(setID); const nameText = name.text; const idx = item.selectedIndex; const itemName = item.options[idx].text; const itemValue = item.value; //▲▲▲▲ tr エレメントを新規作成(ただ生成するだけ) ▲▲▲▲ const taskElement = document.createElement('tr'); //---- td 商品名エレメントを新規作成 ---- const goodsElement = document.createElement('td'); goodsElement.classList.add('goods'); const setValue = set.value; goodsElement.textContent = nameText; //---- div 数量・単価エレメントを新規作成 ---- const unitElement = document.createElement('div'); unitElement.classList.add('unit'); unitElement.textContent = itemName; //---- td qtyエレメントを新規作成 ---- const qtyElement = document.createElement('td'); qtyElement.classList.add('qty'); if (setValue == '') { return false; } else { qtyElement.textContent = setValue; } //---- td subtotalエレメントを新規作成 ---- const subTotalElement = document.createElement('td'); subTotalElement.classList.add('total-box'); const subTotal = itemValue * setValue; subTotalElement.textContent = `${subTotal}円`; addExTax(subTotal); //---- td removeBtnエレメントを新規作成 ---- const removeBtnElement = document.createElement('td'); removeBtnElement.classList.add('amend'); const removeBtn = createRemoveBtn(); removeBtnElement.appendChild(removeBtn); //生成したtrをtodolistにセット todoList.appendChild(taskElement); //生成したtdをtrにセット taskElement.appendChild(goodsElement); taskElement.appendChild(qtyElement); taskElement.appendChild(subTotalElement); taskElement.appendChild(removeBtnElement); //生成したdivをtdにセット goodsElement.appendChild(unitElement); //***** 商品追加関数終り ***** } //***** エバーグリーン ***** buyEver.addEventListener('click', () => { addCart('nameEver', 'itemEver', 'setEver'); }); //***** ウォッシュド ***** buyWashed.addEventListener('click', () => { addCart('nameWashed', 'itemWashed', 'setWashed'); }); //---------------------------------------- // removeBtnを生成する関数 // [引数] // なし // [戻り値] // removeBtn:タスクを削除するボタン //---------------------------------------- const createRemoveBtn = function() { const removeBtn = document.createElement('button'); removeBtn.textContent = `削除`; //●●●● removeBtn押下時のイベントを追加 ●●●● removeBtn.addEventListener('click', (e) => { removeBtn.parentNode.parentNode.parentNode.removeChild(removeBtn.parentNode.parentNode); }); return removeBtn; } //***** 商品追加終了 ***** }); //***** 税別合計始め ***** let totalExTax = 0; function addExTax(price) { const exTax = document.getElementById('exTax'); totalExTax += price; exTax.textContent = `${totalExTax}円`; } //***** 税別合計終り ***** //○○○○○○○○○○○○○ カート終り ○○○○○○○○○○○○○
tanishi_a

2019/10/06 13:39

進んだようで良かったです。 続きの問題おきたら新規の質問ですかね。
Nobu_Nobuta

2019/10/06 14:14

Teratailのルールとしては、新規スレッドを立てた方が良いでしょうか。 削除ボタンを押した時にマイナスする関数が分からなかった時は、 またご相談させて下さい。
tanishi_a

2019/10/06 14:16

もとの質問と異なる内容なのだから、 分けたほうが答えが得られやすいと思いますよ。
Nobu_Nobuta

2019/10/06 14:18

ご指導ありがとうございます。 そのように致します。
guest

0

質問1について、
やりかたはいくつかあると思いますが、小計額を求めたタイミングで関数を呼び出すのはどうでしょうか。

javascript

1subTotalElement.textContent = ${subTotalEver}; 2addTotal(subTotalEver); 3 4subTotalElement.textContent = ${subTotalWashed}; 5addTotal(subTotalWashed); 6 7 8function addTotal(subTotal) { 9 const exTax = document.getElementById('exTax'); 10 const total = Number(exTax.textContent.replace('円', '')); 11 const totalExTax = total + subTotal; 12 exTax.textContent = `${totalExTax}`; 13}

質問2について、
optionタグにname属性はつけません。
セレクトボックスに表示されているラベルをそのまま取得することができます。

javascript

1const itemEver = document.getElementById('itemEver'); 2const idx = itemEver.selectedIndex; //追加 3//const itemEverName = itemEver.name; //削除 4const itemEverName = itemEver.options[idx].text; //追加 5//console.log(itemEver.name); //削除 6console.log(itemEver); //追加 7const itemEverValue = itemEver.value; 8 9

投稿2019/10/06 00:49

編集2019/10/06 01:02
syachiku

総合スコア117

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

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

Nobu_Nobuta

2019/10/06 01:27

長文なコードにも関わらず、ご丁寧なご回答ありがとうございました。 何日も悩んでいたのですが、おかげでスッキリしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問