Reputation: 1
I'm doing this for a class assignment and I know there has to be a better way of writing it. Maybe some kind of loop that gets the inputs and labels? I'm repeating a lot here and it seems better to minify this if possible.
function checkEmptyFields() {
if(formName.value === "") {
formLabels[0].classList.add("has-errors");
formLabels[0].innerHTML = "Name is required *";
formName.style.borderBottomColor = "red";
} else {
formLabels[0].classList.remove("has-errors");
formLabels[0].innerHTML = "Name";
formName.style.borderBottomColor = "green";
}
if(formEmail.value === "") {
formLabels[1].classList.add("has-errors");
formLabels[1].innerHTML = "Email is required *";
formEmail.style.borderBottomColor = "red";
} else {
formLabels[1].classList.remove("has-errors");
formLabels[1].innerHTML = "Email";
formEmail.style.borderBottomColor = "green";
}
if(formNumber.value === "") {
formLabels[2].classList.add("has-errors");
formLabels[2].innerHTML = "Phone is required *";
formNumber.style.borderBottomColor = "red";
} else {
formLabels[2].classList.remove("has-errors");
formLabels[2].innerHTML = "Phone";
formNumber.style.borderBottomColor = "green";
}
if(formMessage.value === "") {
formLabels[3].classList.add("has-errors");
formLabels[3].innerHTML = "message is required *";
formMessage.style.borderBottomColor = "red";
} else {
formLabels[3].classList.remove("has-errors");
formLabels[3].innerHTML = "Email";
formMessage.style.borderBottomColor = "green";
}
}
Upvotes: 0
Views: 128
Reputation: 59
You can try like this:
fields = [{
'name': formName,
'index': 0,
'css-error': "has-errors",
'innerHtml': "Name",
'innerHtml-error': "Name is required *",
'borderBottomColor ': "green", //Or you can hardcode it in the loop itself.
'borderBottomColor-error': "red"
},
....
]
for(var i=0; i < fields.length; i++) {
var field = fields[i];
if(field.name.value == "") {
formLabels[field.index].classList.add(field.css);
formLabels[field.index].innerHTML = field.innerHtml-error;
field.name.style.borderBottomColor = field.borderBottomColor-error ;
} else {
formLabels[field.index].classList.remove(field.css);
formLabels[field.index].innerHTML = field.innerHtml;
field.name.style.borderBottomColor = field.borderBottomColor ;
}
}
Upvotes: 2
Reputation: 65806
Anytime you have roughly the same code in more than one place, you should stop and rethink your approach as you are doing here.
If you give each of the HTML elements that need to be validated a common class, you can then create a node list (collection/array) that contains them. Then you can loop over that collection and perform the same test (written only once) on each item and act accordingly.
Also, I'm not quite sure what you are doing with .innerHTML
, but don't use that when the text you are working with doesn't have any HTML in it. .innerHTML
has security and performance implications. Instead, use .textContent
when there is no HTML.
// Get all the form fields that need validation into an Array
let fields = Array.prototype.slice.call(document.querySelectorAll(".validationNeeded"));
// Set up form submit event handler
document.querySelector("form").addEventListener("submit", checkEmptyFields);
function checkEmptyFields(event) {
let validCount = fields.length; // Holds the number of valid fields
// Loop over the array
fields.forEach(function(field){
if(field.value === ""){
field.previousElementSibling.classList.add("has-errors-label"); // style the label
field.classList.add("has-errors-field"); // style the field
field.classList.remove("valid-field"); // style the field
validCount--; // Decrease the count of valid fields
} else {
field.previousElementSibling.classList.remove("has-errors-label"); // style the label
field.classList.remove("has-errors-field"); // style the field
field.classList.add("valid-field"); // style the field
}
});
// Check to see if the form should be submitted
if(validCount !== fields.length){
event.preventDefault(); // Cancel the form's submission
}
}
.row {margin-bottom:5px; }
.has-errors-label { color:red; }
.has-errors-field { outline:1px solid red; }
.valid-field { outline:1px solid green; }
<form action="#" method="get">
<div class="row">
<label for="userName">Name: </label>
<input class="validationNeeded" name="userName" id="userName">
</div>
<div class="row">
<label for="email">Email: </label>
<input class="validationNeeded" name="email" id="email">
</div>
<div class="row">
<label for="phone">Phone: </label>
<input class="validationNeeded" name="phone" id="phone">
</div>
<button>Submit</button>
</form>
Upvotes: 0
Reputation: 24137
You can create arrays for both the controls and the control names, and process them together with the formLabels
array that you already have, in a for-loop that goes from 0 to length (not inclusive), like this:
function checkEmptyFields() {
var controls = [formName, formEmail, formNumber, formMessage];
var controlNames = ["Name", "Email", "Phone", "Message"];
for (var i = 0; i < controls.length; i++) {
if(controls[i].value === "") {
formLabels[i].classList.add("has-errors");
formLabels[i].innerHTML = controlNames[i] + " is required *";
controls[i].style.borderBottomColor = "red";
} else {
formLabels[i].classList.remove("has-errors");
formLabels[i].innerHTML = controlNames[i];
controls[i].style.borderBottomColor = "green";
}
}
}
Upvotes: 1
Reputation: 915
If you know about and understand for loops you can simply loop over 2 arrays of data like this:
function checkEmptyFields() {
formArray = [formName, formEmail, formNumber, formMessage];
labelArray = ["Name", "Email", "Phone", "Message"];
for (let i = 0; i < formArray.length; i++) {
if(formArray[i].value === "") {
formLabels[i].classList.add("has-errors");
formLabels[i].innerHTML = labelArray[i] + " is required *";
formArray[i].style.borderBottomColor = "red";
} else {
formLabels[i].classList.remove("has-errors");
formLabels[i].innerHTML = labelArray[i];
formArray[i].style.borderBottomColor = "green";
}
}
}
if not then you can read about them here:
https://www.w3schools.com/js/js_loop_for.asp
Upvotes: 0
Reputation: 469
You can write an additional function to check one field:
function checkEmptyField(field, ind, msg, errmsg) {
if(field.value === "") {
formLabels[ind].classList.add("has-errors");
formLabels[ind].innerHTML = errmsg;
field.style.borderBottomColor = "red";
} else {
formLabels[ind].classList.remove("has-errors");
formLabels[ind].innerHTML = msg;
field.style.borderBottomColor = "green";
}
}
Then you can call it
function checkEmptyFields() {
checkEmptyField(formName,0,"Name","Name is required *");
...
Upvotes: 0