Tell us what’s happening:
It seems like my code has a subtle bug in it! as the test number 15,16 and 23,24 failing!
15 - Once one checkbox from #complaints-group
is checked, you should set #complaints-group
’s border color to green
.
16 - When all of the checkboxes from #complaints-group
are changed to the unchecked state, you should set #complaints-group
’s border color to red
.
23 - Once a radio button from #solutions-group
is checked, you should set #solutions-group
’s border color to green
.
24 - When all of the checkboxes from #complaints-group
are changed to the unchecked state, you should set #complaints-group
’s border color to red
.
Your code so far
<!-- file: index.html -->
<!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" required>
</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>
<div 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>
</div>
<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>
<div 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>
</div>
<div id="btn-container">
<button type="submit" id="submit-btn">Submit</button>
<span id="message-box"></span>
</div>
</form>
<script src="script.js"></script>
</body>
</html>
/* file: styles.css */
:root {
--light-grey: #f5f6f7;
--dark-blue: #0a0a23;
--fcc-blue: #1b1b32;
--light-yellow: #fecc4c;
--dark-yellow: #feac32;
--light-pink: #ffadad;
--dark-red: #850000;
--light-green: #acd157;
}
body {
font-family: "Lato", Helvetica, Arial, sans-serif;
font-size: 18px;
background-color: var(--fcc-blue);
color: var(--light-grey);
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button {
cursor: pointer;
text-decoration: none;
background-color: var(--light-yellow);
border: 2px solid var(--dark-yellow);
}
button,
input,
select {
min-height: 24px;
color: var(--dark-blue);
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid var(--light-grey);
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: var(--light-pink);
}
.deficit {
color: var(--light-green);
}
/* file: script.js */
const complaintForm = document.getElementById('form');
function nameValidator(str) {
return str.trim() !== ""
}
function emailValidator(str) {
const pattern = /\w+@\w+\.\w+/i // acceptable email = a@b.c
return pattern.test(str)
}
function orderNumberValidator(str) {
const pattern = /2024\d{6}/
return pattern.test(str)
}
function productCodeValidator(str) {
const pattern = /[a-z]{2}\d{2}-[a-z]\d{3}-[a-z]{2}\d/i
return pattern.test(str)
}
function productQuantityValidator(str) {
return Number(str) > 0
}
function complaintValidator() {
const complaintReasons = document.querySelectorAll('input[type="checkbox"]');
const otherReason = document.getElementById("other-complaint")
const complaintContainer = document.getElementById("complaint-description-container")
// hiding and showing the element as needed
complaintContainer.style.display = otherReason.checked? "block" : "none";
// we can create an array or use some array functions on this NodeList
return Array.from(complaintReasons).some(reason => reason.checked);
}
function customComplaintValidator(str) {
const otherReason = document.getElementById("other-complaint")
return otherReason.checked && str.length >= 20 || (!otherReason.checked);
}
function solutionValidator() {
const solutions = document.querySelectorAll('input[type="radio"]');
const otherSolution = document.getElementById("other-solution");
const solutionsContainer = document.getElementById("solution-description-container");
// hiding and showing the element as needed
solutionsContainer.style.display = otherSolution.checked? "block" : "none";
// we can create an array or use some array functions on this NodeList
return Array.from(solutions).some(reason => reason.checked);
}
function customSolutionValidator(str) {
const otherSolution = document.getElementById("other-solution");
return (otherSolution.checked && str.length >= 20) || (!otherSolution.checked);
}
function validateForm() {
// getting the elements
const fullName = document.getElementById("full-name")
const emailAddress = document.getElementById("email")
const orderNumber = document.getElementById("order-no")
const productCode = document.getElementById("product-code")
const productQuantity = document.getElementById("quantity")
const complaintDescription = document.getElementById("complaint-description")
const solutionDescription = document.getElementById("solution-description")
// return object containing keys and values as booleans
return {
"full-name": nameValidator(fullName.value),
"email": emailValidator(emailAddress.value),
"order-no": orderNumberValidator(orderNumber.value),
"product-code": productCodeValidator(productCode.value),
"quantity": productQuantityValidator(productQuantity.value),
"complaints-group": complaintValidator(),
"complaint-description": customComplaintValidator(complaintDescription.value),
"solutions-group": solutionValidator(),
"solution-description": customSolutionValidator(solutionDescription.value),
};
}
function isValid(ob) {
return Object.values(ob).every(value => value === true);
}
complaintForm.addEventListener("change", (e) => {
e.stopPropagation();
const complaintReasons = ["damaged-product", "nonconforming-product", "delayed-dispatch", "other-complaint"]
const solutions = ["refund", "exchange", "other-solution"]
if (e.target.id === "full-name") {
e.target.style.borderColor = nameValidator(e.target.value)? "green" : "red";
} else if (e.target.id === "email") {
e.target.style.borderColor = emailValidator(e.target.value)? "green" : "red";
} else if (e.target.id === "order-no") {
e.target.style.borderColor = orderNumberValidator(e.target.value)? "green" : "red";
} else if (e.target.id === "product-code") {
e.target.style.borderColor = productCodeValidator(e.target.value)? "green" : "red";
} else if (e.target.id === "quantity") {
e.target.style.borderColor = productQuantityValidator(e.target.value)? "green" : "red";
} else if (complaintReasons.includes(e.target.id)) {
const fieldset = e.target.closest('fieldset');
fieldset.style.borderColor = complaintValidator()? "green" : "red";
} else if (e.target.id === "complaint-description") {
e.target.style.borderColor = customComplaintValidator(e.target.value)? "green" : "red";
} else if (solutions.includes(e.target.id)) {
const fieldset = e.target.closest('fieldset');
fieldset.style.borderColor = solutionValidator()? "green" : "red";
} else if (e.target.id === "solution-description") {
e.target.style.borderColor = customSolutionValidator(e.target.value)? "green" : "red";
}
})
// it seems like my code has a very subtle bug in it! as it can't pass 15,16 and 23,24 tests
complaintForm.addEventListener("submit", (e) => {
e.preventDefault();
if (isValid(validateForm())) {
console.log(validateForm());
console.log("Form is valid");
} else {
console.log(validateForm());
console.log(validateForm)
console.log("Form is invalid");
}
})
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0
Challenge Information:
Build a Customer Complaint Form - Build a Customer Complaint Form