31 KiB
id, title, challengeType, dashedName, demoType
| id | title | challengeType | dashedName | demoType |
|---|---|---|---|---|
| 67279fe50237291f80eed8b8 | Build a Customer Complaint Form | 25 | build-a-customer-complaint-form | onClick |
--description--
For this lab, you have been provided with all the HTML and CSS. You will use JavaScript to validate the complaint form.
Objective: Fulfill the user stories below and get all the tests to pass to complete the lab.
User Stories:
- When the form is submitted, you should ensure that:
#full-nameis not empty.#emailis a valid email address format.#order-nois a sequence of ten numbers starting with2024.#product-codefollows the patternXX##-X###-XX#, whereXrepresents either a lowercase letter or an uppercase letter and#represents a number.#quantityis a positive integer.- at least one checkbox from
#complaints-groupis checked. #complaint-descriptioncontains at least twenty characters if theOthercheckbox is checked.- a radio button from
#solutions-groupis selected. #solution-descriptioncontains at least twenty characters if theOtherradio button is selected.
- You should have a function named
validateFormthat returns an object containing the following keys:full-name,email,order-no,product-code,quantity,complaints-group,complaint-description,solutions-group, andsolution-description. The value of each key should betrueif the corresponding form field is correctly filled andfalseotherwise. The conditional description fields should betruewhen they are not required, and otherwise validated based on whether they contain at least twenty characters. - You should have a function named
isValidthat takes the object returned byvalidateFormas argument and returnstrueif every form field is correctly filled andfalseotherwise. - If a change event is triggered on a form field and it has a valid value, you should set its border color to
green. In case of checkbox and radio button groups, you should set the border color of the parentfieldset. - If a change event is triggered on a form field and it has an invalid value, you should set its border color to
red. In case of checkbox and radio button groups, you should set the border color of the parentfieldset. - When you try to submit the form you should call
isValidto validate the form. - When you try to submit the form, if the form has any invalid field, each invalid field should be highlighted by setting the border color of each invalid input, textarea or fieldset (in case of checkbox and radio button groups) to
red.
--hints--
You should have a function named validateForm.
assert.isFunction(validateForm);
validateForm should return an object.
assert.isObject(validateForm());
validateForm()["full-name"] should be false when #full-name is empty, and true otherwise.
const field = document.getElementById("full-name");
field.value = "";
assert.isFalse(validateForm()["full-name"]);
field.value = "testing";
assert.isTrue(validateForm()["full-name"]);
When a change event is triggered on #full-name, you should set its border color to green if it contains a valid value, and red otherwise.
const field = document.getElementById("full-name");
field.value = "testing"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "green");
field.value = ""
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "red");
validateForm()["email"] should be true when #email contains a valid email address, and false otherwise.
const field = document.getElementById("email");
field.value = "example@domain.com"
assert.isTrue(validateForm()["email"]);
field.value = "testing"
assert.isFalse(validateForm()["email"]);
When a change event is triggered on #email, you should set its border color to green if it contains a valid email address, and red otherwise.
const field = document.getElementById("email");
field.value = "example@domain.com"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "green");
field.value = ""
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "red");
validateForm()["order-no"] should be true when #order-no contains a valid value, and false otherwise.
const field = document.getElementById("order-no");
field.value = "2024001122"
assert.isTrue(validateForm()["order-no"]);
field.value = "testing"
assert.isFalse(validateForm()["order-no"]);
When a change event is triggered on #order-no, you should set its border color to green if it contains a valid value, and red otherwise.
const field = document.getElementById("order-no");
field.value = "2024001122"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "green");
field.value = "20240011"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "red");
validateForm()["product-code"] should be true when #product-code contains a valid value, and false otherwise.
const field = document.getElementById("product-code");
field.value = "Xa22-X123-Xb4";
assert.isTrue(validateForm()["product-code"]);
field.value = "testing"
assert.isFalse(validateForm()["product-code"]);
When a change event is triggered on #product-code, you should set its border color to green if it contains a valid value, and red otherwise.
const field = document.getElementById("product-code");
field.value = "Xa22-X123-Xb4"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "green");
field.value = "Xa22-123-Xb4"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "red");
validateForm()["quantity"] should be true when #quantity contains a valid value, and false otherwise.
const field = document.getElementById("quantity");
field.value = "5";
assert.isTrue(validateForm()["quantity"]);
field.value = "0";
assert.isFalse(validateForm()["quantity"]);
When a change event is triggered on #quantity, you should set its border color to green if it contains a valid value, and red otherwise.
const field = document.getElementById("quantity");
field.value = "2"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "green");
field.value = "0"
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "red");
When at least one checkbox from #complaints-group is checked, validateForm()["complaints-group"] should be true.
document.getElementById("damaged-product").checked = true
assert.isTrue(validateForm()["complaints-group"]);
When none of the checkboxes from #complaints-group is checked, validateForm()["complaints-group"] should be false.
document.getElementById("damaged-product").checked = false;
document.getElementById("nonconforming-product").checked = false;
document.getElementById("delayed-dispatch").checked = false;
document.getElementById("other-complaint").checked = false;
assert.isFalse(validateForm()["complaints-group"]);
Once one checkbox from #complaints-group is checked, you should set #complaints-group's border color to green.
document.getElementById("nonconforming-product").checked = false;
document.getElementById("delayed-dispatch").checked = false;
document.getElementById("other-complaint").checked = false;
const damagedProduct = document.getElementById("damaged-product");
damagedProduct.checked = true;
damagedProduct.dispatchEvent(new Event("change", { bubbles: true }));
const fieldset = document.getElementById("complaints-group");
assert.equal(fieldset.style.borderColor, "green");
When all of the checkboxes from #complaints-group are changed to the unchecked state, you should set #complaints-group's border color to red.
document.getElementById("damaged-product").checked = false;
document.getElementById("delayed-dispatch").checked = false;
document.getElementById("other-complaint").checked = false;
const nonConfProduct = document.getElementById("nonconforming-product");
nonConfProduct.checked = false;
nonConfProduct.dispatchEvent(new Event("change", { bubbles: true }));
const fieldset = document.getElementById("complaints-group");
assert.equal(fieldset.style.borderColor, "red");
When #other-complaint is not checked, validateForm()["complaint-description"] should be true.
document.getElementById("other-complaint").checked = false;
assert.isTrue(validateForm()["complaint-description"]);
When #other-complaint is checked and #complaint-description contains at least twenty characters, validateForm()["complaint-description"] should be true.
document.getElementById("other-complaint").checked = true
document.getElementById("complaint-description").value = "A sentence with at least twenty characters";
assert.isTrue(validateForm()["complaint-description"]);
When #other-complaint is checked and #complaint-description contains less than twenty characters, validateForm()["complaint-description"] should be false.
document.getElementById("other-complaint").checked = true
document.getElementById("complaint-description").value = "Less than 20 chars";
assert.isFalse(validateForm()["complaint-description"]);
When #other-complaint is checked and the value of #complaint-description is changed to a valid value, you should set its border color to green.
document.getElementById("other-complaint").checked = true;
const field = document.getElementById("complaint-description");
field.value = "A sentence with at least twenty characters"
field.dispatchEvent(new Event("input", { bubbles: true }));
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "green");
When #other-complaint is checked and the value of #complaint-description is changed to an invalid value, you should set its border color to red.
document.getElementById("other-complaint").checked = true;
const field = document.getElementById("complaint-description");
field.value = "Not enough chars"
field.dispatchEvent(new Event("input", { bubbles: true }));
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "red");
When a radio button from #solutions-group is checked, validateForm()["solutions-group"] should be true.
document.getElementById("refund").checked = true
assert.isTrue(validateForm()["solutions-group"]);
When none of the radio buttons from #solutions-group is checked, validateForm()["solutions-group"] should be false.
document.getElementById("refund").checked = false;
document.getElementById("exchange").checked = false;
document.getElementById("other-solution").checked = false;
assert.isFalse(validateForm()["solutions-group"]);
Once a radio button from #solutions-group is checked, you should set #solutions-group's border color to green.
document.getElementById("exchange").checked = false;
document.getElementById("other-solution").checked = false;
const refundRadioBtn = document.getElementById("refund");
refundRadioBtn.checked = true;
refundRadioBtn.dispatchEvent(new Event("change", { bubbles: true }));
const fieldset = document.getElementById("solutions-group");
assert.equal(fieldset.style.borderColor, "green");
When all of the radio buttons from #solutions-group are in the unchecked state after a change event, you should set #solutions-group's border color to red.
document.getElementById("refund").checked = false;
document.getElementById("other-solution").checked = false;
const exchangeRadioBtn = document.getElementById("exchange");
exchangeRadioBtn.checked = false;
exchangeRadioBtn.dispatchEvent(new Event("change", { bubbles: true }));
const fieldset = document.getElementById("solutions-group");
assert.equal(fieldset.style.borderColor, "red");
When #other-solution is not checked, validateForm()["solution-description"] should be true.
document.getElementById("other-solution").checked = false;
assert.isTrue(validateForm()["solution-description"]);
When #other-solution is checked and #solution-description contains at least twenty characters, validateForm()["solution-description"] should be true.
document.getElementById("other-solution").checked = true
document.getElementById("solution-description").value = "A sentence with at least twenty characters";
assert.isTrue(validateForm()["solution-description"]);
When #other-solution is checked and #solution-description contains less than twenty characters, validateForm()["solution-description"] should be false.
document.getElementById("other-solution").checked = true
document.getElementById("solution-description").value = "Less than 20 chars";
assert.isFalse(validateForm()["solution-description"]);
When #other-solution is checked and the value of #solution-description is changed to a valid value, you should set its border color to green.
document.getElementById("other-solution").checked = true;
const field = document.getElementById("solution-description");
field.value = "A sentence with at least twenty characters"
field.dispatchEvent(new Event("input", { bubbles: true }));
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "green");
When #other-solution is checked and the value of #solution-description is changed to an invalid value, you should set its border color to red.
document.getElementById("other-solution").checked = true;
const field = document.getElementById("solution-description");
field.value = "Not enough chars"
field.dispatchEvent(new Event("input", { bubbles: true }));
field.dispatchEvent(new Event("change", { bubbles: true }));
assert.equal(field.style.borderColor, "red");
You should have a function named isValid.
assert.isFunction(isValid);
Your isValid function should take the validateForm() as its argument and return true when all the form fields have been filled correctly.
document.getElementById("full-name").value = "testing"
document.getElementById("email").value = "example@domain.com"
document.getElementById("order-no").value = "2024001122"
document.getElementById("product-code").value = "Xa22-X123-Xb4"
document.getElementById("quantity").value = "5"
document.getElementById("damaged-product").checked = true
document.getElementById("other-complaint").checked = false
document.getElementById("refund").checked = true
document.getElementById("other-solution").checked = false
assert.isTrue(isValid(validateForm()));
document.getElementById("other-complaint").checked = true
document.getElementById("complaint-description").value = "A sentence with at least twenty characters";
document.getElementById("other-solution").checked = true
document.getElementById("solution-description").value = "A sentence with at least twenty characters";
assert.isTrue(isValid(validateForm()));
Your isValid function should take the validateForm() as its argument and return false when not all the form fields have been filled correctly.
const name = document.getElementById("full-name");
const email = document.getElementById("email");
const orderNo = document.getElementById("order-no");
const prCode = document.getElementById("product-code");
const quantity = document.getElementById("quantity");
const damaged = document.getElementById("damaged-product");
const nonConforming = document.getElementById("nonconforming-product");
const delayed = document.getElementById("delayed-dispatch");
const otherC = document.getElementById("other-complaint");
const complaintDescr = document.getElementById("complaint-description");
const refund = document.getElementById("refund");
const exchange = document.getElementById("exchange");
const otherS = document.getElementById("other-solution");
const solutionDescr = document.getElementById("solution-description");
// invalid full-name
name.value = "";
email.value = "example@domain.com";
orderNo.value = "2024001122";
prCode.value = "Xa22-X123-Xb4";
quantity.value = "5";
damaged.checked = true;
refund.checked = true;
assert.isFalse(isValid(validateForm()));
// invalid email
name.value = "testing";
email.value = "";
assert.isFalse(isValid(validateForm()));
// invalid order-no
email.value = "example@domain.com";
orderNo.value = "202400";
assert.isFalse(isValid(validateForm()));
// invalid product-code
orderNo.value = "2024001122";
prCode.value = "1a22-Xa23-Xb4";
assert.isFalse(isValid(validateForm()));
// invalid quantity
prCode.value = "Xa22-X123-Xb4";
quantity.value = 0;
assert.isFalse(isValid(validateForm()));
// invalid complaints-group
quantity.value = 5;
damaged.checked = false;
nonConforming.checked = false;
delayed.checked = false;
otherC.checked = false;
assert.isFalse(isValid(validateForm()));
// invalid complaint-description
otherC.checked = true;
complaintDescr.value = "not enough chars";
assert.isFalse(isValid(validateForm()));
// invalid solutions-group
complaintDescr.value = "A sentence with at least twenty characters";
refund.checked = false;
exchange.checked = false;
otherS.checked = false;
assert.isFalse(isValid(validateForm()));
// invalid solutions-description
otherS.checked = true;
solutionDescr.value = "not enough chars";
assert.isFalse(isValid(validateForm()));
You should call isValid when you try to submit the form.
let flag = false;
const temp = isValid;
try {
isValid = (obj) => {flag = true};
document.getElementById("form").dispatchEvent(new Event("submit"));
assert.isTrue(flag);
} finally {
isValid = temp;
}
--seed--
--seed-contents--
<!DOCTYPE html>
<html lang="en">
<head>
<title>Customer Complaint Form</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Complaint Form</h1>
<form id="form">
<fieldset id="personal-info">
<div>
<label for="full-name">Full Name:</label>
<input type="text" id="full-name" name="full-name" placeholder="John Doe">
</div>
<div>
<label for="email">Email Address:</label>
<input type="email" id="email" name="email" placeholder="example@domain.com">
</div>
</fieldset>
<hr>
<fieldset id="product-info">
<div>
<label for="order-no">Order No:</label>
<input type="text" id="order-no" name="order-no" placeholder="2024######">
</div>
<div>
<label for="product-code">Product Code:</label>
<input type="text" id="product-code" name="product-code" placeholder="XX##-X###-XX#">
</div>
<div>
<label for="quantity">Quantity:</label>
<input type="number" id="quantity" name="quantity" min="1">
</div>
</fieldset>
<fieldset id="complaints-group">
<legend>Complaint Reason:</legend>
<div>
<input type="checkbox" id="damaged-product" name="complaint" value="damaged-product">
<label for="damaged-product">Damaged Product</label>
</div>
<div>
<input type="checkbox" id="nonconforming-product" name="complaint" value="nonconforming-product">
<label for="nonconforming-product">Nonconforming Product</label>
</div>
<div>
<input type="checkbox" id="delayed-dispatch" name="complaint" value="delayed-dispatch">
<label for="delayed-dispatch">Delayed Dispatch</label>
</div>
<div>
<input type="checkbox" id="other-complaint" name="complaint" value="other">
<label for="other-complaint">Other</label>
</div>
</fieldset>
<fieldset id="complaint-description-container">
<legend>Description of Complaint Reason</legend>
<textarea placeholder="Describe the reason of your complaint in at least 20 characters"
name="complaint-textarea" id="complaint-description"></textarea>
</fieldset>
<fieldset id="solutions-group">
<legend>Desired Solution</legend>
<input type="radio" name="solutions" id="refund" value="refund">
<label for="refund">Refund</label>
<input type="radio" name="solutions" id="exchange" value="exchange">
<label for="exchange">Exchange</label>
<input type="radio" name="solutions" id="other-solution" value="other">
<label for="other-solution">Other</label>
</fieldset>
<fieldset id="solution-description-container">
<legend>Description of Desired Solution</legend>
<textarea placeholder="Describe the desired solution to your issue in at least 20 characters"
name="solution-textarea" id="solution-description"></textarea>
</fieldset>
<div id="btn-container">
<button type="submit" id="submit-btn">Submit</button>
<span id="message-box" aria-live="polite"></span>
</div>
</form>
<script src="script.js"></script>
</body>
</html>
* {
box-sizing: border-box;
}
h1 {
text-align: center;
}
#form {
max-width: 70%;
margin: auto;
border-radius: 10px;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
padding: 10px;
}
input {
border-color: rgb(118, 118, 118);
}
#personal-info input, #product-info input {
width: 100%;
margin-bottom: 10px;
}
fieldset {
margin-bottom: 10px;
border-radius: 5px;
border-color: rgb(118, 118, 118);
}
textarea {
width: 100%;
border-color: rgb(118, 118, 118);
}
#btn-container {
display: flex;
justify-content: space-between;
align-items: center;
}
#submit-btn, #clear-btn {
margin: 10px 15px 0;
}
--solutions--
<!DOCTYPE html>
<html lang="en">
<head>
<title>Customer Complaint Form</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Complaint Form</h1>
<form id="form">
<fieldset id="personal-info">
<div>
<label for="full-name">Full Name:</label>
<input type="text" id="full-name" name="full-name" placeholder="John Doe">
</div>
<div>
<label for="email">Email Address:</label>
<input type="email" id="email" name="email" placeholder="example@domain.com">
</div>
</fieldset>
<hr>
<fieldset id="product-info">
<div>
<label for="order-no">Order No:</label>
<input type="text" id="order-no" name="order-no" placeholder="2024######">
</div>
<div>
<label for="product-code">Product Code:</label>
<input type="text" id="product-code" name="product-code" placeholder="XX##-X###-XX#">
</div>
<div>
<label for="quantity">Quantity:</label>
<input type="number" id="quantity" name="quantity" min="1">
</div>
</fieldset>
<fieldset id="complaints-group">
<legend>Complaint Reason:</legend>
<div>
<input type="checkbox" id="damaged-product" name="complaint" value="damaged-product">
<label for="damaged-product">Damaged Product</label>
</div>
<div>
<input type="checkbox" id="nonconforming-product" name="complaint" value="nonconforming-product">
<label for="nonconforming-product">Nonconforming Product</label>
</div>
<div>
<input type="checkbox" id="delayed-dispatch" name="complaint" value="delayed-dispatch">
<label for="delayed-dispatch">Delayed Dispatch</label>
</div>
<div>
<input type="checkbox" id="other-complaint" name="complaint" value="other">
<label for="other-complaint">Other</label>
</div>
</fieldset>
<fieldset id="complaint-description-container">
<legend>Description of Complaint Reason</legend>
<textarea placeholder="Describe the reason of your complaint in at least 20 characters"
name="complaint-textarea" id="complaint-description"></textarea>
</fieldset>
<fieldset id="solutions-group">
<legend>Desired Solution</legend>
<input type="radio" name="solutions" id="refund" value="refund">
<label for="refund">Refund</label>
<input type="radio" name="solutions" id="exchange" value="exchange">
<label for="exchange">Exchange</label>
<input type="radio" name="solutions" id="other-solution" value="other">
<label for="other-solution">Other</label>
</fieldset>
<fieldset id="solution-description-container">
<legend>Description of Desired Solution</legend>
<textarea placeholder="Describe the desired solution to your issue in at least 20 characters"
name="solution-textarea" id="solution-description"></textarea>
</fieldset>
<div id="btn-container">
<button type="submit" id="submit-btn">Submit</button>
<span id="message-box" aria-live="polite"></span>
<button type="button" id="clear-btn">Clear</button>
</div>
</form>
<script src="script.js"></script>
</body>
</html>
* {
box-sizing: border-box;
}
h1 {
text-align: center;
}
#form {
max-width: 70%;
margin: auto;
border-radius: 10px;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
padding: 10px;
}
input {
border-color: rgb(118, 118, 118);
}
#personal-info input, #product-info input {
width: 100%;
margin-bottom: 10px;
}
fieldset {
margin-bottom: 10px;
border-radius: 5px;
border-color: rgb(118, 118, 118);
}
textarea {
width: 100%;
border-color: rgb(118, 118, 118);
}
#btn-container {
display: flex;
justify-content: space-between;
align-items: center;
}
#submit-btn, #clear-btn {
margin: 10px 15px 0;
}
const form = document.getElementById("form");
const fullName = document.getElementById("full-name");
const emailAddress = document.getElementById("email");
const orderNo = document.getElementById("order-no");
const productCode = document.getElementById("product-code");
const quantity = document.getElementById("quantity");
const complaints = document.querySelectorAll('input[name="complaint"]');
const complaintDescription = document.getElementById("complaint-description");
const complaintTextAreaDiv = document.getElementById("complaint-description-container");
const solutions = document.querySelectorAll('input[name="solutions"]');
const solutionDescription = document.getElementById("solution-description");
const solutionTextAreaDiv = document.getElementById("solution-description-container");
const submitBtn = document.getElementById("submit-btn");
const messageBox = document.getElementById("message-box");
const clearBtn = document.getElementById("clear-btn");
const hideTextareas = () => {
complaintTextAreaDiv.style.display = "none";
solutionTextAreaDiv.style.display = "none";
}
hideTextareas();
const formFields = {
"full-name": fullName,
"email": emailAddress,
"order-no": orderNo,
"product-code": productCode,
"quantity": quantity,
"complaints-group": Array.from(complaints),
"complaint-description": complaintDescription,
"solutions-group": Array.from(solutions),
"solution-description": solutionDescription
}
const clearForm = () => {
Object.entries(formFields).forEach(entry => {
const [key, val] = entry;
if (Array.isArray(val)) {
val.forEach(i => i.checked = false);
} else {
val.value = "";
}
hideTextareas();
messageBox.innerText = "";
document.getElementById(key).style.borderColor = "rgb(118, 118, 118)";
})
}
const validateForm = () => {
const complaintsArr = Array.from(complaints).map(i => i.checked);
const solutionsArr = Array.from(solutions).map(i => i.checked);
const validationObject = {
"full-name": Boolean(fullName.value.trim()),
"email": /^\S+@\S+\.\S+$/.test(emailAddress.value.trim()),
"order-no": /^2024\d{6}$/.test(orderNo.value.trim()),
"product-code": /[A-Z]{2}\d{2}-[A-Z]\d{3}-[A-Z]{2}\d/i.test(productCode.value.trim()),
"quantity": Number(quantity.value.trim()) > 0,
"complaints-group": complaintsArr.some(i => i),
"complaint-description": true,
"solutions-group": solutionsArr.some(i => i),
"solution-description": true
}
if (complaintsArr[3]) {
complaintTextAreaDiv.style.display = "block";
const complaintsDescriptionVal = complaintDescription.value.trim();
if (complaintsDescriptionVal.length < 20) {
validationObject["complaint-description"] = false;
} else {
validationObject["complaint-description"] = true;
}
} else {
complaintTextAreaDiv.style.display = "none";
}
if (solutionsArr[2]) {
solutionTextAreaDiv.style.display = "block";
const solutionDescriptionVal = solutionDescription.value.trim();
if (solutionDescriptionVal.length < 20) {
validationObject["solution-description"] = false;
} else {
validationObject["solution-description"] = true;
}
} else {
solutionTextAreaDiv.style.display = "none";
}
return validationObject;
}
clearBtn.addEventListener("click", clearForm);
Object.keys(formFields).forEach(key => {
document.getElementById(key).addEventListener("change", (e) => {
const validationObject = validateForm();
if (Object.values(validationObject).every(val => val)) messageBox.innerText = "";
if (!validationObject[key]) {
document.getElementById(key).style.borderColor = "red";
} else {
document.getElementById(key).style.borderColor = "green";
}
});
});
const isValid = (validationObj) => Object.values(validationObj).every(i => i);
form.addEventListener("submit", (e) => {
e.preventDefault();
const validationObject = validateForm();
if (!isValid(validationObject)) {
messageBox.innerText = "Please, fill out the required fields correctly before submitting.";
Object.keys(validationObject).forEach(key => {
if (!validationObject[key]) {
document.getElementById(key).style.borderColor = "red";
} else {
document.getElementById(key).style.borderColor = "green";
}
});
} else {
messageBox.innerText = "";
alert("Form successfully submitted.");
clearForm();
}
});