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

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

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

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

Q&A

解決済

4回答

1132閲覧

JavaScriptでリアルタイム計算で入力値のチェックについて教えてください。

keykey

総合スコア6

JavaScript

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

0グッド

1クリップ

投稿2020/07/22 23:24

編集2020/07/23 00:50

前提・実現したいこと

リアルタイムに金利の計算をするプログラムの勉強をしているJS初心者です。
初めて投稿させていただきます。よろしくお願いいたします。

発生している問題

計算については正しく動作はしますが、入力した値の
チェックをしたいのですが、警告メッセージが表示されない状況です。

やりたいチェック機能
1. 4つの入力フィールドに値が入っていない場合にエラーを表示させたい。
2. cb_amount に   if(cb_amount <= ( amount - downpayment ) / 2 )
という条件をしたい。

該当のソースコード

JavaScript

1 2document.loanform.addEventListener('submit', function(e) { 3 document.getElementById('results').style.display = 'none'; 4 document.getElementById('loading').style.display = 'block'; 5 setTimeout(calculateResults, 100); 6 e.preventDefault(); 7}); 8

JavaScript

1 if(cb_amount <= ( amount - downpayment ) / 2 ){ 2 3 showError("Please check cb_amount "); 4 console.log("Error"); 5 //hide loader 6 document.getElementById("loading").style.display = "none"; 7 //show results 8 document.getElementById("results").style.display = "none"; 9 } 10

HTML

1  <form name="loanform"> 2 <div class="form-group"> 3 <div class="input-group"> 4 <span class="input-group-addon">amount</span> 5 <input class="form-control t_rlt" name="amount" placeholder="amount"> 6 </div> 7 </div> 8 9 <div class="form-group"> 10 <div class="input-group"> 11 <span class="input-group-addon">downpayment</span> 12 <input class="form-control t_rlt" name="downpayment" placeholder="downpayment"> 13 </div> 14 </div> 15 16 <div class="form-group"> 17 18 <div class="input-group"> 19 20 <span class="input-group-addon">combind bonus</span> 21 <input class="form-control t_rlt" name="cb_amount" placeholder="combind bonus"> 22 </div> 23 </div> 24 25 <div class="form-group"> 26 <select class="form-control" name="years" > 27 <option value="" selected>select payment yeart</option> 28 <option value="1" selected>1 year payment </option> 29 <option value="2" selected>2 year payment </option> 30 31 </select> 32 </div> 33 34 <div class="form-group"> 35 <input type="submit" value="submit" class="btn btn-dark btn-block"> 36 </div> 37</form> 38<div id="loading"> 39 <img src="img/loading.gif" alt="Loading"> 40</div> 41<div id="results" class="pt-4">          42

コード全体はこちらにおいています。

https://jsfiddle.net/diessses/qwkejm9p/1/

お手数おかけしますが、どこが問題かご教授いただけますでしょうか?
よろしくお願いいたします。

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

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

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

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

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

m.ts10806

2020/07/22 23:30 編集

HTMLも質問本文に追記してください。 ただ、ここ数日内で、似たような質問があったと思うのですけど、同じ人でしょうか。
keykey

2020/07/23 00:51

このサイトの利用は初めてになります。よろしくお願いいたします。 HTMLを追記しましたので、ご確認お願いいたします。
yambejp

2020/07/23 01:59

amount > downpayment という条件はいらないのでしょうか?
keykey

2020/07/23 03:27

ご回答ありがとうございます。すみません。はい。 cb_amount <= ( amount - downpayment ) / 2 の条件は入れたいです。よろしくお願いいたします。
guest

回答4

0

文字数オーバーだったためこちらに追記します。

で、ここからは改善案(好みの部分)です。

1.今nameで取得している項目をidに変更し、getElementByIdで取得します。
idで取得しているのとnameで取得しているのと混在しているため、私はid統一の方が好みです。

2.id値を一括管理
htmlのidに万が一変更があった場合、jsソースの変更箇所全てを変えないといけなくなってくるため
バグにつながりやすくなります。
idを一括管理することで、それをある程度防げます。(下のソースでは、downpayment, amount, cb_amountのみその対応を行っています。)

3.セレクトボックスの要素をjsで設定
要素をjsで設定することにより、要素の追加が発生した際の修正範囲を縮小できます。
今回は、HTMLの読み込みが完了したときにコンボボックス要素を設定する用にしてます。
要素の内容はオブジェクト内(下のソースですとyearsElement)に格納してあります。
また、選択地に応じて1, 1.5などの数値を取ってくると思うのですが、その際もswitchのcaseを追加する必要がなく、yearsElementの中から探して取ってきます。
(本来はこの辺のデータ管理はjson使う方がいいです。)

結果が下のソースです。
HTMLはidの追加とコンボボックス要素の削除、jsは上記の説明の修正と、submitを設定している箇所を少し実践向きに修正してます。(本来はsubmitではなくonslickの方がいいと思われますが、もともとsubmitで製造していたようなのでsubmitのままです。)

JS

1/** 2 * エレメントの属性値 3 */ 4var elementId = { 5 downpayment: "downpayment", // 頭金 6 amount: "amount", // 製品料金 7 cb_amount: "cb_amount", // ボーナス併用払い 8 years: "years" // yearsコンボボックス 9} 10 11/** 12 * yearsコンボボックス要素 13 */ 14var yearsElement = { 15 blank: { 16 value: "", 17 dispName: "select payment yeart", 18 intValue: 0, 19 interest: 0 20 }, 21 aa1: { 22 value: "aa1", 23 dispName: "1 year payment", 24 intValue: 1, 25 interest: 1.5 26 }, 27 bb2: { 28 value: "bb2", 29 dispName: "2 year payment", 30 intValue: 2, 31 interest: 2.5 32 } 33} 34 35/** 36 * DOMLoaded 37 */ 38document.addEventListener("DOMContentLoaded", function(e) { 39 40 // submit 41 document.loanform.addEventListener('submit', function(e) { 42 onSubmit(e); 43 }); 44 // yearsコンボボックス要素設定 45 setSelectboxValue(elementId.years, yearsElement); 46}, false) 47 48/** 49 * サブミットイベント 50 */ 51function onSubmit(e) { 52 // 入力チェック通過後、calculateResultsを実行する 53 if (checkValue()) { 54 // 活性制御 55 document.getElementById('results').style.display = 'none'; 56 document.getElementById('loading').style.display = 'block'; 57 58 // calculateResults実行 59 setTimeout(calculateResults, 3500); 60 } 61 e.preventDefault(); 62} 63 64/** 65 * セレクトボックス要素設定 66 * @param id セットするセレクトボックスのid 67 * @param object セットするオブジェクト 68 * セットするオブジェクトはkey.valueの形式であること 69 */ 70function setSelectboxValue(id, object) { 71 let selectBox = document.getElementById(id); 72 let loopCnt = 1; 73 74 // 要素数分ループ 75 Object.keys(object).forEach(function(key) { 76 let element = document.createElement("option"); 77 element.value = object[key].value; 78 element.innerHTML = object[key].dispName; 79 if (loopCnt == 1) { 80 element.selected = true; 81 } 82 selectBox.appendChild(element); 83 84 loopCnt++; 85 }); 86} 87 88/** 89 * 計算前チェック処理 90 * @return チェックOK:true, チェックNG:false 91 */ 92function checkValue() { 93 let rtn = true; // 返却用 94 95 let downpayment = document.getElementById(elementId.downpayment).value; // 頭金 96 let amount = document.getElementById(elementId.amount).value; // 製品料金 97 let cb_amount = document.getElementById(elementId.cb_amount).value; // ボーナス支払い金額 98 let selectedYears = document.getElementById(elementId.years).value; // yearsコンボボックス 99 // 必須チェック 100 if (!amount) { 101 102 // amountが未設定の場合エラー 103 showError("Please check amount"); 104 rtn = false; 105 106 } else if (!downpayment) { 107 108 // downpaymentが未設定の場合エラー 109 showError("Please check downpayment."); 110 rtn = false; 111 112 } else if (!cb_amount) { 113 114 // cb_amountが未設定の場合エラー 115 showError("Please check cb_amount."); 116 rtn = false; 117 118 } else if (!selectedYears) { 119 120 // yearsが未選択の場合エラー 121 showError("Please check selectbox of years."); 122 rtn = false; 123 124 } 125 126 // 必須チェックがtrueの場合、相関チェックを行う 127 if (rtn) { 128 129 if (cb_amount >= ( amount - downpayment ) / 2 ) { 130 131 // ボーナス併用払い金額 >= 商品代金と頭金の差額 / 2の場合エラー 132 showError("正しい金額を入力してください"); 133 rtn = false; 134 } 135 } 136 137 // チェック通過 138 return rtn; 139} 140 141/** 142 * 金利の算出 143 */ 144function calculateResults(e) { 145 let downpayment = document.getElementById(elementId.downpayment).value; // 頭金 146 let amount = document.getElementById(elementId.amount).value; // 製品料金 147 let cb_amount = document.getElementById(elementId.cb_amount).value; // ボーナス支払い金額 148 let years, interest; 149 150 // yearsコンボボックス内選択値に応じて、years, interestをENUMから設定 151 let selectedYears = document.getElementById(elementId.years).value; // yearsコンボボックス 152 years = yearsElement[selectedYears].intValue; 153 interest = yearsElement[selectedYears].interest; 154 155 // 算出 156 console.log('Calculating...'); 157 console.log('downpayment = ' + downpayment); 158 console.log('amount = ' + amount); 159 console.log('cb_amount = ' + cb_amount); 160 161 162 const difference = amount - downpayment; // 商品代金と頭金の差額 163 const cbTimes = years * 2; // ボーナス支払いの回数 164 const cbEveryPayment = cb_amount / cbTimes; // ボーナス一回あたりに支払う金額 165 const paymentTimes = years * 12; // 支払い回数(ボーナス除く) 166 const interestMod = 1 + (interest / 100); // 手を加えた金利を算出 167// const amountWithoutBns = difference * interestMod; 168 const totalPayment = (difference - cb_amount) * interestMod; // ボーナス支払い以外の支払金額を算出 169 const justDevideMonthlyPayment = totalPayment / paymentTimes; // ひと月辺りの支払額を一度算出 170 const secondToLastMonthlyPayment = (Math.floor(justDevideMonthlyPayment / 100) * 100); // 10円単位の切り捨て 171 const firstMonthlyPayment = totalPayment - (secondToLastMonthlyPayment * (paymentTimes - 1)); // 切り捨て額を1ヶ月目の支払額に集約 172 const totalInterest = (difference * interestMod) - difference; // 商品にかかる金利 173 174 175 // 各項目にセット 176 document.getElementById('monthly-payment1').value = comma(parseInt(firstMonthlyPayment)); 177 document.getElementById('monthly-payment2').value = comma(parseInt(secondToLastMonthlyPayment)); 178 document.getElementById('total-payment').value = comma(parseInt(interestMod)); 179 document.getElementById('total_interest').value = comma(parseInt(totalInterest)); 180 document.getElementById('showyears').value = years; 181 document.getElementById('showinterest').value = interest / 100; 182 document.getElementById('showdiffrence').value = comma(parseInt(difference)); 183 document.getElementById('cb_num').value = cbTimes; 184 document.getElementById('cb_input').value = comma(parseInt(cb_amount)); 185 document.getElementById('cb_everypayment').value = comma(parseInt(cbEveryPayment)); 186} 187 188/** 189 * 金額をカンマ編集する 190 * @param num 金額 191 * @return カンマ編集後の金額 192 */ 193function comma(num) { 194 return String(num).replace( /(\d)(?=(\d\d\d)+(?!\d))/g, '$1,'); 195} 196 197/* 198 * エラーハンドラ 199 */ 200 201// Error message 202function showError(error){ 203 console.log("Error ..." + error); 204 205 // create a div 206 const errorDiv = document.createElement("div"); 207 208 // get element 209 const card = document.querySelector(".card"); 210 const heading = document.querySelector(".heading"); 211 212 // add class 213 errorDiv.className = "alert alert-danger"; 214 215 // create text node and append div 216 errorDiv.appendChild(document.createTextNode(error)); 217 218 // Insert error above heading 219 card.insertBefore(errorDiv, heading); 220 221 // clear error after 3 secs. 222 setTimeout(clearError, 3000); 223} 224 225// clear error function 226function clearError() { 227 document.querySelector(".alert").remove(); 228}

一応動作環境が異なるので、不具合があればお伝えください。

その他の点として、

2.ユーザーによっては、cb_amount や downpayment は 0円 のときがあります。

つまり、何も入力しない。0円のときもありますが、計算は行えるようにしたいです。
3.計算後の出力は小数点切り捨てでOKです。計算中の小数点は無視をしてOKです。
4.ボーナス併用(cb_amount)に値が入力されたときの計算。
もし、cb_amountに値が入っていたときは、単純に、支払年数 * 2
で そのcb_amount を割った金額で支払をします。”これに金利はかかりません”なので、
cb_amount が入力されたときには、まず、この計算をして、その差額
を出してから、金利がかかる通常の計算を行う流れになります。

上記を含めておりません。
理由としては以下になります。
2.ユーザー情報との兼ね合いが分からなかったため。
3.こちらの環境ではsubmit後の表示が見れないので、対応できませんでした。
4.計算ロジックが複雑そうで、設計書等見ないと自分の頭では分からなかったです、、、。

以上ご確認をお願い致します。

投稿2020/07/26 03:04

編集2020/07/26 05:21
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

m.ts10806

2020/07/26 09:04

質問に対する回答ではなく作業依頼に対する作業請負になってませんか? そもそも文字数オーバーになるほどになる要件になるのがおかしいです。 あまり魚を与えすぎるのも(至れり尽くせりしすぎるのも)質問者の成長には繋がらないので程ほどにされたほうが良いかと思います。
退会済みユーザー

退会済みユーザー

2020/07/26 09:25

そうですね。 このサービスの意味合いが変わってきますね。すみません。 以後気をつけます。
guest

0

htmlソース掲載します。
一応変更箇所にコメントを記載しました。

HTML

1<!doctype html> 2<html lang="ja"> 3<head> 4 <!-- Required meta tags --> 5 <meta charset="utf-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 7 8 <!-- Bootstrap CSS --> 9 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous"> 10 <link rel="stylesheet" type="text/css" href="loan.css"> 11 12 <title></title> 13 <style> 14 #loading, #results { 15 display:none; 16 } 17 </style> 18 19 20</head> 21<body class="bg-dark"> 22 <div class="container"> 23 <div class="row"> 24 <div class="col-md-6 mx-auto"> 25 <div class="card card-body text-center mt-5"> 26 <h6 class="heading display-5 pb-3">loan calc</h6> 27 <form name="loanform"> 28 29 30 31 32 <div class="form-group"> 33 <div class="input-group"> 34 <span class="input-group-addon">amount</span> 35 <!-- id追加 --> 36 <input class="form-control t_rlt" id="amount" name="amount" placeholder="amount"> 37 </div> 38 </div> 39 40 <div class="form-group"> 41 <div class="input-group"> 42 <span class="input-group-addon">downpayment</span> 43 <!-- id追加 --> 44 <input class="form-control t_rlt" id="downpayment" name="downpayment" placeholder="downpayment"> 45 </div> 46 </div> 47 48 <div class="form-group"> 49 50 <div class="input-group"> 51 52 <span class="input-group-addon">combind bonus</span> 53 <!-- id追加 --> 54 <input class="form-control t_rlt" id="cb_amount" name="cb_amount" placeholder="combind bonus"> 55 </div> 56 </div> 57 58 <div class="form-group"> 59 <!-- id追加と要素の削除 --> 60 <select class="form-control" id="years" name="years"> 61 </select> 62 </div> 63 64 <div class="form-group"> 65 <input type="submit" value="submit" class="btn btn-dark btn-block"> 66 </div> 67 </form> 68 <div id="loading"> 69 <img src="img/loading.gif" alt="Loading"> 70 </div> 71 <div id="results" class="pt-4"> 72 <h5>result</h5> 73 74 <div class="form-group"> 75 <div class="input-group"> 76 <span class="input-group-addon">Years </span> 77 <input class="form-control t_rlt" id="showyears" disabled> 78 </div> 79 </div> 80 81 <div class="form-group"> 82 <div class="input-group"> 83 <span class="input-group-addon">Interest</span> 84 <input class="form-control t_rlt" id="showinterest" disabled> 85 </div> 86 </div> 87 88 89 <div class="form-group"> 90 <div class="input-group"> 91 <span class="input-group-addon">monthly payment</span> 92 <input class="form-control t_rlt" id="monthly-payment2" disabled> 93 </div> 94 </div> 95 <div class="form-group"> 96 <div class="input-group"> 97 <span class="input-group-addon">Fist month payment</span> 98 <input class="form-control t_rlt" id="monthly-payment1" disabled> 99 </div> 100 </div> 101 102 103 <div class="form-group"> 104 <div class="input-group"> 105 <span class="input-group-addon">Combined bonus</span> 106 <input class="form-control t_rlt" id="cb_input" disabled> 107 </div> 108 </div> 109 110 <div class="form-group"> 111 <div class="input-group"> 112 <span class="input-group-addon">Combined bonus paying times</span> 113 <input class="form-control t_rlt" id="cb_num" disabled> 114 </div> 115 </div> 116 117 <div class="form-group"> 118 <div class="input-group"> 119 <span class="input-group-addon">total bonus paying times</span> 120 <input class="form-control t_rlt" id="cb_everypayment" disabled> 121 </div> 122 </div> 123 124 125 <div class="form-group"> 126 <div class="input-group"> 127 <span class="input-group-addon">total - downpayment </span> 128 <input class="form-control t_rlt" id="showdiffrence" disabled> 129 </div> 130 </div> 131 132 <div class="form-group"> 133 <div class="input-group"> 134 <span class="input-group-addon">total payment</span> 135 <input class="form-control t_rlt" id="total-payment" disabled> 136 </div> 137 </div> 138 139 <div class="form-group"> 140 <div class="input-group"> 141 <span class="input-group-addon">total interest</span> 142 <input class="form-control t_rlt" id="total_interest" disabled> 143 144 </div> 145 </div> 146 </div> 147 </div> 148 </div> 149 </div> 150 </div> 151 152 153 <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> 154 <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script> 155 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script> 156 <script src="eng.js"></script> 157</body> 158 159</html>

投稿2020/07/26 08:30

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ベストアンサー

2020/7/26 修正

文字数オーバーだったので、書き直してます。
ソース修正しました。

まずyearsのセレクトボックスについて文字列も混在とのことですが、自分のソースのyearsEnumの値を対応するものに変えて頂ければ対応可能です。

/** * yaersコンボボックス要素 */ var yearsEnum = { "1": { valueInt: 1, interest: 1.5 }, "2": { valueInt: 2, interest: 2.5 }, } // サブミットイベント document.loanform.addEventListener('submit', function(e) { // 入力チェック通過後、calculateResultsを実行する if (checkValue()) { // 活性制御 document.getElementById('results').style.display = 'none'; document.getElementById('loading').style.display = 'block'; // calculateResults実行 setTimeout(calculateResults, 3500); } e.preventDefault(); }); /** * 計算前チェック処理 * @return チェックOK:true, チェックNG:false */ function checkValue() { let rtn = true; // 返却用 let downpayment = document.getElementsByName('downpayment')[0].value; // 頭金 let amount = document.getElementsByName('amount')[0].value; // 製品料金 let cb_amount = document.getElementsByName('cb_amount')[0].value; // ボーナス支払い金額 let selectedYears = document.loanform.years.value; // years // 必須チェック if (!amount) { // amountが未設定の場合エラー showError("Please check amount"); rtn = false; } else if (!downpayment) { // downpaymentが未設定の場合エラー showError("Please check downpayment."); rtn = false; } else if (!cb_amount) { // cb_amountが未設定の場合エラー showError("Please check cb_amount."); rtn = false; } else if (!selectedYears) { // yearsが未選択の場合エラー showError("Please check selectbox of years."); rtn = false; } // 必須チェックがtrueの場合、相関チェックを行う if (rtn) { if (cb_amount >= ( amount - downpayment ) / 2 ) { // ボーナス併用払い金額 >= 商品代金と頭金の差額 / 2の場合エラー showError("Please check cb_amount "); rtn = false; } } // チェック通過 return rtn; } /** * 金利の算出 */ function calculateResults(e) { let downpayment = document.getElementsByName('downpayment')[0].value; // 頭金 let amount = document.getElementsByName('amount')[0].value; // 製品料金 let cb_amount = document.getElementsByName('cb_amount')[0].value; // ボーナス支払い金額 let years, interest; // yearsコンボボックス内選択値に応じて、years, interestをENUMから設定 let selectedYears = document.loanform.years.value; years = yearsEnum[selectedYears].valueInt; interest = yearsEnum[selectedYears].interest; // 算出 console.log('Calculating...'); console.log('downpayment = ' + downpayment); console.log('amount = ' + amount); console.log('cb_amount = ' + cb_amount); const difference = amount - downpayment; // 商品代金と頭金の差額 const cbTimes = years * 2; // ボーナス支払いの回数 const cbEveryPayment = cb_amount / cbTimes; // ボーナス一回あたりに支払う金額 const paymentTimes = years * 12; // 支払い回数(ボーナス除く) const interestMod = 1 + (interest / 100); // 手を加えた金利を算出 // const amountWithoutBns = difference * interestMod; const totalPayment = (difference - cb_amount) * interestMod; // ボーナス支払い以外の支払金額を算出 const justDevideMonthlyPayment = totalPayment / paymentTimes; // ひと月辺りの支払額を一度算出 const secondToLastMonthlyPayment = (Math.floor(justDevideMonthlyPayment / 100) * 100); // 10円単位の切り捨て const firstMonthlyPayment = totalPayment - (secondToLastMonthlyPayment * (paymentTimes - 1)); // 切り捨て額を1ヶ月目の支払額に集約 const totalInterest = (difference * interestMod) - difference; // 商品にかかる金利 // 各項目にセット document.getElementById('monthly-payment1').value = comma(parseInt(firstMonthlyPayment)); document.getElementById('monthly-payment2').value = comma(parseInt(secondToLastMonthlyPayment)); document.getElementById('total-payment').value = comma(parseInt(interestMod)); document.getElementById('total_interest').value = comma(parseInt(totalInterest)); document.getElementById('showyears').value = years; document.getElementById('showinterest').value = interest / 100; document.getElementById('showdiffrence').value = comma(parseInt(difference)); document.getElementById('cb_num').value = cbTimes; document.getElementById('cb_input').value = comma(parseInt(cb_amount)); document.getElementById('cb_everypayment').value = comma(parseInt(cbEveryPayment)); } /** * 金額をカンマ編集する * @param num 金額 * @return カンマ編集後の金額 */ function comma(num) { return String(num).replace( /(\d)(?=(\d\d\d)+(?!\d))/g, '$1,'); } /* * エラーハンドラ */ // Error message function showError(error){ console.log("Error ..." + error); // create a div const errorDiv = document.createElement("div"); // get element const card = document.querySelector(".card"); const heading = document.querySelector(".heading"); // add class errorDiv.className = "alert alert-danger"; // create text node and append div errorDiv.appendChild(document.createTextNode(error)); // Insert error above heading card.insertBefore(errorDiv, heading); // clear error after 3 secs. setTimeout(clearError, 3000); } // clear error function function clearError() { document.querySelector(".alert").remove(); }

投稿2020/07/23 01:47

編集2020/07/26 03:04
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/07/23 01:50

すみません。 var checkValue = function() { } で記載してますが、calculateResults(e)に合わせるなら function checkValue() { } です。
keykey

2020/07/23 03:09

ご回答いただき誠にありがとうございます。初心者でして、ゆっくりと1つ1つ調べながら作業をしているので返信に時間がかかってしまいました。申し訳ございません。詳しくわかりやすくご回答いただき本当にありがたいです。いただいたコードを確認しながら組み込んでやっているのですが、私の追加に問題があるようで動作しない状況です。大変お手数ですが、問題になっている箇所を教えていただけますでしょうか。よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2020/07/23 07:40

申し訳ありません。 if文の中、正しく修正しました。(!が抜けてました。) これで動きませんか?
退会済みユーザー

退会済みユーザー

2020/07/23 08:23

動作検証しましたが、別の個所でエラーが発生しています。 ちょっと今時間がないためのちに原因調査修正して載せますが、コードを見てみると全体的にインデントのずれやコメントなどが不足していてソースが見づらいです。 インデントをきれいに記述するところが、まずエラー回避の第一歩だと思われます。 夜にまたエラー調査・修正して、ソース載せますね。
keykey

2020/07/23 10:47

お手間おかけしております。ご連絡誠にありがとうございます。初心者でして、読みにくいコードで申し訳ありません。アドバイスとても勉強になります。夜にまたご連絡いただけるということでありがたいです。どうぞよろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2020/07/23 11:55

遅くなってしまい申し訳ございません。 修正したソースを追記しましたので、ご確認をお願い致します。
keykey

2020/07/23 12:07

誠にありがとうございます!!度々お手間をおかけして申し訳ございません。 素人なので1つ1つ教えていただいた内容をしっかりと確認しながら理解が必要でして、少しお時間いただけますでしょうか。またご連絡させていただきます。
退会済みユーザー

退会済みユーザー

2020/07/23 12:11 編集

全然構わないですよー。 上から目線で失礼ですが、ちゃんと理解しながら書いているコードだなと感じました。 所々ミスはありますが、コメントがあれば普通のプログラマーのコードと差異はないと思います。 またご連絡ください。
keykey

2020/07/23 12:22

ありがとうございます。お言葉とてもうれしいです。励みになります!それではまたご連絡させていただきます。
退会済みユーザー

退会済みユーザー

2020/07/23 16:38

すみません言い忘れておりました。 直接コードと関係はないのですが、javascriptの少数の計算は精度が低いです。 勉強で上記コードを製造していると思われますが、お金に関するシステム開発では、実際の業務ではもう少し精度の高い方法を用いなければならないです。 もし自分で色々試しているうちに変な計算結果となった場合は、上記も頭に入れておいてください。
keykey

2020/07/24 04:08

すばらしいコード本当にありがとうございます。見ていてとても美しく1行1行勉強させてもらっております!昨晩から、1つ1つ確認をしながら学習しているのですが、いくつかお尋ねしたいことと私の最初の説明が不足していてところがありました。申し訳ございません!またご相談に乗っていただけますでしょうか? 1.チェック機能は最高でございます!たいへん勉強になりました。わかりやすくコメントをしていただいてコードを読んでいて楽しいです。 1つ疑問点があります。必須チェックは希望の動作をしているのですが、55行にある相関チェックの後に、計算がスタートできませんでした。どのような値をcb_amountに入れても計算が開始されない状況でした。 そして、私の最初の説明に不備があり、>と<が逆になっていました。申し訳ありません。 ここは以下のチェックにしようとしていますが、このように直しても計算が実行されませんでした。 if (cb_amount >= ( amount - downpayment ) / 2 ) { showError("cb_amount の値が不正です"); } 例として、以下のような値が入るとエラーにならず計算が行われるようになっています。 amount = 2000000 downpayment =200000 cb_amount = 600000 それからセレクトボックスの値について、申し訳ありません。訂正をさせてください。この度のご相談をする際に、皆様にわかりやすく完結に伝わるようにと以下のように書きました。 <option value="1" selected>1 year payment </option> <option value="2" selected>2 year payment </option> しかし、実際は <option value="bx1" selected>bx 1 year payment </option> <option value="ss2" selected>ss 2 year payment </option> というコードでして、valueは”数字だけでなく文字列も含まれます” そのために switch(document.loanform.years.value){ case "bx1": years = 1; interest = 1.5; break; case "ss2": years = 2; interest = 2.5; break; } という風にswitch文にしておりました。本当に申し訳ありません。 数値を見て処理をする、せっかく素晴らしいコードを作っていただいたのに、最初の説明が悪くご迷惑おかけしました。申し訳ありませんでした。 文字列を含むvalueの場合で、再度教えていただけますでしょうか。 とても親切に教えていただいて本当にありがとうございます。大変お手数おかけしますが、よろしくお願いいたします。
keykey

2020/07/24 04:24

お伝えし忘れました。少数の計算のアドバイスありがとうございます。そうなのですね!一応、テストは何度も繰り返しており正しい計算結果になっていることを確認しているのですが、そうなのですね。。。知りませんでした。注意してもう一度、計算方法を考え直します。
退会済みユーザー

退会済みユーザー

2020/07/24 16:10

お世話になっております。 コメント拝見致しました。 amount = 2000000 downpayment =200000 cb_amount = 600000 で正しく計算できるということですね。 こちらで今夜か明日に動作確認できる時に見てみます。 仕事で上記を行っていたら説明出来ないかもしれませんが、計算等について、やはりこちらとしては業務の内容を理解していないと、ソースの改良がしづらいです。 お伝え頂ける範囲で構わないので全体的な業務の処理の流れをご説明頂けないでしょうか? 例えばamountは○○と言う意味、 downpaymentは○○と言う意味、 cb_amountは○○と言う意味、 yearsのセレクトボックスは○○を年で○○した場合の〜を表している 計算部分は まず○○と○○をかけて☆☆を算出 それをyearsで選択された○○で〜〜する みたいな感じで 業務内容に関わってくるので、お伝えできる範囲で構いません。 すみませんが、よろしくお願いいたします。
keykey

2020/07/24 17:52

ご返信ありがとうございます。はい。喜んで内容を説明させていただきます。どうぞよろしくお願いいたします。 amount は商品の代金 downpayment は頭金 cb_amountは ボーナス併用払いです。 years は ’ローン会社’と、’支払回数’ ’金利’の3つの情報を 含んでおり、switichにしています。頭のアルファベットがローン会社 です。 計算の86行目から説明いたします。 86: 商品の代金から頭金を引いた数値を出します(difference 差額) 87: ボーナス併用(コンバインドボーナス amount)を何回で支払うか 支払回数(cbTimes)を算出します。yearsを選んだ段階で、 x2(ボーナスは年2回のため) years*2がその値になります。 88 :cbEveryPayment(ボーナス併用の一回あたりの支払額)は cb_amountで設定した金額 ÷ 87行で算出したcbTimes 89:通常のローンの支払回数(paymentTimes)= 年数 * 12 90: 手を加えた金利( interestMod )を算出します。たとえば interestが 2.5の場合は、2.5/100 をしてから 1を たします。つまり 1.025になります。これが、interestMod の値です。 91:amountWithoutBns は ボーナス払いを含めない、商品代金とその金利の合計を算出します。 92:totalPayment は 商品代金とその金利の合計を算出します (ボーナス併用分をのぞく) 93:”ここからの計算は特殊になります” 月々の支払金額は切りの良い金額にしたいので、十円単位をなくします。 この十円の金額はすべて一回目の支払に入れ込みます。そのため、まずは、totalPayment ÷ローンの支払回数で割って、1回あたりの支払い金額を”とりあえず”算出します。 94:次にそのとりあえず、算出した1回あたりの金額を100で割って、小数点以下を切り落とします。そして、100をかけることで、十円以下をなくします。これがつまり、二回目から最後までの月々の支払金額になります(secondToLastMonthlyPayment) 95:一回目の支払金額(firstMonthlyPayment)を算出します 2回目から最後までの回数、つまり (paymentTimes - 1) と secondToLastMonthlyPayment をかけて、それを totalPayment から マイナスすれば、初回の支払金額が算出されます。 96:totalInterest (商品にかかる金利)の計算になります。 いくつか、ルールがあります。 1. if (cb_amount >= ( amount - downpayment ) / 2 )について ボーナス併用の設定金額にはルールがあります。 商品代金(amount)から頭金(downpayment)を引いて、それを2で割った金額よりも高い数値をボーナス併用(cb_amount)に設定した場合、”正しい金額を入力してください ”のエラーを出します。 2.ユーザーによっては、cb_amount や downpayment は 0円 のときがあります。 つまり、何も入力しない。0円のときもありますが、計算は行えるようにしたいです。 3.計算後の出力は小数点切り捨てでOKです。計算中の小数点は無視をしてOKです。 4.ボーナス併用(cb_amount)に値が入力されたときの計算。 もし、cb_amountに値が入っていたときは、単純に、支払年数 * 2 で そのcb_amount を割った金額で支払をします。”これに金利はかかりません”なので、 cb_amount が入力されたときには、まず、この計算をして、その差額 を出してから、金利がかかる通常の計算を行う流れになります。 計算自体は、正しく間違いなくできています。 しかし、今気づきましたが、91行と92行は同じことを2度計算していますね^^; 例として、 以下の値を入力したときの、正しい計算の答えは こちらになります。 amount が 1400000 downpayment が 200000 combind bonus が 200000 yearsが 2years payment つまり case "2": years = 2; interest = 2.5; の場合、計算の結果は以下の通りです。 years が 2 Interest が  0.025 monthly payment が 42,700 Fist month payment が 42,899 Combined bonus が 200,000 Combined bonus paying times が 4 total bonus paying times が 50,000 total - downpayment  が 1,200,000 total payment が 1,230,000 以上、できる限り詳しく書きました。大変お手数おかけしますが、 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2020/07/25 00:11

詳しいご説明ありがとうございます。 非常に分かりやすいです。 エラー調査しやすくなりました。 また後ほど御報告させていただきますね。
退会済みユーザー

退会済みユーザー

2020/07/25 05:48

たびたびプログラムに関係のない質問で申し訳ないのですが、amountWithoutBnsとtotalPaymentの違いは何でしょうか?
退会済みユーザー

退会済みユーザー

2020/07/25 05:52

すみません。 相関チェックについては自分のバグでした。 rtn = false; がぬけてました。
keykey

2020/07/25 06:46

いつも見守っていただいてありがとうございます。 この説明でよかったでしょうか。お手数おかけしますが、 よろしくお願いいたします。 はい。amountWithoutBnsとtotalPayment は同じであり、意味がないですね(笑) 昨日、説明の文章を作っていて自分で気付きました。LOVE様に内容をお伝えする中で、あれもた足りなかった、これ足りなかったということで、追加でチェックしなければいけないことを思いつきお願いしてしまって申し訳ないです><LOVE様が作成された美しいコードを見たいので、申し訳ないですがもう少しお付き合いよろしくお願いいたします。
keykey

2020/07/25 06:49

2点、お尋ねします。本件とは関係のないことですが、LOVE様はどのコーディングソフトを利用されているのでしょうか?JS用に使いやすいソフトはあるのでしょうか? それから、LOVE様はTwitterなどはされていますか?どういうお方か知りたいので、質問させていただきました!
退会済みユーザー

退会済みユーザー

2020/07/25 10:13 編集

コーディングソフトは特に使用していませんよー EclipseっていうJava用に開発されたIDEです。 Windowsならやはり定番はVisualStudioではないでしょうか? 自分はjavaの勉強をしたりするので、Eclipseをよく使用しているためそっちを使ってますが。
keykey

2020/07/25 09:39

LOVE様、ご連絡ありがとうございます。Twitterありがとうございます。早速拝見させていただきます。私はtwitterをしていないのですが、LOVE様のページを拝ませていただこうと思います。 そうですか、Eclipseなのですね!ソフトのことも教えていただいてありがとうございます!
退会済みユーザー

退会済みユーザー

2020/07/25 10:15

私はあまりTwitterで発信をしないものですから…(こういう業界にいると、SNSとか怖いですよね(笑)) 遅くなってますが、ソース触ってます。 ちょっと食事などがあるため、今しばらくお待ちください。
keykey

2020/07/26 02:06

LOVE様 そうですか、お仕事の関係でSNSの裏側も見えてしまうんですね。誰というのが特定される可能性があると言いたいことも言いにくいですよね。 ゆっくりで結構ですので、楽しみに待っています!どうぞよろしくお願いいたします!
退会済みユーザー

退会済みユーザー

2020/07/26 03:05

修正したものと、自分の好みの書き方の両方をupしました。 お手数ですが、ご確認をお願い致します。
keykey

2020/07/26 04:48

LOVE様、すばらしいコードを考えていただいて本当にありがとうございます!!! いくつか、ご相談があります。”2020/7/26 修正 ”から始まるソースですが、セレクトボックスが空欄に表示される状況でした。 ”文字数オーバーだったためこちらに追記します。 ”から始まる、LOVE様が修正されたHTMLや、過去に私が投稿をしたHTMLを使用しているのですが、私の手順は合っていますでしょうか? なのでまだ、計算を試せていない状況です。お手数おかけいたしますが、教えていただけますでしょうか。 >自分の好みの書き方の両方をupしました。 とのことですが、jsコードも2つあるのでしょうか?こちらでは1つしか見えなかったです。
退会済みユーザー

退会済みユーザー

2020/07/26 05:22

すみません。お伝えし忘れておりました。 文字数オーバーだったため、先にHTMKのみ記載しました。 好みの~の方の回答をJSに差し替えたため、そちらも適用頂ければと思います。
退会済みユーザー

退会済みユーザー

2020/07/26 05:24

詳細を説明すると 2020/7/26 修正の回答:JSのみ変更 文字数オーバー~の回答:HTMLとJSの修正 です。
keykey

2020/07/26 05:47

LOVE様 お手数おかけして申し訳ありません。 文字数オーバーということで、LOVE様のすべてのコードが書きにくい状況なのだと推測いたします。 いただいたファイルを実行しますが、やはり、selectが出なかったり 計算がされなかったりします。 修正していただいたJSコードをどのHTMLに組み合わせるのか、 LOVE様がお考えになった新しいHTMLとどのJSのペアなのかわからなくなっておりまして。 なので、本件は一度、解決したということで、クローズとさせていただいて 、続きということで再度質問させていただこうと思うのですが、いかがでしょうか?
退会済みユーザー

退会済みユーザー

2020/07/26 05:51

もしかしたら、teratailの性質上あまり再度質問をするのは推奨されないと思うので、(基本的に疑問に対して答えるというシステムであり、全てのソースコードの掲載を行うことがあまりないため) 私のソースを適用したというソースこーどを、URLを貼っていただいたようにして見ることはできませんか?
退会済みユーザー

退会済みユーザー

2020/07/26 05:53

あとは環境が異なるので、DOMloadイベントが走らないなどの別の原因も考えられます。 私のソースコードが正しく適用されていればそちらが原因なので、別の方法取らせて頂きたいです。
keykey

2020/07/26 06:04

私は、ただ、HTMLファイルをブラウザ上(FIrefoxとChromeで試しました)にドラック&ドロップして実行をしています。その際に、HTMLファイルに <script src="eng.js"></script>のように書いてJSファイルを読み込んでいます。 jsfiddle上に、LOVE様から作っていただいた、2つのJSファイルを設置しました。 part1(修正のみ) https://jsfiddle.net/blueinkk/fht9kcms/2/ part2(LOVE様が進化させたコード) https://jsfiddle.net/blueinkk/Lwt5jqxc/2/ 以上になります。お手数おかけします。よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2020/07/26 08:11

回答に含め忘れていた(文字数オーバーでこちらに書こうとしていた内容)を追記します。 差分は今確認しておりますので、お待ちいただけますか。 その他の点として、 > 2.ユーザーによっては、cb_amount や downpayment は 0円 のときがあります。 つまり、何も入力しない。0円のときもありますが、計算は行えるようにしたいです。 3.計算後の出力は小数点切り捨てでOKです。計算中の小数点は無視をしてOKです。 4.ボーナス併用(cb_amount)に値が入力されたときの計算。 もし、cb_amountに値が入っていたときは、単純に、支払年数 * 2 で そのcb_amount を割った金額で支払をします。”これに金利はかかりません”なので、 cb_amount が入力されたときには、まず、この計算をして、その差額 を出してから、金利がかかる通常の計算を行う流れになります。 上記を含めておりません。 理由としては以下になります。 2.ユーザー情報との兼ね合いが分からなかったため。 3.こちらの環境ではsubmit後の表示が見れないので、対応できませんでした。 4.計算ロジックが複雑そうで、設計書等見ないと自分の頭では分からなかったです、、、。 以上ご確認をお願い致します。 1.今nameで取得している項目をidに変更し、getElementByIdで取得します。 idで取得しているのとnameで取得しているのと混在しているため、私はid統一の方が好みです。 2.id値を一括管理 htmlのidに万が一変更があった場合、jsソースの変更箇所全てを変えないといけなくなってくるため バグにつながりやすくなります。 idを一括管理することで、それをある程度防げます。(下のソースでは、downpayment, amount, cb_amountのみその対応を行っています。) 3.セレクトボックスの要素をjsで設定 要素をjsで設定することにより、要素の追加が発生した際の修正範囲を縮小できます。 今回は、HTMLの読み込みが完了したときにコンボボックス要素を設定する用にしてます。 要素の内容はオブジェクト内(下のソースですとyearsElement)に格納してあります。 また、選択地に応じて1, 1.5などの数値を取ってくると思うのですが、その際もswitchのcaseを追加する必要がなく、yearsElementの中から探して取ってきます。 (本来はこの辺のデータ管理はjson使う方がいいです。) HTMLはidの追加とコンボボックス要素の削除、jsは上記の説明の修正と、submitを設定している箇所を少し実践向きに修正してます。(本来はsubmitではなくonslickの方がいいと思われますが、もともとsubmitで製造していたようなのでsubmitのままです。)
退会済みユーザー

退会済みユーザー

2020/07/26 08:26 編集

差分を確認しました。 以下が原因だと思われます。 ・part1(修正のみ)の方 htmlのjs読み込みのファイル名がshinになってますが、正しいでしょうか? その他は大丈夫そうに見えます。 ・part2(LOVE様が進化させたコード) htmlのjs読み込みがそもそも行われていないようになってますが、正しいでしょうか? あと、htmlの方が自分の反映した内容が含まれていないです。 新たに回答をいたしますので、そちらを適用してください。 その他は大丈夫そうに見えます。 ですね。 htmlは<script src="eng.js"></script>が読み込まれたときにそのリソースを読み込むため、ブラウザで表示後に<script src="eng.js"></script>を追加しても、動かないと思われます。
guest

0

リアルタイムの意図がわかりませんが、inputイベントを拾えば
入力するごとに再計算されます

投稿2020/07/23 04:51

yambejp

総合スコア114850

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

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

keykey

2020/07/23 05:04

ご回答ありがとうございます。リアルタイムというのは意味不明でしたね。申し訳ありませんでした。一応、ただしく計算はできておりますが、入力チェックが動作しない状況でした。LOVE-KANON 様より 入力チェックの アンサーをいただきましたが、私の修正と追加に問題があるようで動作しない状況であります。。。 現在のコードはこちらです。 https://jsfiddle.net/blueinkk/6mfkxjud/1/
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問