Back to Freecodecamp

Build a Customer Complaint Form

curriculum/challenges/english/blocks/lab-customer-complaint-form/67279fe50237291f80eed8b8.md

latest30.5 KB
Original Source

--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:

  1. When the form is submitted, you should ensure that:
    • #full-name is not empty.
    • #email is a valid email address format.
    • #order-no is a sequence of ten numbers starting with 2024.
    • #product-code follows the pattern XX##-X###-XX#, where X represents either a lowercase letter or an uppercase letter and # represents a number.
    • #quantity is a positive integer.
    • at least one checkbox from #complaints-group is checked.
    • #complaint-description contains at least twenty characters if the Other checkbox is checked.
    • a radio button from #solutions-group is selected.
    • #solution-description contains at least twenty characters if the Other radio button is selected.
  2. You should have a function named validateForm that returns an object containing the following keys: full-name, email, order-no, product-code, quantity, complaints-group, complaint-description, solutions-group, and solution-description. The value of each key should be true if the corresponding form field is correctly filled and false otherwise.
  3. You should have a function named isValid that takes the object returned by validateForm as argument and returns true if every form field is correctly filled and false otherwise.
  4. 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 parent fieldset.
  5. 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 parent fieldset.
  6. When you try to submit the form you should call isValid to validate the form.
  7. 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.

js
assert.isFunction(validateForm);

validateForm should return an object.

js
assert.isObject(validateForm());

validateForm()["full-name"] should be false when #full-name is empty, and true otherwise.

js
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.

js
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.

js
const field = document.getElementById("email");
field.value = "[email protected]"
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.

js
const field = document.getElementById("email");
field.value = "[email protected]"
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.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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 checked and #complaint-description contains at least twenty characters, validateForm()["complaint-description"] should be true.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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.

js
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 checked and #solution-description contains at least twenty characters, validateForm()["solution-description"] should be true.

js
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.

js
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.

js
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.

js
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.

js
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.

js
document.getElementById("full-name").value = "testing"
document.getElementById("email").value = "[email protected]"
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.

js
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 = "[email protected]";
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 = "[email protected]";
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.

js
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--

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">
            </div>

            <div>
                <label for="email">Email Address:</label>
                <input type="email" id="email" name="email" placeholder="[email protected]">
            </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>
css
* {
    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;
}
js

--solutions--

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">
            </div>

            <div>
                <label for="email">Email Address:</label>
                <input type="email" id="email" name="email" placeholder="[email protected]">
            </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>
css
* {
    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;
}
js
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": null,
        "solutions-group": solutionsArr.some(i => i),
        "solution-description": null
    }

    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";
    }
    if (validationObject["complaint-description"] === null) delete validationObject["complaint-description"];
    if (validationObject["solution-description"] === null) delete validationObject["solution-description"];

    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();
    }
});