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

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

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

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

JavaScript

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

Q&A

解決済

4回答

2091閲覧

JavaSprictで入力フォームに入力した値を自動計算して表示させたい

sundara.

総合スコア5

HTML5

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

JavaScript

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

0グッド

0クリップ

投稿2020/09/23 14:03

編集2020/09/23 17:03

入力フォームに数値を入力したものを三桁でカンマ区切り、全角数値を半角に変換、入力した値同士で足し算した合計のものを表示、数値以外は表示させないことを実装したいのですが、合計金額の表示が上手くいきません。三桁までの数字は上手く足されるのでカンマ区切りの処理が邪魔をしているみたいです……

html

1 //数値を入力するフォーム 2 <input class="money1 js-money" style="width:100%; box-sizing:border-box" name="money1"> 3 <input class="money2 js-money" style="width:100%; box-sizing:border-box" name="money2"> 4 <input class="money3 js-money" style="width:100%; box-sizing:border-box" name="money3"> 5 6 //合計金額を表示させる場所 7 <span class="total-money"></span>

JavaScript

1//文字列にカンマを追加 2function addComma(val) { 3 return val.replace( /(\d)(?=(\d\d\d)+(?!\d))/g, '$1,'); 4} 5 6//文字列からカンマを除去 7function deleteComma(val) { 8 return val.replace(/,/g, ''); 9} 10 11document.addEventListener( 'DOMContentLoaded', () => { 12 document.querySelectorAll('.js-money').forEach((el) => { 13 14 /***** フォームに入力された数値を集計し、表示する *****/ 15 el.addEventListener('change', (e) => { 16 17 /***** フォームがフォーカスされた時にカンマを除去 *****/ 18 el.addEventListener('focus', (e) => { 19 const val = e.target.value; 20 e.target.value = deleteComma(val); 21 }); 22 23 /***** フォームからフォーカスが外れた時にカンマを表示 *****/ 24 el.addEventListener('blur', (e) => { 25 const val = e.target.value; 26 e.target.value = addComma(val);0 27 }); 28 29 //0以上の整数、半角と全角の数字以外が入力されたら、フォームを初期化する 30 let inputVal = e.target.value; 31 const pattern = /^([0-90-9]*|0)$/; 32 if(!pattern.test(inputVal)){ 33 e.target.value = ""; 34 inputVal = ""; 35 } 36 37 //全角数字を半角数字に変換 38 e.target.value = inputVal.replace(/[0-9]/g,(s) => { 39 return String.fromCharCode(s.charCodeAt(0) - 0xFEE0); 40 }); 41 42 //合計金額の表示 43 let money1 = 0; 44 if(document.querySelector('.money1').value){ 45 money1 = parseInt(document.querySelector('.money1').value); 46 } 47 let money2 = 0; 48 if(document.querySelector('.money2').value){ 49 money2 = parseInt(document.querySelector('.money2').value); 50 } 51 let money3 = 0; 52 if(document.querySelector('.money3').value){ 53 money3 = parseInt(document.querySelector('.money3').value); 54 } 55 56 let totle = money1 + money2 + money3; 57 58 let money_sum = document.querySelector('.total-money'); 59 money_sum.innerHTML = totle +"円"; 60 61 }); 62 63 }); 64 65});

上記のフォームに入力を行うと三桁のカンマ区切り、数値以外は入力しない、全角数値を半角に変換は上手くいきます。
spanタグに合計数値を表示するときに三桁以上入力すると変な表示になってしまいます。

入力例:
inputタグのclass="money1”~class="money3"に11,111と入力すると合計が表示されるspanタグ部分には11133と表示されてしまいます。
また、let totle = money1 + money2 + money3;時点でconsole.log(totle)とするとspanタグ表示される変な値と同じ表示になります。

console.logにて値がおかしくなる所を探したところ次のようなことが判明しました。
↓↓↓
class="money1"に11111を入力→console.log(money1)でコンソールに11111と表示。
続けてclass="money2"に11111を入力→console.log(money1)でコンソールに11と表示,console.log(money2)でコンソールに11111と表示。
続けてclass="money3"に11111を入力→console.log(money1)でコンソールに11と表示,console.log(money2)でコンソールに11と表示,console.log(money3)でコンソールに11111と表示。

このことからinputに値を入力した時点では数値として代入されるが、
他のinputに値を代入した時(イベント発生時)にはカンマを含むため文字列に反映されるのかなと思います。
試しにcosole.log(parseInt(111,111))とやってみたら111と表示されました。

↓のJSコードを取り除いた状態で入力すると上手くいきます。
ですが、カンマ区切りがなくなります…あちらがたてばこちらが立たず状態です。

JavaScript

