Build a Customer Complaint Form - Build a Customer Complaint Form

Tell us what’s happening:

Estoy atascado en el proyecto de validación de formularios. Hay cuatro pruebas que fallan constantemente:

Prueba 8: Cambio de evento en el color del borde de #order-no.
Prueba 9: validación de validateForm()[“product-code”].
Prueba 10: Cambio de evento en el color del borde de #product-code.
Prueba 30: función isValid().

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">
            </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>
/* file: styles.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;
}

/* file: script.js */
// Declarar referencias globales
let fullNameInput, inputEmail, inputOrder, inputProductCode, inputQuantity;
let otherComplaintCheckbox, complaintDescription, form;
let complaintsGroupContainer, solutionsGroupContainer;
let complaintInputs, solutionInputs;
let otherSolutionCheckbox, solutionDescriptionInput;

// Funciones globales (accesibles para tests)
function validateForm() {
  const validationStatus = {};
  
  validationStatus["full-name"] = fullNameInput.value.trim() !== "";
  validationStatus["email"] = inputEmail.value.includes("@") && inputEmail.value.includes(".");
  validationStatus["order-no"] = /^[0-9]+$/.test(inputOrder.value) && Number(inputOrder.value) > 0;
  validationStatus["product-code"] = /^[a-zA-Z0-9]+$/.test(inputProductCode.value);
  validationStatus["quantity"] = !isNaN(inputQuantity.value) && Number(inputQuantity.value) > 0;
  validationStatus["complaint-description"] = otherComplaintCheckbox.checked ? complaintDescription.value.trim().length >= 20 : true;
  validationStatus["solution-description"] = otherSolutionCheckbox.checked ? solutionDescriptionInput.value.trim().length >= 20 : true;
  validationStatus["complaints-group"] = Array.from(complaintInputs).some(cb => cb.checked);
  validationStatus["solutions-group"] = Array.from(solutionInputs).some(radio => radio.checked);
  
  return validationStatus;
}

function isValid(status) {
  return Object.values(status).every(val => val === true);
}

function updateBorderStyle(element, valid) {
  if (valid) {
    element.style.borderColor = "green";
  } else {
    element.style.borderColor = "red";
  }
}

// Inicialización cuando el DOM esté listo
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initializeForm);
} else {
  initializeForm();
}

function initializeForm() {
  // Inicializar referencias
  fullNameInput = document.getElementById("full-name");
  inputEmail = document.getElementById("email");
  inputOrder = document.getElementById("order-no");
  inputProductCode = document.getElementById("product-code");
  inputQuantity = document.getElementById("quantity");
  otherComplaintCheckbox = document.getElementById("other-complaint");
  complaintDescription = document.getElementById("complaint-description");
  form = document.querySelector("form");
  complaintsGroupContainer = document.getElementById("complaints-group");
  solutionsGroupContainer = document.getElementById("solutions-group");
  complaintInputs = document.querySelectorAll('#complaints-group input[type="checkbox"]');
  solutionInputs = document.querySelectorAll('input[name="solutions"]');
  otherSolutionCheckbox = document.getElementById("other-solution");
  solutionDescriptionInput = document.getElementById("solution-description");

  // Event listeners
  inputOrder.addEventListener("change", () => {
    updateBorderStyle(inputOrder, validateForm()["order-no"]);
  });

  inputProductCode.addEventListener("change", () => {
    updateBorderStyle(inputProductCode, validateForm()["product-code"]);
  });

  fullNameInput.addEventListener("change", () => {
    updateBorderStyle(fullNameInput, validateForm()["full-name"]);
  });

  inputEmail.addEventListener("change", () => {
    updateBorderStyle(inputEmail, validateForm()["email"]);
  });

  inputQuantity.addEventListener("change", () => {
    updateBorderStyle(inputQuantity, validateForm()["quantity"]);
  });

  complaintInputs.forEach(cb => {
    cb.addEventListener("change", () => {
      updateBorderStyle(complaintsGroupContainer, validateForm()["complaints-group"]);
    });
  });

  complaintDescription.addEventListener("change", () => {
    if (otherComplaintCheckbox.checked) {
      updateBorderStyle(complaintDescription, validateForm()["complaint-description"]);
    }
  });

  solutionInputs.forEach(radio => {
    radio.addEventListener("change", () => {
      updateBorderStyle(solutionsGroupContainer, validateForm()["solutions-group"]);
    });
  });

  solutionDescriptionInput.addEventListener("change", () => {
    if (otherSolutionCheckbox.checked) {
      updateBorderStyle(solutionDescriptionInput, validateForm()["solution-description"]);
    }
  });

  otherSolutionCheckbox.addEventListener("change", () => {
    updateBorderStyle(solutionDescriptionInput, validateForm()["solution-description"]);
  });

  form.addEventListener("submit", (e) => {
    e.preventDefault();
    const status = validateForm();
    
    Object.keys(status).forEach(key => {
      const el = document.getElementById(key) || 
        (key === "complaints-group" ? complaintsGroupContainer : 
         key === "solutions-group" ? solutionsGroupContainer : null);
      if (el) {
        updateBorderStyle(el, status[key]);
      }
    });
    
    if (isValid(status)) {
      console.log("Formulario válido");
    }
  });
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36

Challenge Information:

Build a Customer Complaint Form - Build a Customer Complaint Form