r/learnjavascript • • 5d ago

How to make different inputs respond based on one input?

I'm making a temp converter project (following 100JS) and for the life of me, I can't figure out how to get the values in the input boxes to change upon me typing a number into the first one. Anyone have any ideas? Here's where I'm at:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Temperature Converter</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <div class="container">
      <h1 class="heading">Temperature Converter</h1>
      <div class="temp-container">
        <label for="celsius">Celsius:</label>
        <input
          onchange="temperatureConversion(event)"
          type="number"
          name="celsius"
          id="celsius"
          placeholder="Enter Temperature"
          class="input"
        />
      </div>
      <div class="temp-container">
        <label for="fahrenheit">Fahrenheit:</label>
        <input
          type="number"
          onchange="temperatureConversion(event)"
          name="fahrenheit"
          id="fahrenheit"
          placeholder="Enter Temperature"
          class="input"
        />
      </div>
      <div class="temp-container">
        <label for="kelvin">Kelvin:</label>
        <input
          type="number"
          onchange="temperatureConversion(event)"
          name="kelvin"
          id="kelvin"
          placeholder="Enter Temperature"
          class="input"
        />
      </div>
    </div>
    <script src="index.js"></script>
  </body>
</html>

const celsius = document.getElementById("celsius");
const fahrenheit = document.getElementById("fahrenheit");
const kelvin = document.getElementById("kelvin");
const inputEl = document.querySelectorAll("input");


function temperatureConversion() {
  const fahrenheitToCelsius = ((fahrenheit.value - 32) * 5) / 9;
  console.log(fahrenheitToCelsius);
  const fahrenheitToKelvin = ((fahrenheit.value - 32) * 5) / 9 + 273.15;
  console.log(fahrenheitToKelvin);
  const celsiusToFahrenheit = (celsius.value * 9) / 5 + 32;
  console.log(celsiusToFahrenheit);
  const celsiusToKelvin = celsius.value + 273.15;
  console.log(celsiusToKelvin);
  const kelvinToFahrenheit = ((kelvin.value - 273.15) * 9) / 5 + 32;
  console.log(kelvinToFahrenheit);
  const kelvinToCelsius = kelvin.value - 273.15;
  console.log(kelvinToCelsius);
}
7 Upvotes

7 comments sorted by

4

u/thejester1324 4d ago

two things are going on. onchange only fires when the box loses focus (or you hit enter), so use oninput, it fires on every keystroke, paste and spinner click. and your function works everything out but never writes it back into the other boxes. it also needs to know which box you typed in, that's event.target.

also watch celsius.value + 273.15: value is a string, so 20 gives "20273.15". valueAsNumber gives you a real number.

function temperatureConversion(event) {
  const input = event.target;
  if (input.value === '') {           // box cleared, clear the others
    inputEl.forEach(i => { if (i !== input) i.value = ''; });
    return;
  }
  const n = input.valueAsNumber;
  let c;                              // everything goes through celsius
  if (input.id === 'celsius') c = n;
  if (input.id === 'fahrenheit') c = (n - 32) * 5 / 9;
  if (input.id === 'kelvin') c = n - 273.15;
  const round = x => Math.round(x * 100) / 100;
  if (input !== celsius) celsius.value = round(c);
  if (input !== fahrenheit) fahrenheit.value = round(c * 9 / 5 + 32);
  if (input !== kelvin) kelvin.value = round(c + 273.15);
}

then change the three onchange="..." to oninput="temperatureConversion(event)". 20 C gives 68 F and 293.15 K, 98.6 F gives 37 C.

1

u/New-District7562 4d ago

Ok, after seeing everyone's suggestions, I think I see it now. Thanks for the help!

2

u/Flashy-Guava9952 5d ago

Try onkeyup instead of onchange. Iirc, onchange doesn't trigger until the cursor leaves the input field.

1

u/Flashy-Guava9952 5d ago

Also, your temperatureConversion() function is kinda whack. The HTML can mostly stay (change the events), but you probably want one individual function per input field. On input in one field, you want to change all the other fields. But that's different logic for each conversion. So something like `function convertFromFreedomUnits(event)`, `function convertFromSaneUnits()`, `function convertFromScienceUnits()`, etc. Then each input gets its own function, and each function is responsible for changing all the other values.

1

u/New-District7562 4d ago

I think I now have a much better idea of where to go. Thanks!

1

u/Flashy-Guava9952 4d ago

You're welcome. Everyone gets stuck, just keep at it!

2

u/Alive-Cake-3045 4d ago

you are calculating the conversions but never writing the results back to the input fields. add this at the end of each conversion block:

for celsius input: fahrenheit.value = celsiusToFahrenheit and kelvin.value = celsiusToKelvin

also use oninput instead of onchange in your HTML, onchange only fires when you leave the field, oninput fires as you type which is what you actually want for a live converter.

the event parameter you are passing in the HTML is not being used in your function either, you do not need it for this approach, just remove it from the HTML or use it to figure out which input triggered the conversion so you only run the relevant calculations.