ミギムキ

[JavaScript] 計算コンテンツ用の雛形テンプレート

ウェブサイト上に簡易な計算コンテンツを設置する際のテンプレートを検討してみました。

サンプルコード

html

<div class="calculator"> <dl class="calculator_input"> <dt>上底</dt> <dd><input type="text" id="joutei"></dd> <dt>下底</dt> <dd><input type="text" id="katei"></dd> <dt>高さ</dt> <dd><input type="text" id="takasa"></dd> </dl> <div class="calculator_action"> <button class="calculator_action_reset">リセット</button> <button class="calculator_action_calc">計算</button> </div> <dl class="calculator_result"> <dt>計算結果</dt> <dd></dd> </dl> </div>

入力項目や計算の実行ボタン、入力内容のリセットボタンを配置するhtmlです。

各入力項目のinputタグには「takasa」などの固有のidを設定しています。後述するJavaScriptの処理で、このidを使用して入力項目の値を参照します。

CSS

.calculator { margin: 0px auto; max-width: 600px; } .calculator * { box-sizing: border-box; } .calculator_input { display: flex; align-items: center; flex-wrap: wrap; margin: 0px; } .calculator_input dt, .calculator_input dd { margin: 20px 0px 0px; } .calculator_input dt { width: 60%; } .calculator_input dd { width: 40%; } .calculator_input input { padding: 1em; text-align: center; } .calculator_input input { width: 100%; } .calculator_action { display: flex; justify-content: space-around; align-items: center; margin-top: 20px; } .calculator_action button { padding: 1em; width: 40%; border: none; outline: none; border-radius: 10px; background-color: #000; color: #fff; appearance: none; cursor: pointer; } .calculator_result { display: flex; align-items: center; flex-wrap: wrap; margin: 0px; border-bottom: 1px solid #000; } .calculator_result dt, .calculator_result dd { margin: 0px; } .calculator_result dt { width: 60%; } .calculator_result dd { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; width: 40%; height: 3em; font-size: 2em; text-align: center; }

JavaScript

document.addEventListener('DOMContentLoaded', function() { const calculator = document.querySelector('.calculator'); const inputItems = calculator.querySelectorAll('.calculator_input input'); for(let i = 0; i < inputItems.length; i++) { inputItems[i].addEventListener('change', correctInput); } const resultItem = calculator.querySelector('.calculator_result dd'); calculator.querySelector('.calculator_action_calc').addEventListener('click', calcInput); calculator.querySelector('.calculator_action_reset').addEventListener('click', resetAll); const inputValues = new Array(); function updateInputValues() { for(let i = 0; i < inputItems.length; i++) { inputValues[inputItems[i].getAttribute('id')] = parseFloat(inputItems[i].value); } } function resetAll() { for(let i = 0; i < inputItems.length; i++) { inputItems[i].value = ''; } resultItem.textContent = ''; updateInputValues(); } function correctInput(event) { const inputValue = event.target.value; // 数字と小数点以外の文字を削除 const valueNumber = inputValue.replace(/[^0-9.0-9.]/g, ''); // 全角の数字と小数点を半角に変換 event.target.value = valueNumber.replace(/[0-9.]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 0xFEE0); }); } function checkInput() { let result = true; for(let i = 0; i < inputItems.length; i++) { if(inputItems[i].value === '') { alert('未入力の項目があります'); result = false; break; } } return result; } function calcInput() { const checkResult = checkInput(); if(checkResult === false) { return; } updateInputValues(); let result = (inputValues.joutei + inputValues.katei) * inputValues.takasa / 2; // 小数第一位で四捨五入 result = Math.round(result * 10) / 10; resultItem.textContent = result; } }, false);

計算を行うJavaScriptのコードです。

部分的にコードを解説していきます。

const calculator = document.querySelector('.calculator'); const inputItems = calculator.querySelectorAll('.calculator_input input'); for(let i = 0; i < inputItems.length; i++) { inputItems[i].addEventListener('change', correctInput); } const resultItem = calculator.querySelector('.calculator_result dd'); calculator.querySelector('.calculator_action_calc').addEventListener('click', calcInput); calculator.querySelector('.calculator_action_reset').addEventListener('click', resetAll);

入力項目のinputや各buttonにイベント処理を登録しています。

const inputValues = new Array(); function updateInputValues() { for(let i = 0; i < inputItems.length; i++) { inputValues[inputItems[i].getAttribute('id')] = parseFloat(inputItems[i].value); } }

各入力項目の値を配列に格納しています。

id属性に設定された値をキーにした連想配列にまとめているため、「inputValues.takasa」といった書き方で値を参照します。

各入力項目に設定されたデータは文字列データとなっているため、配列データに格納する際、「parseFloat」関数を使って実数として取得しています。

function resetAll() { for(let i = 0; i < inputItems.length; i++) { inputItems[i].value = ''; } resultItem.textContent = ''; updateInputValues(); }

入力された内容の初期化を行う関数です。

function correctInput(event) { const inputValue = event.target.value; // 数字と小数点以外の文字を削除 const valueNumber = inputValue.replace(/[^0-9.0-9.]/g, ''); // 全角の数字と小数点を半角に変換 event.target.value = valueNumber.replace(/[0-9.]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 0xFEE0); }); }

入力内容の補正を行う処理です。
input項目に何かしらの値が入力されたときに呼ばれ、数字と小数点以外の文字は削除し、全角の値は半角に変換してinput項目に入れ直しています。

function checkInput() { let result = true; for(let i = 0; i < inputItems.length; i++) { if(inputItems[i].value === '') { alert('未入力の項目があります'); result = false; break; } } return result; }

入力内容のチェックを行う関数です。
今回のサンプルでは、未入力項目のチェックのみを行っています。

function calcInput() { const checkResult = checkInput(); if(checkResult === false) { return; } updateInputValues(); let result = (inputValues.joutei + inputValues.katei) * inputValues.takasa / 2; // 小数第一位で四捨五入 result = Math.round(result * 10) / 10; resultItem.textContent = result; }

一番重要な計算を行う関数です。
各入力項目の内容を「checkInput」関数でチェックし、問題なければ「updateInputValues」関数で配列データに格納します。

あとは配列データを使って計算を行い、結果を表示します。

ご質問など受け付けています

記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。

ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。