1//文字列にカンマを追加 2function addComma(val) { 3 return val.replace( /(\d)(?=(\d\d\d)+(?!\d))/g, '$1,'); 4} 5 6//文字列からカンマを除去 7function deleteComma(val) { 8 return val.replace(/,/g, ''); 9}

カンマ区切りとしつつ、数値を合計させるいい方法があればご教授いただきたいです。

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

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

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

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

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

AkitoshiManabe

2020/09/24 06:18 編集

> カンマ区切りがなくなります…あちらがたてばこちらが立たず状態 ソースを読むと「入力フィールドにフォーカスしているときはカンマ区切りなし。そうでないときはコンマ区切りで表示」という実装目標が感じられますが、そうであればご質問内に明文化したほうが良いと思います。 ※タイトルの「自動計算して表示」だけであれば、回答は出ています。
guest

回答4

0

自己解決

Jon_doさんのコード内のNumber(money[0].value.replace(/,/g, ""))を参考にコードを修正したら上手くいきました!

//合計金額の表示(編集前) let money1 = 0; if(document.querySelector('.money1').value){ money1 = parseInt(document.querySelector('.money1').value); } let money2 = 0; if(document.querySelector('.money2').value){ money2 = parseInt(document.querySelector('.money2').value); } let money3 = 0; if(document.querySelector('.money3').value){ money3 = parseInt(document.querySelector('.money3').value); } //合計金額の表示(編集後.replace(/,/g, "")の処理を追加) let money1 = 0; if(document.querySelector('.money1').value){ money1 = parseInt(document.querySelector('.money1').value.replace(/,/g, "")); } let money2 = 0; if(document.querySelector('.money2').value){ money2 = parseInt(document.querySelector('.money2').value.replace(/,/g, "")); } let money3 = 0; if(document.querySelector('.money3').value){ money3 = parseInt(document.querySelector('.money3').value.replace(/,/g, "")); }

投稿2020/09/26 04:35

sundara.

総合スコア5

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

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

0

いい方法

HTML上に表示する数字(string)と、四則演算等の伴う数値(number)をしっかりと捉えます。
※数値(number) <=> 数字(string) を混同してしまう場合
「混乱を避けるためにユーザ関数でイベントリスナ内のコードを簡素化する」のが良い方法と言えそうです。


ご質問のコードで気づいた点は、 change イベントのリスナ内で、focus / blur を 繰り返し addEventListener でリスナを多重登録をしている点です。

投稿2020/09/24 07:30

AkitoshiManabe

総合スコア5434

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

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

0

元のソースを読み解くのは難しそうだったので自作してみました。
参考までにどうぞ。
下記コードはコピペすると動作します。

HTML

1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8</head> 9 10<body> 11 <input class="money1 js-money" style="width:100%; box-sizing:border-box" name="money1" autocomplete="off"> 12 <input class="money2 js-money" style="width:100%; box-sizing:border-box" name="money2" autocomplete="off"> 13 <input class="money3 js-money" style="width:100%; box-sizing:border-box" name="money3" autocomplete="off"> 14 <span class="total-money"></span> 15 <script> 16 17 const money = document.getElementsByClassName("js-money"); 18 const total = document.getElementsByClassName("total-money")[0]; 19 20 for (let i = 0; i < 3; i++) { 21 money[i].addEventListener("input", () => { 22 // 0~9 0~9以外の入力は受け付けない + 数値をカンマ表記に 23 money[i].value = Number(changeHalfWidth(money[i].value.replace(/[^0-90-9]/g, ""))).toLocaleString(); 24 // money1 + money2 + money3 25 const add = Number(money[0].value.replace(/,/g, "")) + Number(money[1].value.replace(/,/g, "")) + Number(money[2].value.replace(/,/g, "")); 26 // totalの数値をカンマ表記にして円を語尾に付加 27 total.innerText = add.toLocaleString() + "円"; 28 // 0のみの場合 何も表示しない 29 if (money[i].value === "0") money[i].value = ""; 30 // 0 円の場合何も表示しない 31 if (add === 0) total.innerText = ""; 32 }); 33 } 34 35 // 全角数字を半角に 36 const changeHalfWidth = (num) => { 37 const changeNum = num.replace(/[0-9]/g, (s) => { return String.fromCharCode(s.charCodeAt(0) - 0xFEE0) }); 38 return changeNum; 39 } 40 41 </script> 42</body> 43 44</html>

投稿2020/09/24 03:03

Jon_do

総合スコア1373

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

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

0

let totle = money1 + money2 + money3;
の段階では、totalは正しい数値となっていますでしょうか?
debugでどのタイミングでおかしくなっているか、確認してみてください。

投稿2020/09/23 14:34

Kaiser

総合スコア295

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

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

Hogeike

2020/09/24 00:29 編集

そういうのは修正依頼に書いた方が良いと思います。回答になっていません
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問