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;
}
}
2
Answers
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.
You need to save and clear the timeout. You are setting display to none but you never reset it to flex or whatever.