0

I'm building a simple multiplication form which calculates a sum and renders the answer direct to the DOM. I'm using a <select> menu to choose the initial number and an <input type="number"> for the multiplier.

Is it possible to recalculate the answer and render it to the DOM automatically when changing the <select> value? The form currently works but the user will need to delete the multiplier after re-selecting the initial number.

Here's where I currently am:

const selectValIn = document.querySelector(".select-val-in");
const inputValIn = document.querySelector(".input-val-in");
const valOut = document.querySelector(".val-out");
let multiplier = 2;

selectValIn.addEventListener("change", switchValIn);
inputValIn.addEventListener("keyup", convert);

function switchValIn() {
  let selectedVal = selectValIn.value;

  if (selectedVal === "four") {
  multiplier = 4;
  } else if (selectedVal === "six") {
  multiplier = 6;
  } else if (selectedVal === "eight") {
  multiplier = 8;
  }
}

function convert(e) {
  const inputValIn = e.target.value;
  const multiplication = inputValIn * multiplier;

  valOut.innerText = multiplication;
}
<div class="converter">
  <div class="converter-row">
    <select class="select-val-in">
    <option value="two">2</option>
    <option value="four">4</option>
    <option value="six">6</option>
    <option value="eight">8</option>
  </select>
  </div>
  <div class="converter-row">
  <label>Multiplied by:</label>
  <input class="input-val-in" type="number" value="0" />
  </div>
  <div class="converter-row">
  <p>Equals: <span class="val-out">0</span></p>
  </div>
</div>

Here's a Codepen with a working example: https://codepen.io/abbasarezoo/pen/59776227c017d1c1a3a245a37c305e76

SuperDJ
  • 7,488
  • 11
  • 40
  • 74
abbas_arezoo
  • 1,038
  • 3
  • 20
  • 38

3 Answers3

2

Rather than storing the changes, just call the calculation function when something changes and get the values there. Removing state makes the functions simpler and less error-prone.

// Selectors

const selectValIn = document.querySelector(".select-val-in");
const inputValIn = document.querySelector(".input-val-in");
const valOut = document.querySelector(".val-out");

// Calculate

function calculate() {
 const value = Number(inputValIn.value);
 const multiplier = Number(selectValIn.value);
 valOut.innerText = value * multiplier;
}

// Event listeners

selectValIn.addEventListener("change", calculate);
inputValIn.addEventListener("input", calculate);
* {
 box-sizing: border-box;
 margin: 0;
 padding: 0;
}

.converter-row {
 margin: 0 0 1rem;
}
<div class="converter">
 <div class="converter-row">
  <select class="select-val-in">
   <option value="2" selected>2</option>
   <option value="4">4</option>
   <option value="6">6</option>
   <option value="8">8</option>
  </select>
 </div>
 <div class="converter-row">
  <label>Multiplied by:</label>
  <input class="input-val-in" type="number" value="0" />
 </div>
 <div class="converter-row">
  <p>Equals: <span class="val-out">0</span></p>
 </div>
</div>
Dominic
  • 62,658
  • 20
  • 139
  • 163
2

Take a look at the following example. Also take a look at the following to see the difference between change and input.

const selectValIn = document.querySelector(".select-val-in");
const inputValIn = document.querySelector(".input-val-in");
const valOut = document.querySelector(".val-out");

selectValIn.addEventListener("input", calculate);
inputValIn.addEventListener("input", calculate);

function calculate()
{
  valOut.innerText = Number(inputValIn.value) * Number(selectValIn.value);
}
<div class="converter">
  <div class="converter-row">
    <select class="select-val-in">
      <option value="2">2</option>
      <option value="4">4</option>
      <option value="6">6</option>
      <option value="8">8</option>
    </select>
  </div>
  
  <div class="converter-row">
    <label>Multiplied by:</label>
    <input class="input-val-in" type="number" value="0" />
  </div>
  
  <div class="converter-row">
    <p>Equals: <span class="val-out">0</span></p>
  </div>
</div>

Also note that a switch might have been easier to read:

// Easier to read
switch(selectedVal)
{
 case 'two':
  multiplier = 2;
  break;
case 'four':
  multiplier = 4;
  break;
case 'six':
  multiplier = 6;
  break;
case 'eigth':
  multiplier = 8;
  break;
}
SuperDJ
  • 7,488
  • 11
  • 40
  • 74
  • Thanks for your help, this is what I was looking for. I guess using a switch would work if the option value wasn't a number? – abbas_arezoo Sep 04 '18 at 07:31
0

Have you tried storing your inputValIn as well as your multiplier? This way, you can just do a check inside of your switchValIn function to see if the inputValIn already exists, in which case you can just do the multiplication and render immediately.

Another approach is to set a default inputValue so you never have to do the check and instead run the multiplication every time either of them changes

Damanveer Singh
  • 261
  • 3
  • 4
  • Your answer would be more usefull for the OP and future visitors if you would show what you mean. You can do this by providing some code in the answer – SuperDJ Sep 03 '18 at 21:27