【JavaScript&CSS】自動計算式の作り方

JavaScriptで自動計算ツールを作ってみる

JavaScriptとCSSを使って、簡単な計算式の作り方を公開します。
自分の学習・メモ用がメインですが、プログラミング学習初心者の参考になればと思います!

目次

フォームに入力した数値の和を計算する実装3例

コードの書き方は無数に存在しますが、ここでは個人的に理解しやすいと思った3パターンを紹介します。

もっとも単純なパターン

+

=

0

左辺に数字(半角)を打ち込むと、その合計(和)が右辺に自動表示されるプログラム。
(外観やここでの機能は他2例と同じです。)

HTML/CSS/JavaScript コードはこちら
  <div class="custom-space">
    <input type="number" id="A1">
    <p>+</p>
    <input type="number" id="B1">
    <p>=</p>
    <p class="answer" id="X1">0</p>
  </div>
  • input要素のtype属性をnumberにしておくと、数字のみ入力できるようになる。
    (要素にカーソルをもっていくと数を1ずつ増減できるボタンも実装される。)
p {
  margin: 0;
  line-height: 50px;
}

.custom-space {
  width: 800px;
  margin: 8px auto;
  display: flex;
  justify-content: space-between;
}

input {
  width: 25%;
  height: 50px;
  text-align: center;
  font-size: 18px;
}

.answer {
  width: 25%;
  height: 50px;
  border: 1px solid #ccc;
  background-color: rgba(238, 238, 238, .5);
  text-align: center;
}
  • フレックスボックスdisplay: flex;を使うと、input要素やp要素が横並びになり式っぽくなる。
    さらにjustify-content: space-between;とすることで、すべての要素が等間隔に並べられる。
  • フレックスボックスについては こちらの記事 で解説しています。
const A1 = document.getElementById('A1');
const B1 = document.getElementById('B1');
const X1 = document.getElementById('X1');

A1.addEventListener('input', () => {
  X1.textContent = Number(A1.value) + Number(B1.value);
});

B1.addEventListener('input', () => {
  X1.textContent = Number(A1.value) + Number(B1.value);
});
  • 左辺どちらか(A1 or B1)に数字が入力(input)されると、右辺(X1)のテキストに『A1 + B1』の結果が代入される。
  • input要素の値はvalue属性で取得できる。が、value属性は文字列のため、Number()で数値変換が必要。
    • 数値変換しないと、『1 + 1 = 11』のように数字が連結表示されてしまう。

計算部分を関数でまとめる

+

=

0

左辺に数字(半角)を打ち込むと、その合計(和)が右辺に自動表示されるプログラム。
(外観やここでの機能は他2例と同じです。)

HTMLとCSSのコードは他2例と基本的に同じです。
JavaScriptは、重複していた計算部分を関数に置き換えています。

HTML/CSS/JavaScript コードはこちら
  <div class="custom-space">
    <input type="number" id="A2">
    <p>+</p>
    <input type="number" id="B2">
    <p>=</p>
    <p class="answer" id="X2">0</p>
  </div>
  • input要素のtype属性をnumberにしておくと、数字のみ入力できるようになる。
    (要素にカーソルをもっていくと数を1ずつ増減できるボタンも実装される。)
p {
  margin: 0;
  line-height: 50px;
}

.custom-space {
  width: 800px;
  margin: 8px auto;
  display: flex;
  justify-content: space-between;
}

input {
  width: 25%;
  height: 50px;
  text-align: center;
  font-size: 18px;
}

.answer {
  width: 25%;
  height: 50px;
  border: 1px solid #ccc;
  background-color: rgba(238, 238, 238, .5);
  text-align: center;
}
  • フレックスボックスdisplay: flex;を使うと、input要素やp要素が横並びになり式っぽくなる。
    さらにjustify-content: space-between;とすることで、すべての要素が等間隔に並べられる。
  • フレックスボックスについては こちらの記事 で解説しています。
const A2 = document.getElementById('A2');
const B2 = document.getElementById('B2');
const X2 = document.getElementById('X2');

function add() {
  X2.textContent = Number(A2.value) + Number(B2.value);
}

A2.addEventListener('input', () => {
  add();
});

B2.addEventListener('input', () => {
  add();
});
  • 左辺どちらか(A2 or B2)に数字が入力(input)されるとadd関数が動作し、右辺(X2)のテキストに『A2 + B2』の結果が代入される。
  • input要素の値はvalue属性で取得できる。が、value属性は文字列のため、Number()で数値変換が必要。
    • 数値変換しないと、『1 + 1 = 11』のように数字が連結表示されてしまう。
  • 関数で機能をまとめておくことで、あとで計算式を変更するのが楽になる。
    また、コードも基本的に短くなる。(この例では計算式が簡単で短いので、逆に長くなってしまったが。)

