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') { clearTimeout(timeoutId); displayValid.style.display = "block"; displayInvalid.style.display = "block"; input = document.getElementById("userInput").value; input = String(input).split('').map(Number); if (!validateCred(input)) { // Set message for invalid input displayInvalid.innerHTML = 'This number is not valid.'; displayValid.innerHTML = ''; timeoutId = setTimeout(() => { displayInvalid.style.display = "none"; }, 2000); } else { // Set message for valid input displayValid.innerHTML = 'This number is valid.'; displayInvalid.innerHTML = ''; // Clear the invalid message // Hide valid message after 2 seconds timeoutId = setTimeout(() => { displayValid.style.display = "none"; }, 2000); } document.getElementById("userInput").value = null; } }