user11452535
user11452535

Reputation:

How to build a lengths converter

I'm very new to JS and want to create a basic converter (mm, cm, dm, m, km). I want that if the mm input is bigger than 0, the converted cm will be entered into the cm input. Does anyone know what I'm doing wrong?

function convert() {
  let milliM = parseFloat(document.getElementById("mm").value);
  let centiM = parseFloat(document.getElementById("cm").value);
  let deciM = parseFloat(document.getElementById("dm").value);
  let Meter = parseFloat(document.getElementById("m").value);
  let kiloM = parseFloat(document.getElementById("km").value);

  let mm = parseFloat(document.getElementById("mm"));
  let cm = parseFloat(document.getElementById("cm"));
  let dm = parseFloat(document.getElementById("dm"));
  let m = parseFloat(document.getElementById("m"));
  let km = parseFloat(document.getElementById("km"));

  if (milliM > 0) {
    centiM = milliM / 10;
    cm.value = centiM;
  }
}
<h1>Converter</h1>
<h2>Length</h2>
<div class="container">
  <input type="text" id="mm" value="0"> mm
  <input type="text" id="cm" value="0"> cm
  <input type="text" id="dm" value="0"> dm
  <input type="text" id="m" value="0"> m
  <input type="text" id="km" value="0"> km
  <br>
  <button onclick="convert()">Convert</button>
</div>

Upvotes: 0

Views: 583

Answers (4)

user3589620
user3589620

Reputation:

Meter (m) as reference unit:

const converter = {
    "mm": 1000,
    "cm": 100,
    "dm": 10,
    "m": 1,
    "km": 0.001,
    "mile": 3.600/3.937 * 1.760
};

Example

Convert 30 dm to km

let res = 30 * 0.001 / 10;
console.log(res);

Complete solution

// Meter as reference unit
const converter = {
  "mm": 1000,
  "cm": 100,
  "dm": 10,
  "m": 1,
  "km": 0.001,
  "mile": 3.600 / 3.937 * 1.760
};

const units = Object.keys(converter);

function convertAll(currentValue, currentUnit) {
  units.forEach((unit) => {

    // If not the current input
    if (unit !== currentUnit) {
      let input = document.getElementById(unit);
      input.value = Number(currentValue) * converter[unit] / converter[currentUnit];
    }
  })
}

units.forEach((unit) => {
  let input = document.getElementById(unit);
  input.addEventListener("input", function() {
    convertAll(this.value, this.id);
  })
})
ul {
  list-style: none;
  padding: 0;
}

ul span {
  margin-left: 5px;
}
<ul>
  <li><input type="text" id="mm" value="0"><span>mm</span></li>
  <li><input type="text" id="cm" value="0"><span>cm</span></li>
  <li><input type="text" id="dm" value="0"><span>dm</span></li>
  <li><input type="text" id="m" value="0"><span>m</span></li>
  <li><input type="text" id="km" value="0"><span>km</span></li>
  <li><input type="text" id="mile" value="0"><span>mile</span></li>
</ul>

Upvotes: 1

Sarah Gro&#223;
Sarah Gro&#223;

Reputation: 10879

In addition to the issues addressed in the comments and answers so far, here's a fully working example with a different approach that I'd prefer. Instead of requiring the user to click a button to trigger the recalculation (btw, which value would you take as the base value in that case? You could highlight the last changed field to give visual feedback to the user and use this field as the base, but that still seems overly complicated to me...), trigger the calculation every time one of the inputs is changed, and use this input as the base for your calculations:

const mm = document.getElementById("mm");
const cm = document.getElementById("cm");
const dm = document.getElementById("dm");
const m = document.getElementById("m");
const km = document.getElementById("km");

[mm, cm, dm, m, km].forEach((inputEl) => {
  inputEl.addEventListener('input', () => convert(inputEl));
});

function convert(inputEl) {
  switch (inputEl.id) {
    case 'mm':
      let milliM = parseFloat(document.getElementById("mm").value);
      cm.value = milliM / 10;
      dm.value = milliM / 100;
      m.value = milliM / 1000;
      km.value = milliM / 1000000;
      break;
    case 'cm':
      let centiM = parseFloat(document.getElementById("cm").value);
      mm.value = centiM * 10;
      dm.value = centiM / 10;
      m.value = centiM / 100;
      km.value = centiM / 100000;
      break;
    case 'dm':
      let deciM = parseFloat(document.getElementById("dm").value);
      mm.value = deciM * 100;
      cm.value = deciM * 10;
      m.value = deciM / 10;
      km.value = deciM / 10000;
      break;
    case 'm':
      let Meter = parseFloat(document.getElementById("m").value);
      mm.value = Meter * 1000;
      cm.value = Meter * 100;
      dm.value = Meter * 10;
      km.value = Meter / 1000;
      break;
    case 'km':
      let kiloM = parseFloat(document.getElementById("km").value);
      mm.value = kiloM * 1000000;
      cm.value = kiloM * 100000;
      dm.value = kiloM * 10000;
      m.value = kiloM * 1000;
      break;
  }
}
.last-touched {
  box-shadow: red 0px 0px 8px
}
<h1>Converter</h1>
<h2>Length</h2>

<div class="container">
  <input type="text" id="mm" value="0"> mm
  <input type="text" id="cm" value="0"> cm
  <input type="text" id="dm" value="0"> dm
  <input type="text" id="m" value="0"> m
  <input type="text" id="km" value="0"> km
</div>

Upvotes: 0

Jon Warren
Jon Warren

Reputation: 857

2 Things:

  1. You accidentally declared m twice. The second one should be km. (Not relevant for the problem you're trying to solve, but worth pointing out).

  2. Ditch the parseFloats when defining your selectors. So change this part:

let mm = parseFloat(document.getElementById("mm"));
let cm = parseFloat(document.getElementById("cm"));
let dm = parseFloat(document.getElementById("dm"));
let m =  parseFloat(document.getElementById("m"));
let m =  parseFloat(document.getElementById("km"));

To this:

let mm = document.getElementById("mm");
let cm = document.getElementById("cm");
let dm = document.getElementById("dm");
let m =  document.getElementById("m");
let km = document.getElementById("km");

You don't need to use parseFloat since you're just using those variables as references to the selectors.

Upvotes: 0

Ruslan Gataullin
Ruslan Gataullin

Reputation: 478

The first thing I can see you should remove parseFloat from this section. You are looking for element reference so it's not needed here:

let mm = parseFloat(document.getElementById("mm"));
let cm = parseFloat(document.getElementById("cm"));
let dm = parseFloat(document.getElementById("dm"));
let m =  parseFloat(document.getElementById("m"));
let km = parseFloat(document.getElementById("km"));

Should be like this:

let mm = document.getElementById("mm");
let cm = document.getElementById("cm");
let dm = document.getElementById("dm");
let m =  document.getElementById("m");
let km =  document.getElementById("km");

Upvotes: 0

Related Questions