【jQuery】でテキストボックスに入力した値から自動計算する処理を書く！

本当はモダンなJsフレームワークを優雅に使いこなし、業務でゴリゴリ書きたい願望はあるが、結構なシステムでまだまだ現役でjQueryが使われている為、勉強がてらに記事を書きます

### 参考

【JavaScript】桁指定して四捨五入・切り上げ・切り捨て
>https://qiita.com/nagito25/items/0293bc317067d9e6c560

### 実現したい事

<img width="230" alt="テキストボックス.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428016/5fd8fb29-c33d-18d2-d69d-30de35cab1cb.png">

- テキストボックス3つあります。
- 一番上のテキストボックスに数字(半角数字)を入力すると、真ん中には「1000 / 入力した数字 」を計算した結果を表示
- 真ん中テキストボックス右の「/ ポイント」には 「(1000 / 入力した数字) / 20」を計算した結果を少数点第五位までを表示
- 一番下のテキストボックスには「入力した数字 * 10」を計算した結果を表示

### デモ

![demo](https://gyazo.com/c10da528cd9dbf631bc182f54da68170/raw)

### 実装方針

- フォーカスアウトでイベント発火させる
- 入力した値を取得する
- 入力した値を計算して変数に格納する
- 計算した結果をテキストボックスに表示させる

ざっくりだがこれで実装していきます


### 完成

```Js
## JS
function orgFloor(value, base) {
        return Math.floor(value * base) / base;
}

$(document).ready(function() {
	$("#first").focusout(function() {
	  var inputNumber = $("#first").val();
	  var resultDivision = 1000 / inputNumber; 
	  var point = resultDivision / 20;
	  var decimalPoint = orgFloor(point, 10000);
	  var multiplicationResult = inputNumber * 10;
	  var inputZeroForSecond = $("#second").val(0);
	  var inputZeroForPoint = $("#point").text(0);
	  var dataForLast = $("#last").val(multiplicationResult );

	  if (decimalPoint  == Infinity && resultDivision == Infinity) {
	    inputZeroForSecond;
	    inputZeroForPoint;
	    dataForLast;
	  } else if (decimalPoint == Infinity || resultDivision == Infinity){
	    inputZeroForSecond;
	    inputZeroForPoint;
	    dataForLast;
	  } else {
	    $("#point").text(decimalPoint );
	    $("#second").val(resultDivision);
	    dataForLast;
	  }
	})
});
```

```HTML
<table>
##HTML
##適当なHTMLなので悪しからず
  <tr>
    <td><input type="text" id="first"></td>
    <td><input type="text" id="second"> ##ここに表示
               <span> / </span>
               <div id="point"></div> ##ここに表示
               <span>ポイント</span> 
    </td>
    <td><input type="text" id="last">##ここに表示</td>
  </tr>
</table>
```

### 解説

1つずつ分けて説明します

#### まずは真ん中のテキストエリア(second)に計算結果を表示する

```Js
$(document).ready(function() {
	$("#first").focusout(function() {
	  var inputNumber = $("#first").val(); ## ①id=firstのセレクタの値をval()で取得し変数に格納
	  var resultDivision = 1000 / inputNumber;  ## ②1000を①で割り算
	  $("#second").val(resultDivision); ## ③id=secondのセレクタに表示
	})
});
```

#### 次はポイント(point)に計算結果を表示する

```Js
## 小数点第五位以下を四捨五入する関数
## 詳しくは参考記事
function orgFloor(value, base) {
　return Math.floor(value * base) / base; 
}

$(document).ready(function() {
　$("#first").focusout(function() {
　　var inputNumber = $("#first").val();
　　var resultDivision = 1000 / inputNumber;
　　var point = resultDivision / 20; ## ①resultDivisionを20で割った計算結果
　　var decimalPoint = orgFloor(point, 10000); ## ②onFloor関数を呼び出し。引数にpointと10000を渡す
	  
　　$("#point").text(decimalPoint ); ③ onFloor関数で小数点第五位まで丸めたデータを表示
　　$("#second").val(resultDivision);
　})
});
```

#### 次は一番下のテキストボックス(last)に計算結果を表示する

```Js
function orgFloor(value, base) {
        return Math.floor(value * base) / base; 
}

$(document).ready(function() {
　$("#first").focusout(function() {
　　var inputNumber = $("#first").val();
　　var resultDivision = 1000 / inputNumber;
　　var point = resultDivision / 20;
　　var decimalPoint = orgFloor(point, 10000);
　　var multiplicationResult = inputNumber * 10; ①inputNumberに10掛ける計算結果
	  
　　$("#point").text(decimalPoint );
　　$("#second").val(resultDivision);
　　$("#last").val(multiplicationResult ); ②id=lastのセレクタに①を表示
　})
});
```

これで想定する結果を得る事はできました
しかし、一番上のテキストボックスの入力した値を削除すると、

![demo](https://gyazo.com/6286fad7ccfb95b014f4f9fdc51877b1/raw)

これはJavaScriptで0除算を行うと結果がInfinityになります。
かっこ悪い。0除算した時には「0」がテキストボックスには入って欲しい

### 改修

もっとすっきりと書けると思うのだが、この方針しかパっと思いつかなかったです
- セレクタsecondとpointの両方がInfinityの場合 ⇒ 0を代入
- セレクタsecondもしくはpointがInfinityの場合 ⇒ 0を代入
- それ以外は計算結果を代入

```Js
function orgFloor(value, base) {
        return Math.floor(value * base) / base; 
}

$(document).ready(function() {
　$("#first").focusout(function() {
　　var inputNumber = $("#first").val();
　　var resultDivision = 1000 / inputNumber;
　　var point = resultDivision / 20;
　　var decimalPoint = orgFloor(point, 10000);
　　var multiplicationResult = inputNumber * 10;

　　if (decimalPoint  == Infinity && resultDivision == Infinity) {
　　　$("#point").text(0);
　　　$("#second").val(0);
　　　$("#last").val(multiplicationResult );

　　} else if (decimalPoint == Infinity || resultDivision == Infinity){
　　　$("#point").text(0);
　　　$("#second").val(0);
　　　$("#last").val(multiplicationResult );

　　} else {
　　　$("#point").text(decimalPoint );
　　　$("#second").val(resultDivision);
　　　$("#last").val(multiplicationResult );
　　}
　})
});
```

これでInfinityを回避できるようになりました
あとは条件分岐で繰り返し使っている箇所をまとめれば良いでしょう
以上で完成になります

### 課題

大文字数字を入力すると、

<img width="277" alt="NaN.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428016/c8251549-b235-b40a-6e05-52f502cfc96e.png">


非数を考慮していませんでした...
こいつを解消する方針としては、
- テキストボックスには半角数字しか認めない
- 大文字数字を入力した場合は半角数字に変換する

この処理を追加する必要がありそうです

駆け出しプログラマーの戦いは続く
to be continued...