Tell us what’s happening:
I want to inform others about an issue that I just spent 5+ hours trying to figure out. No matter what I did, I could not get Test #30 to pass, because I was too focused on isValid() trying to pass, no matter what I tried, researched, and attempted. There were no posts on the forum with a valid solution.
ANSWER: It was because I was so used to adding a /g in my regex statements that it kept failing test #30, so if #30 is failing, make sure to test your regex for “/g” if you are using .test()
Please ignore the additional bits in my JS - I did just about everything I could think of to debug this
Your code so far
<!-- file: index.html -->
/* file: styles.css */
/* file: script.js */
const form = document.querySelector("form");
function serializeFormData(form) {
var formData = new FormData(form);
var serializedData = {};
for (var [name, value] of formData) {
if (serializedData[name]) {
if (!Array.isArray(serializedData[name])) {
serializedData[name] = [serializedData[name]];
}
serializedData[name].push(value);
} else {
serializedData[name] = value;
}
}
return serializedData;
}
const groups = ["solutions", "complaint"]
const productCodeRegex = /([A-z]{2}\d{2})\-([A-z]{1}\d{3})\-([A-z]{2}\d{1})/;
const fullName = document.getElementById("full-name");
const email = document.getElementById("email");
const orderNo = document.getElementById("order-no");
const productCode = document.getElementById("product-code");
const quantity = document.getElementById("quantity");
const complaintFieldset = document.getElementById("complaints-group")
const complaintBoxes = document.querySelectorAll('input[name="complaint"]');
const complaintDescription = document.getElementById("complaint-description")
const solutionFieldset = document.getElementById("solution-group")
const solutionBoxes = document.querySelectorAll('input[name="solutions"]');
const solutionDescription = document.getElementById("solution-description");
form.addEventListener("submit", (e) => {
e.preventDefault();
console.log("IS VALID FORM:", isValid(validateForm()));
if (isValid(validateForm())) {
// form.submit();
console.log("Form Submitted")
console.log(formValues);
return true;
} else {
console.log("Error - not submitted")
console.log(validateForm());
console.log(serializeFormData(form))
return false;
}
})
const keyValue = (input) => Object.entries(input).forEach(([key,value]) => {
console.log(key,value)
})
function isValid(obj) {
console.log("==============")
keyValue(obj)
console.log(`isValid: ` + Object.values(obj).every(Boolean))
console.log(serializeFormData(form))
return Object.values(obj).every(Boolean)
}
// const isValid = (results) => Object.values(results).every(Boolean);
// const formIsValid = isValid(validateForm());
function validateForm() {
const formValues = {
"full-name": false,
"email": false,
"order-no": false,
"product-code": false,
"quantity": false,
"complaints-group": false,
"complaint-description": false,
"solutions-group": false,
"solution-description": false
}
formValues["full-name"] = fullName.value.trim().length > 0;
// formValues['email'] = email.checkValidity(); // not working in tests?
formValues['email'] = email.value.includes("@") && email.value.includes(".");
const orderNoValue = orderNo.value;
formValues['order-no'] = (/2024\d{6}/.test(orderNoValue) && orderNoValue.length == 10);
formValues['product-code'] = productCodeRegex.test(productCode.value);
const quantityValue = quantity.value;
formValues['quantity'] = (/^\d+$/.test(quantityValue) && parseInt(quantityValue, 10) >= 1);
/// complaint checkboxes
formValues["complaints-group"] = Array.from(complaintBoxes).some(cb => cb.checked);
if (document.getElementById("other-complaint")?.checked) {
if (complaintDescription.value.length >= 20) {
formValues["complaint-description"] = true;
complaintDescription.style.borderColor = "green"
} else {
formValues["complaint-description"] = false;
complaintDescription.style.borderColor = "red"
}
} else {
formValues["complaint-description"] = true;
}
// solution radios
formValues["solutions-group"] = Array.from(solutionBoxes).some(rb => rb.checked);
if (document.getElementById("other-solution")?.checked) {
if (solutionDescription.value.length >= 20) {
formValues["solution-description"] = true;
solutionDescription.style.borderColor = "green"
} else {
formValues["solution-description"] = false;
solutionDescription.style.borderColor = "red"
}
} else {
formValues["solution-description"] = true;
}
return formValues;
}
const inputs = form.querySelectorAll("input");
const textareas = form.querySelectorAll("textarea");
const combined = [...inputs, ...textareas]
for (const input of combined) {
input.addEventListener('change', () => {
const updatedFormValues = validateForm()
// console.log(`Changed ${input.name}`)
const isGroup = groups.includes(input.name);
let inputName = "";
if (input.name.includes("complaint")) {
inputName = "complaints";
} else if (input.name.includes("solution")) {
inputName = "solutions";
}
let key = isGroup ? `${inputName}-group` : input.id;
// if (key.includes("textarea")) key = key.replace("textarea", "description")
const target = isGroup ? input.closest("fieldset") : input;
const isValidKey = updatedFormValues[key];
console.log("===========")
console.log("Changed input:", input.name, "Key:", key, "Valid?", isValidKey, "Value:", input.value);
console.log(updatedFormValues);
console.log(serializeFormData(form))
console.log("===========")
// Update border color
// manual override as textareas are checked in formValues but ONLY if conditions are met
if (!input.name.includes("textarea"))
target.style.borderColor = isValidKey ? "green" : "red";
})
}