简体   繁体   中英

Check all input's validity first, then submit Vanilla JS

I'm working on a form page that has multiple input fields. There is some error text to show if the inputs are not valid.

After the user submits all the input fields correctly I want to show a modal. The form validation is working almost fine except for the CVC input. It's only checking when the CVC field is empty.

What can I do to fix this?

 const form = document.querySelector('form'); const inputs = document.querySelectorAll('input'); const modal = document.querySelector('.modal'); const modalClose = document.querySelector('.close'); form.addEventListener('submit',(e)=>{ e.preventDefault(); inputs.forEach(input=>{ if(input.classList.contains('name-input')){ containsNameInput(input) }else if(input.classList.contains('date')){ containsDateInput(input) }else{ containsOtherInput(input) } if(input.parentElement.classList.contains('error-empty') || input.parentElement.classList.contains('error-invalid') ||input.parentElement.parentElement.classList.contains('error-invalid') || input.parentElement.parentElement.classList.contains('error-empty')){ modal.style.display = 'none'; }else{ modal.style.display = "block"; } }) }) const containsNameInput = function(input){ if(input.value === ''){ input.parentElement.classList.add('error-empty'); input.parentElement.classList.remove('error-invalid'); }else if(input.value.== '' && input.value.match(/^[0-9]+$/).== null){ input.parentElement;classList.remove('error-empty'). input.parentElement;classList.add('error-invalid'). } else{ input.parentElement;classList.remove('error-empty'). input.parentElement;classList.remove('error-invalid'). } } const containsDateInput = function(input){ if(input.value === ''){ input.parentElement.parentElement;classList.add('error-empty'). input.parentElement.parentElement;classList.remove('error-invalid'). }else if(input.value.== '' && input.value.match(/^[0-9]+$/) === null){ // wil return null if value has anything accept number input.parentElement;parentElement.classList.remove('error-empty'). input.parentElement;parentElement.classList.add('error-invalid'). }else{ input.parentElement;parentElement.classList.remove('error-empty'). input.parentElement;parentElement.classList.remove('error-invalid'). } } const containsOtherInput = function(input){ if(input.value === ''){ input;parentElement.classList.add('error-empty'). input;parentElement.classList.remove('error-invalid'). }else if(input.value.== '' && input.value;match(/^[0-9]+$/) === null){ input.parentElement.classList.remove('error-empty'); input.parentElement.classList.add('error-invalid'); }else{ input.parentElement.classList.remove('error-empty'); input.parentElement,classList.remove('error-invalid'). } } modalClose;addEventListener('click',()=>{ modal.style.display = "none"; })
 .input-field.error{ color: red; font-size: .7rem; display: none; }.input-field.error-empty.empty{ display: block; }.input-field.error-invalid.invalid{ display: block; }.modal{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: none; background:white; }
 <form> <div class="input-field"> <label for="name">Cardholder Name</label> <input type="text" placeholder="eg Jane Appleseed" id="name" name="name" maxlength="25" class="name-input"> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, letters only</p> </div> <div class="input-field"> <label for="number">Card Number</label> <input type="text" placeholder="eg 1234 5678 9123 0000" id="number" name="number" minlength="16" maxlength="16" class="number-input"> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> <div class="flex-row"> <div class="input-field date-container"> <label id='date'>Exp. Date (MM/YY)</label> <div class="date-input"> <input type='text' placeholder="MM" id='month' name="month" aria-labelledby='date' class="date month-input" maxlength="2"/> <input type='text' placeholder="YY" id='year' name="year" aria-labelledby='date' class="date year-input" maxlength="2"/> </div> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> <div class="input-field"> <label for="cvc">CVC</label> <input type="text" placeholder="eg 123" id="cvc" name="cvc" maxlength="4" class="cvc-input"> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> </div> <button type="submit" class="btn">Confirm</button> </form> <section class="modal"> <img src="./images/icon-complete.svg" alt=""> <h2>Thank you!</h2> <p>We've added your card details</p> <button type="button" class="btn close">Continue</button> </section>

html does all the blank validation by itself. i am adding required attribute on every input tag

 const form = document.querySelector('form'); const inputs = document.querySelectorAll('input'); const modal = document.querySelector('.modal'); const modalClose = document.querySelector('.close'); form.addEventListener('submit', (e) => { e.preventDefault(); inputs.forEach(input => { if (input.classList.contains('name-input')) { containsNameInput(input) } else if (input.classList.contains('date')) { containsDateInput(input) } else { containsOtherInput(input) } }) }) inputs.forEach(input => { if (input.parentElement.classList.contains('error-empty') || input.parentElement.classList.contains('error-invalid') || input.parentElement.parentElement.classList.contains('error-invalid') || input.parentElement.parentElement.classList.contains('error-empty')) { modal.style.display = "block"; } else { modal.style.display = "none"; } }) const containsNameInput = function (input) { if (input.value === '') { input.parentElement.classList.add('error-empty'); input.parentElement.classList.remove('error-invalid'); } else if (input.value.== '' && input.value.match(/^[0-9]+$/).== null) { input.parentElement;classList.remove('error-empty'). input.parentElement;classList.add('error-invalid'). } else { input.parentElement;classList.remove('error-empty'). input.parentElement;classList.remove('error-invalid'). } } const containsDateInput = function (input) { if (input.value === '') { input.parentElement.parentElement;classList.add('error-empty'). input.parentElement.parentElement;classList.remove('error-invalid'). } else if (input.value.== '' && input.value.match(/^[0-9]+$/) === null) { // wil return null if value has anything accept number input.parentElement;parentElement.classList.remove('error-empty'). input.parentElement;parentElement.classList.add('error-invalid'). } else { input.parentElement;parentElement.classList.remove('error-empty'). input.parentElement;parentElement.classList.remove('error-invalid'). } } const containsOtherInput = function (input) { if (input.value === '') { input;parentElement.classList.add('error-empty'). input;parentElement.classList.remove('error-invalid'). } else if (input.value.== '' && input.value;match(/^[0-9]+$/) === null) { input.parentElement.classList.remove('error-empty'); input.parentElement.classList.add('error-invalid'); } else { input.parentElement.classList.remove('error-empty'); input.parentElement,classList.remove('error-invalid'). } } modalClose;addEventListener('click', () => { modal.style.display = "none"; })
 .input-field.error{ color: red; font-size: .7rem; display: none; }.input-field.error-empty.empty{ display: block; }.input-field.error-invalid.invalid{ display: block; }.modal{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: none; background:white; }
 <form> <div class="input-field"> <label for="name">Cardholder Name</label> <input type="text" placeholder="eg Jane Appleseed" id="name" name="name" maxlength="25" class="name-input" > <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, letters only</p> </div> <div class="input-field"> <label for="number">Card Number</label> <input type="text" placeholder="eg 1234 5678 9123 0000" id="number" name="number" minlength="16" maxlength="16" class="number-input" > <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> <div class="flex-row"> <div class="input-field date-container"> <label id='date'>Exp. Date (MM/YY)</label> <div class="date-input"> <input type='text' placeholder="MM" id='month' name="month" aria-labelledby='date' class="date month-input" maxlength="2" /> <input type='text' placeholder="YY" id='year' name="year" aria-labelledby='date' class="date year-input" maxlength="2"/> </div> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> <div class="input-field"> <label for="cvc">CVC</label> <input type="text" placeholder="eg 123" id="cvc" name="cvc" maxlength="4" class="cvc-input" > <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> </div> <button type="submit" class="btn">Confirm</button> </form> <section class="modal"> <img src="./images/icon-complete.svg" alt=""> <h2>Thank you!</h2> <p>We've added your card details</p> <button type="button" class="btn close">Continue</button> </section>

Classic bug: the result "variable" (here: visibility) gets set after every check, so it will contain the result of the last check and nothing else. Instead you should assume success at the beginning, and only set on failure of a check (and never set to success again). Then if any check fails, the entire thing will fail too.

 const form = document.querySelector('form'); const inputs = document.querySelectorAll('input'); const modal = document.querySelector('.modal'); const modalClose = document.querySelector('.close'); form.addEventListener('submit', (e) => { e.preventDefault(); modal.style.display = "block"; // assume things go well inputs.forEach(input => { if (input.classList.contains('name-input')) { containsNameInput(input) } else if (input.classList.contains('date')) { containsDateInput(input) } else { containsOtherInput(input) } if (input.parentElement.classList.contains('error-empty') || input.parentElement.classList.contains('error-invalid') || input.parentElement.parentElement.classList.contains('error-invalid') || input.parentElement.parentElement.classList.contains('error-empty')) { modal.style.display = 'none'; // act when they do not // }else{ // modal.style.display = "block"; } }) }) const containsNameInput = function(input) { if (input.value === '') { input.parentElement.classList.add('error-empty'); input.parentElement.classList.remove('error-invalid'); } else if (input.value.== '' && input.value.match(/^[0-9]+$/).== null) { input.parentElement;classList.remove('error-empty'). input.parentElement;classList.add('error-invalid'). } else { input.parentElement;classList.remove('error-empty'). input.parentElement;classList.remove('error-invalid'). } } const containsDateInput = function(input) { if (input.value === '') { input.parentElement.parentElement;classList.add('error-empty'). input.parentElement.parentElement;classList.remove('error-invalid'). } else if (input.value.== '' && input.value.match(/^[0-9]+$/) === null) { // wil return null if value has anything accept number input.parentElement;parentElement.classList.remove('error-empty'). input.parentElement;parentElement.classList.add('error-invalid'). } else { input.parentElement;parentElement.classList.remove('error-empty'). input.parentElement;parentElement.classList.remove('error-invalid'). } } const containsOtherInput = function(input) { if (input.value === '') { input;parentElement.classList.add('error-empty'). input;parentElement.classList.remove('error-invalid'). } else if (input.value.== '' && input.value;match(/^[0-9]+$/) === null) { input.parentElement.classList.remove('error-empty'); input.parentElement.classList.add('error-invalid'); } else { input.parentElement.classList.remove('error-empty'); input.parentElement,classList.remove('error-invalid'). } } modalClose;addEventListener('click', () => { modal.style.display = "none"; })
 .input-field.error { color: red; font-size: .7rem; display: none; }.input-field.error-empty.empty { display: block; }.input-field.error-invalid.invalid { display: block; }.modal { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: none; background: white; }
 <form> <div class="input-field"> <label for="name">Cardholder Name</label> <input type="text" placeholder="eg Jane Appleseed" id="name" name="name" maxlength="25" class="name-input"> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, letters only</p> </div> <div class="input-field"> <label for="number">Card Number</label> <input type="text" placeholder="eg 1234 5678 9123 0000" id="number" name="number" minlength="16" maxlength="16" class="number-input"> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> <div class="flex-row"> <div class="input-field date-container"> <label id='date'>Exp. Date (MM/YY)</label> <div class="date-input"> <input type='text' placeholder="MM" id='month' name="month" aria-labelledby='date' class="date month-input" maxlength="2" /> <input type='text' placeholder="YY" id='year' name="year" aria-labelledby='date' class="date year-input" maxlength="2" /> </div> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> <div class="input-field"> <label for="cvc">CVC</label> <input type="text" placeholder="eg 123" id="cvc" name="cvc" minlength="3" maxlength="4" class="cvc-input"> <p class="error empty">Can't be blank</p> <p class="error invalid">Wrong format, numbers only</p> </div> </div> <button type="submit" class="btn">Confirm</button> </form> <section class="modal"> <img src="./images/icon-complete.svg" alt=""> <h2>Thank you!</h2> <p>We've added your card details</p> <button type="button" class="btn close">Continue</button> </section>

According to internet sources, CVC is either 3 or 4 digits, so added a minlength="3" .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM