Search code examples
javascriptsettimeoutcleartimeout

displaying message with setTimeOut and clearTimeout


I am working on a credit card checker project. The validation code works (so I don't include the code for it) but I want to go a step further: the user types in a number and gets a reply. If the card is not valid they get "This card is not valid" in red, if it is, the answer is in green. The message disappears after a given time (setTimeout). The problem is it only works once. One time for valid and one for invalid.

I know it has something to do with timeoutId and clearTimeout but I've been chasing my own tail around trying to get it right. Probably because I don't fully understand it yet.

HTML:

<div class="credit-card">
      <p class="credit-card__text">Want to check you if your credit card is valid?</p>

      <input type="number" id="userInput" class="js-input" placeholder="type in your number and press ENTER" onkeydown="handleEnter(event)">

<div>
        <p id="js-return-valid"></p>
        <p id="js-return-invalid"></p>
      </div>
    </div>

JS:

    const displayValid = document.getElementById('js-return-valid');
    const displayInvalid = document.getElementById('js-return-invalid');
    let input  = '';

    
    function handleEnter(event) {
      
      if (event.key === 'Enter') {
        input = document.getElementById("userInput").value;
        input = String(input).split('').map((input
        ) => { return Number(input) });
        
        validateCred(input);  

        if (!validateCred(input)) { 
         
            setTimeout(function() {
                displayInvalid.style.display = "none";
            }, 2000);
            
            displayInvalid.innerHTML = `This number is not valid.`;
         
        } else {
           
            setTimeout(function() {
                displayValid.style.display = "none";
            }, 2000);

            displayValid.innerHTML = `This number is valid.`;
         }

      document.getElementById("userInput").value = null;

        } 
    }

Solution

    • Always clear any existing timeout before starting a new one. This ensures that the message will always show for the full duration even if the user rapidly presses the Enter key multiple times.

    • Reset the display properties of both displayValid and displayInvalid so that they're both potentially available to show messages again.

      const displayValid = document.getElementById('js-return-valid');
      const displayInvalid = document.getElementById('js-return-invalid');
      let input  = '';
      let timeoutId;
      
       function handleEnter(event) {
      if (event.key === 'Enter') {
       const input = document.getElementById("userInput").value.split('').map(Number);
      
       // Check for empty input
       if (input.length === 0) {
           displayValid.style.display = 'none';
           displayInvalid.style.display = 'none';
           return;
       }
      
       // Reset style and clear timeouts
       displayValid.style.display = "block";
       displayInvalid.style.display = "block";
       clearTimeout(validTimeoutId);
       clearTimeout(invalidTimeoutId);
      
       if (validateCred(input)) {
           displayValid.textContent = 'This number is valid.';
           displayInvalid.style.display = 'none';
           validTimeoutId = setTimeout(() => {
               displayValid.style.display = 'none';
           }, 2000);
       } else {
           displayInvalid.textContent = 'This number is not valid.';
           displayValid.style.display = 'none';
           invalidTimeoutId = setTimeout(() => {
               displayInvalid.style.display = 'none';
           }, 2000);
       }
      
       document.getElementById("userInput").value = null;
       }
      }