Home > database >  Unit converter (like google's)
Unit converter (like google's)

Time:07-25

I created a length converter just like the one on google including all the units. I did it using the if/else statement and it works perfectly but my code is very long (about 450 lines of code). is there another way of doing the same thing?

below is only one unit (meter to the rest of the units)

Thank you

const input = document.getElementById("input");
const inputType = document.getElementById("inputType");
const output = document.getElementById("output");
const outputType = document.getElementById("outputType");
let inputResult, outputResult;

const finalResult = () => {
    inputResult = inputType.value;
    outputResult = outputType.value;

    // Meter
    if (inputResult === "m" && outputResult === "Cm") {
        //Meter to Centimeter
        output.value = Number(input.value) * 100;
    } else if (inputResult === "m" && outputResult === "Mm") {
        //Meter to Millimeter
        output.value = Number(input.value) * 1000;
    } else if (inputResult === "m" && outputResult === "Km") {
        //Meter to kilometer
        output.value = Number(input.value) / 1000;
    } else if (inputResult === "m" && outputResult === "mm") {
        //Meter to Micrometer
        output.value = Number(input.value) * 1e6;
    } else if (inputResult === "m" && outputResult === "Nm") {
        //Meter to Nanometer
        output.value = Number(input.value) * 1e9;
    } else if (inputResult === "m" && outputResult === "Mi") {
        //Meter to Mile
        output.value = Number(input.value) / 1609;
    } else if (inputResult === "m" && outputResult === "Y") {
        //Meter to Yard
        output.value = Number(input.value) * 1.094;
    } else if (inputResult === "m" && outputResult === "f") {
        //Meter to Foot
        output.value = Number(input.value) * 3.281;
    } else if (inputResult === "m" && outputResult === "In") {
        //Meter to Inch
        output.value = Number(input.value) * 39.37;
    } else if (inputResult === "m" && outputResult === "NM") {
        //Meter to Nautical Mile
        output.value = Number(input.value) / 1852;
    } else if (inputResult === "m" && outputResult === "m") {
        //Meter to Meter
        output.value = input.value;
    }

CodePudding user response:

Some things take a lot of code.. but yes you can make it shorter
The snippet below is compared_input=input*(measurement/compared_measurement)

const lengthTypes={ //a record of every length type with values that they are relative to each other
 Nm:1, //the smallest unit in the calculator, thus everything else is a COUNT of Nm
 mm:1000, //one micrometre is 1000 nanometres
 Mm:1e6, //one millimetre is 1 million nanometres
 Cm:1e7, //one cm is 10 million nanometres
 In:2.54e7, //one inch is 25.4 million nanometres
 f:3.048e8, //one foot is 304.8 million nanometres
 Y:9.144e8, //one yard is 914.4 million nanometres
 m:1e9, //one metre is 1 billion nanometers
 Km:1e12, //one kilometre is 1 trillion nanometres
 Mi:1.609e12, //one mile is 1.609 trillion nanometres
 NM:1.852e12, //one nautical mile is trillion nanometres
}


//1 for the bar on the left, 2 for the bar on the right
const input1 = document.getElementById("input1");
const inputType1 = document.getElementById("inputType1");
const input2 = document.getElementById("input2");
const inputType2 = document.getElementById("inputType2");

function handleChange(e){
  let type1=inputType1.value, type2=inputType2.value
  if([input1,inputType1,inputType2].includes(e.target||e.path[0])){
    //left hand side changed by human(so set right side)
    const n=parseInt(input1.value)
    if(isNaN(n)){return null}
    input2.value=n*(lengthTypes[type1]/lengthTypes[type2])
  }
  else{
    //right hand side changed by human(so set left side)
    const n=parseInt(input2.value)
    if(isNaN(n)){return null}
    input1.value=n*(lengthTypes[type2]/lengthTypes[type1])
  }
}

input1.addEventListener('change',handleChange)
input2.addEventListener('change',handleChange)
inputType1.addEventListener('change',handleChange)
inputType2.addEventListener('change',handleChange)
.card{
  display:table;
  height:50%;
  width:80%;
  background-color:lightblue;
}
.bar{
  float:left;
  width:40%;
  height:90%;
  margin:10px;
  background-color:teal;
}
input{
  width:80%;
}
select{
  width:85%;
}
<div >



<div >
<input type="number" id="input1" />
<select id="inputType1">
  <option value="Nm">Nanometre</option>
  <option value="mm">Micrometre</option>
  <option value="Mm">Millimetre</option>
  <option value="Cm">Centimetre</option>
  <option value="In">Inch</option>
  <option value="f">Foot</option>
  <option value="Y">Yard</option>
  <option value="m">Metre</option>
  <option value="Km">Kilometre</option>
  <option value="Mi">Mile</option>
  <option value="NM">Nautical Mile</option>
</select>
</div>

<div >
<input type="number" id="input2" />
<select id="inputType2">
  <option value="Nm">Nanometre</option>
  <option value="mm">Micrometre</option>
  <option value="Mm">Millimetre</option>
  <option value="Cm">Centimetre</option>
  <option value="In">Inch</option>
  <option value="f">Foot</option>
  <option value="Y">Yard</option>
  <option value="m">Metre</option>
  <option value="Km">Kilometre</option>
  <option value="Mi">Mile</option>
  <option value="NM">Nautical Mile</option>
</select>
</div>



</div>

CodePudding user response:

If you wanted to make it shorter you could set up a sort of anchor and convert off of that. The npm library units-converter does this. This file you would want is the length units

If you are going to the anchor you multiply by the to anchor unit and if you are going away from the anchor you divide.

Example:

Input: 12 km

Output: Centimeters

Anchor: Meter

12 km * 1000 = 12000 meters

12000 meters / (1/100) = 1200000 cm

CodePudding user response:

Detials commented in example

/**
 * @desc - Simple multiplication and division
 * @param {number} a - Operand
 * @param {number} z - Operand
 * @param {string} o - Operator
 * @return {number} Product or quotient of a & z
 */
const divPro = (a, z, o) => 
  o === '*' ? a * z : 
  o === '/' ? a / z : 
  o === '-*' ? a / z : 
  o === '-/' ? a * z : 0;
// Bind input event to <form>
document.forms[0].oninput = convert;

// Event handler passes Event Object by default
function convert(e) {
  // Object of constants and operators
  const M = {
    x: [0, ''],
    m: [1, '/'],
    cm: [100, '/'],
    mm: [1000, '/'],
    km: [1000, '*'],
    um: [1e6, '/'],
    nm: [1e9, '/'],
    mi: [1609, '*'],
    yd: [1.094, '/'],
    ft: [3.281, '/'],
    in: [39.37, '/'],
    nmi: [1852, '*']
  };
  // Reference all form controls
  const fc = this.elements;
  // Get the number from <input>
  let amtA = parseFloat(fc.amountA.value) || 0;
  // Get the value of first <select> - A
  let a = fc.unitA.value || 'x';
  // Get the number associated with first <select> value - B
  let uniA = parseFloat(M[a][0]);
  // Get the operator associated with first <select> value - C
  let oprA = M[a][1];
  
  // A
  let z = fc.unitZ.value || 'x'; 
  // B second <select>
  let uniZ = parseFloat(M[z][0]);
  // C second <select>
  let oprZ = M[z][1];
  
  // Determine the value in meters
  let A = divPro(amtA, uniA, oprA) || 0;
  // Determine the value from meters to selected unit
  let Z = divPro(A, uniZ, '-'   oprZ) || 0;
  
  // Display result in <output>
  fc.amountZ.value = Z || 0;
}
html {
  font: 300 2ch/1 'Segoe UI'
}

input,
select {
  font: inherit;
}

#amountA,
#amountZ {
  width: 8rem;
  font-family: Consolas;
  text-align: right;
}

#amountZ {
  display: inline-block;
  min-width: max-content;
}
<form>
  <input id='amountA' type='number' min='0' step='any' value='0'>&#8202;
  <select id='unitA'>
    <option value='x'>From</option>
    <option value='m'>Meter</option>
    <option value='cm'>Centimeter</option>
    <option value='mm'>Millimeter</option>
    <option value='km'>Kilometer</option>
    <option value='um'>Micrometer</option>
    <option value='nm'>Nanometer</option>
    <option value='mi'>Mile</option>
    <option value='yd'>Yard</option>
    <option value='ft'>Foot</option>
    <option value='in'>Inch</option>
    <option value='nmi'>Nautical Mile</option>
  </select><br>
  <output id='amountZ' value='0'></output>&nbsp;&nbsp;
  <select id='unitZ'>
    <option value='x'>To</option>
    <option value='m'>Meter</option>
    <option value='cm'>Centimeter</option>
    <option value='mm'>Millimeter</option>
    <option value='km'>Kilometer</option>
    <option value='um'>Micrometer</option>
    <option value='nm'>Nanometer</option>
    <option value='mi'>Mile</option>
    <option value='yd'>Yard</option>
    <option value='ft'>Foot</option>
    <option value='in'>Inch</option>
    <option value='nmi'>Nautical Mile</option>
  </select>
</form>

  • Related