同じ動作をするinput要素をforEachでまとめる

+

=

0

左辺に数字(半角)を打ち込むと、その合計(和)が右辺に自動表示されるプログラム。
(外観やここでの機能は他2例と同じです。)

HTMLとCSSのコードは他2例と基本的に同じです。
JavaScriptは、(1)重複していた計算部分を関数で置き換えて、(2)同じ動作をするinput要素をforEachでまとめています。

HTML/CSS/JavaScript コードはこちら
  <div class="custom-space">
    <input type="number" id="A3">
    <p>+</p>
    <input type="number" id="B3">
    <p>=</p>
    <p class="answer" id="X3">0</p>
  </div>
  • input要素のtype属性をnumberにしておくと、数字のみ入力できるようになる。
    (要素にカーソルをもっていくと数を1ずつ増減できるボタンも実装される。)
p {
  margin: 0;
  line-height: 50px;
}

.custom-space {
  width: 800px;
  margin: 8px auto;
  display: flex;
  justify-content: space-between;
}

input {
  width: 25%;
  height: 50px;
  text-align: center;
  font-size: 18px;
}

.answer {
  width: 25%;
  height: 50px;
  border: 1px solid #ccc;
  background-color: rgba(238, 238, 238, .5);
  text-align: center;
}
  • フレックスボックスdisplay: flex;を使うと、input要素やp要素が横並びになり式っぽくなる。
    さらにjustify-content: space-between;とすることで、すべての要素が等間隔に並べられる。
  • フレックスボックスについては こちらの記事 で解説しています。
const A3 = document.getElementById('A3');
const B3 = document.getElementById('B3');
const X3 = document.getElementById('X3');
    
const inputs = document.querySelectorAll('input');

inputs.forEach(input => {
  input.addEventListener('input', () => {
    X3.textContent = Number(A3.value) + Number(B3.value);
  });
});
  • 左辺どちらか(A3 or B3)に数字が入力(input)されるとadd関数が動作し、右辺(X3)のテキストに『A3 + B3』の結果が代入される。
  • input要素の値はvalue属性で取得できる。が、value属性は文字列のため、Number()で数値変換が必要。
    • 数値変換しないと、『1 + 1 = 11』のように数字が連結表示されてしまう。
  • input要素すべてを配列(inputs)で取得し、forEachで一つずつ取り出して同じイベントを設定する。
    イベントを一つにまとめることができて修正が楽になり、input要素が増えてもコードを追加する必要がなくなる。

【応用】表に入力した数値の個数・合計・平均を自動計算する実装

『入力された個数』『数字の合計』『入力された数字の平均』を求める表(リスト)を作ってみました。
表(テーブル)やリストの作成方法については こちらの記事 で解説しています。

入力数が決まっているパターン

A
B
C
個数
0
合計
0
平均
0
HTML/CSS/JavaScript コードはこちら
<div class="custom-space">
  <dl>
    <div class="cal-box">
      <dt>A</dt>
      <dd><input type="number"></dd>
    </div>
    <div class="cal-box">
      <dt>B</dt>
      <dd><input type="number"></dd>
    </div>
    <div class="cal-box">
      <dt>C</dt>
      <dd><input type="number"></dd>
    </div>
    <div class="cal-box">
      <dt class="answer-item">個数</dt>
      <dd class="answer" id="count">0</dd>  
    </div>
    <div class="cal-box">
      <dt class="answer-item">合計</dt>
      <dd class="answer" id="sum">0</dd>
    </div>
    <div class="cal-box">
      <dt class="answer-item">平均</dt>
      <dd class="answer" id="ave">0</dd>
    </div>
  </dl>
</div>
dl {
  width: 100%;
}

.cal-box {
  display: flex;
  justify-content: center;
  width: 100%;
}

dt {
  width: 10%;
  height: 50px;
  line-height: 50px;
  text-align: center;
  background-color: #ccc;
  font-weight: bold;
}

dd {
  width: 25%;
  height: 50px;
  margin: 0;
}

dd input {
  width: 100%;
  height: 50px;
  box-sizing: border-box;
  font-size: 18px;
  text-align: center;
}

dt.answer-item {
  background-color: blue;
  color: white;
}

dd.answer {
  border: 1px solid #ccc;
  background-color: rgba(238, 238, 238, .5);
  text-align: center;
  font-size: 20px;
  line-height: 50px;
  box-sizing: border-box;
}
const sum = document.getElementById('sum');
const ave = document.getElementById('ave');
const count = document.getElementById('count');
const inputs = document.querySelectorAll('input');

