skip to Main Content

The functionality for all valid numbers is working fine. When the "keydown" or "click" are used the Roman Numeral conversion properly displays in the outputField. However, when the same is done for one of the error numbers, the outputField updates to show the string after the next keystroke. For numbers greater than 3999 it will also convert the number then display the error string after the next keystroke. Please, proofread through my JS code and let me know any thoughts.

I am still quite new to JS so any other insights in how I can improve my code would be helpful too.

Here is a codepen to the project: Codepen

const numberInput = document.getElementById("number");
const convertBtn = document.getElementById("convert-btn");
const outputField = document.getElementById("output-field");
const resetBtn = document.getElementById("reset-btn");
const errorField = document.getElementById("error-field");


//conversion
function toRoman(num) {
  const romanNumerals = {
    M: 1000,
    CM: 900,
    D: 500,
    CD: 400,
    C: 100,
    XC: 90,
    L: 50,
    XL: 40,
    X: 10,
    IX: 9,
    V: 5,
    IV: 4,
    I: 1
  };

  let result = "";

  for (let i in romanNumerals) {
    while (num >= romanNumerals[i]) {
      result += i;
      num -= romanNumerals[i];
    }
  }
  return result;
}

//reset
function resetApp() {
  outputField.textContent = "";
  numberInput.value = "";
  errorField.textContent = "";
}

//check user input
function inputCheck() {
  const errorNum = parseInt(numberInput.value)
  if (isNaN(errorNum) || !errorNum) {
    outputField.textContent = "Please enter a valid number";
  } else if (errorNum < 1) {
    outputField.textContent = "Please enter a number greater than or equal to 1";
  } else if (errorNum > 3999) {
    outputField.textContent = "Please enter a number less than or equal to 3999";
  } else {
    outputField.textContent = "";
  };
  return; 
}

//button functionality
convertBtn.addEventListener("click", () => {
  inputCheck(numberInput.value);
  outputField.textContent = toRoman(numberInput.value);
});

resetBtn.addEventListener("click", resetApp);

numberInput.addEventListener
("keydown", (e) => {
  inputCheck(numberInput.value);
  if (e.key === "Enter") {
    outputField.textContent = toRoman(numberInput.value);
  }
});
body {
  font-family: system-ui;
  text-align: center;
}
<!DOCTYPE>
<html>


<body>
<input id='number'>
<button id='convert-btn'>Convert</button>
<p id='output-field'>Output will appear here.</p>
<button id='reset-btn'>Reset</button>
<p id='error-field'>Errors will show here.</p>
</body>
<html>

I’ve tried several fixes with .textContent, .value, .innerHTML, etc. this state is the best working I’ve had yet. When the outputField.textContent was replaced with errorField.textContent and displaying to a separate paragraph element the error messages worked great. However, that violates the code checks for the class as the error messages must display in the #output element.

2

Answers


  1. Change the keydown event to input when you add an event listener to the numberInput:

    numberInput.addEventListener
    ("input", (e) => {
      inputCheck(numberInput.value);
      if (e.key === "Enter") {
        outputField.textContent = toRoman(numberInput.value);
      }
    });
    

    If you want to be able to track the Enter key:

    function inputCheck() {
      const errorNum = parseInt(numberInput.value)
      if (isNaN(errorNum) || !errorNum) {
        outputField.textContent = "Please enter a valid number";
        return false;
      } else if (errorNum < 1) {
        outputField.textContent = "Please enter a number greater than or equal to 1";
        return false;
      } else if (errorNum > 3999) {
        outputField.textContent = "Please enter a number less than or equal to 3999";
        return false;
      } else {
        outputField.textContent = "";
        return true;
      };
    }
    
    numberInput.addEventListener("keyup", (e) => {
      if (inputCheck(numberInput.value)) {
        convertBtn.style.display = 'block';
        if (e.key === "Enter") {
            outputField.textContent = toRoman(numberInput.value);
        } else {
            // pass
        }
      } else {
        convertBtn.style.display = 'none';
      }
    
    });
    

    Here we add return statements in inputCheck to see how the check went, if positive, continue on with calculations, else hide the convert button and disable the option to convert with Enter.

    Login or Signup to reply.
  2. You can try this solution. First thing, when you put a keydown event it checks the value before you actually type, so you change it to keyup which checks after you actually type the character. Also I made the what inputCheck() return true or false, and I put a condition when you press the Convert button. If it is valid it works but if not, it doesn’t put anything.

    const numberInput = document.getElementById("number");
    const convertBtn = document.getElementById("convert-btn");
    const outputField = document.getElementById("output-field");
    const resetBtn = document.getElementById("reset-btn");
    const errorField = document.getElementById("error-field");
    
    
    //conversion
    function toRoman(num) {
      const romanNumerals = {
        M: 1000,
        CM: 900,
        D: 500,
        CD: 400,
        C: 100,
        XC: 90,
        L: 50,
        XL: 40,
        X: 10,
        IX: 9,
        V: 5,
        IV: 4,
        I: 1
      };
    
      let result = "";
    
      for (let i in romanNumerals) {
        while (num >= romanNumerals[i]) {
          result += i;
          num -= romanNumerals[i];
        }
      }
      return result;
    }
    
    //reset
    function resetApp() {
      outputField.textContent = "";
      numberInput.value = "";
      errorField.textContent = "";
    }
    
    //check user input
    function inputCheck() {
      const errorNum = parseInt(numberInput.value)
      if (isNaN(errorNum) || !errorNum) {
        outputField.textContent = "Please enter a valid number";
        return false;
      } else if (errorNum < 1) {
        outputField.textContent = "Please enter a number greater than or equal to 1";
        return false;
      } else if (errorNum > 3999) {
        outputField.textContent = "Please enter a number less than or equal to 3999";
        return false;
      } else {
        outputField.textContent = "";
      };
      return true; 
    }
    
    //button functionality
    convertBtn.addEventListener("click", () => {
      if (inputCheck(numberInput.value)) outputField.textContent = toRoman(numberInput.value);
    });
    
    resetBtn.addEventListener("click", resetApp);
    
    numberInput.addEventListener
    ("keyup", (e) => {
      
        inputCheck(numberInput.value);
        if (e.key === "Enter") {
          outputField.textContent = toRoman(numberInput.value);
        }
      
      
      
    });
    body {
      font-family: system-ui;
      text-align: center;
    }
    <!DOCTYPE>
    <html>
    
    
    <body>
    <input id='number'>
    <button id='convert-btn'>Convert</button>
    <p id='output-field'>Output will appear here.</p>
    <button id='reset-btn'>Reset</button>
    <p id='error-field'>Errors will show here.</p>
    </body>
    <html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search