Home > Net >  Javascript input event listener broken?
Javascript input event listener broken?

Time:04-30

I'm working on a unit conversion app as part of a course and I'm confused with the "input" event listener working only once. When I open the page, or I refresh the page, when I first type into my input element the function works properly and displays the initial value. Subsequent inputs properly display, but the result remains the same and sometimes even stays at 0 requiring another refresh.

Here is my code:

////// HTML Elements
const inputEl = document.getElementById("input-el")
const Lresult = document.getElementById("lresult")
const Vresult = document.getElementById("vresult")
const Mresult = document.getElementById("mresult")

////// Ratios for conversion
const metricLratio = 3.28084
const metricVratio = 0.264172
const metricMratio = 2.20462
const imperialLratio = 0.3048
const imperialVratio = 4.54609
const imperialMratio = 0.453592

////// Getting conversion results first so I can use the toFixed method
let metricLresult = inputEl.value * metricLratio
let metricVresult = inputEl.value * metricVratio
let metricMresult = inputEl.value * metricMratio
let imperialLresult = inputEl.value * imperialLratio
let imperialVresult = inputEl.value * imperialVratio
let imperialMresult = inputEl.value * imperialMratio

////// Functions
inputEl.addEventListener("input", function() {
    
    Lresult.textContent = `${inputEl.value} meters = ${metricLresult.toFixed(3)} feet | ${inputEl.value} feet = ${imperialLresult.toFixed(3)} meters`

    Vresult.textContent = `${inputEl.value} liters = ${metricVresult.toFixed(3)} gallons | ${inputEl.value} gallons = ${imperialVresult.toFixed(3)} liters`

    Mresult.textContent = `${inputEl.value} kilos = ${metricMresult.toFixed(3)} pounds | ${inputEl.value} pounds = ${imperialMresult.toFixed(3)} kilos`
})
<!DOCTYPE html>
<html>
    <head>
        <title>Unit Conversion Tool</title>
        <link rel="stylesheet" href="styles.css">
        <script src="index.js" defer></script>
    </head>
    <body>
        <div >
            <div id="top-side">
                <h3>Metric/Imperial unit conversion</h3>
                <input id="input-el" inputmode="numeric" placeholder="Enter value here" min="0">
            </div>
            <div id="bot-side">
                <div>
                    <h4>Length (Meter/Feet)</h4>
                    <p id="lresult">
                        0 meters = 0.000 feet | 0 feet = 0.000 meters
                    </p>
                </div>
                <div>
                    <h4>Volume (Liters/Gallons)</h4>
                    <p id="vresult">
                        0 liters = 0.000 gallons | 0 gallons = 0.000 liters
                    </p>
                </div>
                <div>
                    <h4>Mass (Kilograms/Pounds</h4>
                    <p id="mresult">
                        0 kilos = 0.000 pounds | 0 pounds = 0.000 kilos
                    </p>
                </div>
            </div>
        </div>
    </body>
</html>

As I mentioned, subsequent inputs into the field properly update the inputEl.value and it displays okay, but the various results I wish to display remain the same.

Am I dumb or something?

CodePudding user response:

You calculate those values like metricLresult only once off the value the input element had at the very beginning! In your event listener, you never recalculate them. It would work if you'd move all these lets into the function so they run every time:

////// Functions
inputEl.addEventListener("input", function() {
    
    ////// Getting conversion results first so I can use the toFixed method
    let metricLresult = inputEl.value * metricLratio
    let metricVresult = inputEl.value * metricVratio
    let metricMresult = inputEl.value * metricMratio
    let imperialLresult = inputEl.value * imperialLratio
    let imperialVresult = inputEl.value * imperialVratio
    let imperialMresult = inputEl.value * imperialMratio

    Lresult.textContent = `${inputEl.value} meters = ${metricLresult.toFixed(3)} feet | ${inputEl.value} feet = ${imperialLresult.toFixed(3)} meters`

    Vresult.textContent = `${inputEl.value} liters = ${metricVresult.toFixed(3)} gallons | ${inputEl.value} gallons = ${imperialVresult.toFixed(3)} liters`

    Mresult.textContent = `${inputEl.value} kilos = ${metricMresult.toFixed(3)} pounds | ${inputEl.value} pounds = ${imperialMresult.toFixed(3)} kilos`
})

Working code as runnable snippet:

////// HTML Elements
const inputEl = document.getElementById("input-el")
const Lresult = document.getElementById("lresult")
const Vresult = document.getElementById("vresult")
const Mresult = document.getElementById("mresult")

////// Ratios for conversion
const metricLratio = 3.28084
const metricVratio = 0.264172
const metricMratio = 2.20462
const imperialLratio = 0.3048
const imperialVratio = 4.54609
const imperialMratio = 0.453592

////// Functions
inputEl.addEventListener("input", function() {
    
    ////// Getting conversion results first so I can use the toFixed method
    let metricLresult = inputEl.value * metricLratio
    let metricVresult = inputEl.value * metricVratio
    let metricMresult = inputEl.value * metricMratio
    let imperialLresult = inputEl.value * imperialLratio
    let imperialVresult = inputEl.value * imperialVratio
    let imperialMresult = inputEl.value * imperialMratio

    Lresult.textContent = `${inputEl.value} meters = ${metricLresult.toFixed(3)} feet | ${inputEl.value} feet = ${imperialLresult.toFixed(3)} meters`

    Vresult.textContent = `${inputEl.value} liters = ${metricVresult.toFixed(3)} gallons | ${inputEl.value} gallons = ${imperialVresult.toFixed(3)} liters`

    Mresult.textContent = `${inputEl.value} kilos = ${metricMresult.toFixed(3)} pounds | ${inputEl.value} pounds = ${imperialMresult.toFixed(3)} kilos`
})
<!DOCTYPE html>
<html>
    <head>
        <title>Unit Conversion Tool</title>
        <link rel="stylesheet" href="styles.css">
        <script src="index.js" defer></script>
    </head>
    <body>
        <div >
            <div id="top-side">
                <h3>Metric/Imperial unit conversion</h3>
                <input id="input-el" inputmode="numeric" placeholder="Enter value here" min="0">
            </div>
            <div id="bot-side">
                <div>
                    <h4>Length (Meter/Feet)</h4>
                    <p id="lresult">
                        0 meters = 0.000 feet | 0 feet = 0.000 meters
                    </p>
                </div>
                <div>
                    <h4>Volume (Liters/Gallons)</h4>
                    <p id="vresult">
                        0 liters = 0.000 gallons | 0 gallons = 0.000 liters
                    </p>
                </div>
                <div>
                    <h4>Mass (Kilograms/Pounds</h4>
                    <p id="mresult">
                        0 kilos = 0.000 pounds | 0 pounds = 0.000 kilos
                    </p>
                </div>
            </div>
        </div>
    </body>
</html>

  • Related