function getSum() {
  let result = 0;
  inputs.forEach(input => {
    result += Number(input.value);
  });
  
  return result;
}

function getCount() {
  let result = 0;
  inputs.forEach(input => {
    if (input.value) {
      result += 1;
    }
  });

  return result;
}

inputs.forEach(input => {
  input.addEventListener('input', () => {
    count.textContent = getCount();
    sum.textContent = getSum();
    ave.textContent = (getSum() / getCount()).toFixed(2);
  });
});

入力数をボタンで増やせるパターン

(1)
(2)
(3)
個数
0
合計
0
平均
0
HTML/CSS/JavaScript コードはこちら
<div class="custom-space">
  <dl>
    <div class="cal-box">
      <dt>(1)</dt>
      <dd><input type="number"></dd>
    </div>
    <div class="cal-box">
      <dt>(2)</dt>
      <dd><input type="number"></dd>
    </div>
    <div class="cal-box">
      <dt>(3)</dt>
      <dd><input type="number"></dd>
    </div>
    <div class="cal-box" id="cal-count">
      <dt class="answer-item">個数</dt>
      <dd class="answer" id="count">0</dd>  
    </div>
    <div class="cal-box">
      <dt class="answer-item">合計</dt>
      <dd class="answer" id="sum">0</dd>
    </div>
    <div class="cal-box">
      <dt class="answer-item">平均</dt>
      <dd class="answer" id="ave">0</dd>
    </div>
  </dl>
</div>
<div class="button-box">
  <button class="custom-button">項目を増やす</button>
</div>
dl {
  width: 100%;
}

.cal-box {
  display: flex;
  justify-content: center;
  width: 100%;
}

dt {
  width: 10%;
  height: 50px;
  line-height: 50px;
  text-align: center;
  background-color: #ccc;
  font-weight: bold;
}

dd {
  width: 25%;
  height: 50px;
  margin: 0;
}

dd input {
  width: 100%;
  height: 50px;
  box-sizing: border-box;
  font-size: 18px;
  text-align: center;
}

dt.answer-item {
  background-color: blue;
  color: white;
}

dd.answer {
  border: 1px solid #ccc;
  background-color: rgba(238, 238, 238, .5);
  text-align: center;
  font-size: 20px;
  line-height: 50px;
  box-sizing: border-box;
}

.button-box {
  width: 100%;
  max-width: 300px;
  padding: 8px 16px;
  margin: 16px auto;
  text-align: center;
  display: flex;
  flex-direction: column;
}

.custom-button {
  width: 50%;
  height: 2.5em;
  margin: 8px auto;
  padding: 4px 0;
  border-radius: 4px;
  background-color: red;
  color: white;
}

button:hover {
  opacity: .7;
}
const sum = document.getElementById('sum');
const ave = document.getElementById('ave');
const count = document.getElementById('count');
let calInputs = document.querySelectorAll('input');

function getSum(calinputs) {
  let result = 0;
  calInputs.forEach(calInput => {
    result += Number(calInput.value);
  });
  
  return result;
}

function getCount(calinputs) {
  let result = 0;
  calInputs.forEach(calInput => {
    if (calInput.value) {
      result += 1;
    }
  });

  return result;
}

calInputs.forEach(calInput => {
  calInput.addEventListener('input', () => {
    count.textContent = getCount(calInputs);
    sum.textContent = getSum(calInputs);
    ave.textContent = (getSum(calInputs) / getCount(calInputs)).toFixed(2);
  });
});

document.querySelector('.custom-button').addEventListener('click', () => {
  const formCount = document.querySelectorAll('input').length + 1;

  const newForm = document.createElement('input');
  newForm.type = 'number';
  
  const newDiv = document.createElement('div');
  newDiv.classList.add('cal-box');

  const newDt = document.createElement('dt');
  newDt.textContent = '(' + formCount + ')';

  const newDd = document.createElement('dd');

  newDd.appendChild(newForm);
  newDiv.appendChild(newDt);
  newDiv.appendChild(newDd);

  document.getElementById('cal-count').before(newDiv);

  calInputs = document.querySelectorAll('input');
  calInputs.forEach(calInput => {
    calInput.addEventListener('input', () => {
      count.textContent = getCount(calInputs);
      sum.textContent = getSum(calInputs);
      ave.textContent = (getSum(calInputs) / getCount(calInputs)).toFixed(2);
    });
  });
});

本サイトで実装している自動計算ツール

本サイトでは、以下のような自動計算ツールを公開しています。
コードは載せていませんが、計算式さえ組めればこのような実装も可能です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次