Reputation: 4420
I am trying to write a pure JavaScript form validation that will add an error message next to the label
elements if the input
is empty.
The confirmEmail input
gets an additional error message if it does not match the email input
My problem is that if you hit the submit button when all fields are empty, then put a value into the email
input but leave confirmEmail empty and hit submit again, both error messages will appear next to the confirmEmail's label. The ideal result would be that confirmEmail only has text that says "Email does not match"
Here is a fiddle: http://jsfiddle.net/R5e2T/
Here is my HTML:
<div id="theForm">
<div>
<label for="firstName">First Name:</label>
<br>
<input type="text" id="firstName" name="first" value="" />
</div>
<div>
<label for="lastName">Last Name:</label>
<br>
<input type="text" id="lastName" name="last" value="" />
</div>
<div>
<label for="email">Email:</label>
<br>
<input type="email" id="email" name="email" value="" />
</div>
<div>
<label for="confirmEmail">Confirm Email:</label>
<br>
<input type="text" id="confirmEmail" name="confirmEmail" value="" />
</div>
<button type="button" id="submitButton">Submit</button>
</div>
Here is my JavaScript:
function validate () {
var theForm = document.getElementById('theForm'),
firstName = document.getElementById('firstName'),
lastName = document.getElementById('lastName'),
email = document.getElementById('email'),
confirmEmail = document.getElementById('confirmEmail'),
label = theForm.getElementsByTagName('label'),
input = theForm.getElementsByTagName('input'),
inputLength = input.length;
// Remove any spans that may have been added by the next for loop
for (var x = 0; x < inputLength; x++) {
var currLbl = label[x];
if ( currLbl.parentNode.getElementsByTagName('span').length > 0 ) {
var span = currLbl.parentNode.getElementsByTagName('span')[0];
removeElement(span);
}
}
// Error checking for the form.
// Add error message next to any element that has a blank value.
for (var i = 0; i < inputLength; i++) {
// innerText for IE, textContent for other browsers
var labelText = label[i].innerText || label[i].textContent;
var currLabel = label[i];
var text = document.createTextNode( labelText + ' cannot be empty');
if ( input[i].value === '' ) {
currLabel.parentNode.style.color = 'red';
currLabel.insertAdjacentHTML('afterend', ' <span>cannot be empty</span>');
}
else if ( input[i].value !== '') {
currLabel.parentNode.style.color = '';
}
}
// Test to see if confirmEmail is equal to email.
// If not add a warning message next to confirmEmail's label
if (confirmEmail.value !== email.value) {
var labelElement = confirmEmail.parentNode.getElementsByTagName('label')[0]
labelElement.insertAdjacentHTML('afterend', ' <span>Email does not match</span>');
labelElement.parentNode.style.color = 'red';
}
// Test to make sure all inputs have a value,
// and that confirmEmail equals email.
if (firstName.value !== '' && lastName.value !== '' && email.value !== '' && confirmEmail.value !== '' && email.value === confirmEmail.value) {
alert("Submitted!!!");
return true;
} else {
return false;
}
};
// Remove Element function
function removeElement(node) {
node.parentNode.removeChild(node);
}
(function () {
var button = document.getElementById('submitButton');
button.addEventListener('click', validate, false);
}());
Upvotes: 0
Views: 591
Reputation: 1164
I forked your fiddle.
What I did was to use innerHtml
and just replace the text of the label, instead of creating new span-nodes and appending them to the document.
I store the original label, like "E-Mail" in a dataset variable, so that I can reset the label later.
Upvotes: 2
Reputation: 5183
Another solution is to add this before you add the "Email doensn't match" message:
var oldSpan = labelElement.parentNode.getElementsByTagName('span')[0];
removeElement(oldSpan);
An even better solution would be to check for confirmEmail
matching email
before checking for empty fields and do not add the "cannot be empty" message if another error message has been added already.
Upvotes: 1