163 lines
4.7 KiB
JavaScript
163 lines
4.7 KiB
JavaScript
|
function toggleMenu() {
|
||
|
const navList = document.querySelector("nav ul");
|
||
|
navList.classList.toggle("active");
|
||
|
}
|
||
|
|
||
|
const form = document.querySelector(".form-wizard");
|
||
|
const progress = form.querySelector(".progress");
|
||
|
const stepsContainer = form.querySelector(".steps-container");
|
||
|
const steps = form.querySelectorAll(".step");
|
||
|
const stepIndicators = form.querySelectorAll(".progress-container li");
|
||
|
const prevButton = form.querySelector(".prev-btn");
|
||
|
const nextButton = form.querySelector(".next-btn");
|
||
|
const submitButton = form.querySelector(".submit-btn");
|
||
|
const editButton = form.querySelector("#editBtn");
|
||
|
|
||
|
let currentStep = 0;
|
||
|
let formData = JSON.parse(localStorage.getItem("formData")) || {};
|
||
|
|
||
|
// Update progres
|
||
|
const updateProgress = () => {
|
||
|
let width = currentStep / (steps.length - 1);
|
||
|
progress.style.transform = `scaleX(${width})`;
|
||
|
|
||
|
// Update the step indicators
|
||
|
stepIndicators.forEach((indicator, index) => {
|
||
|
indicator.classList.toggle("current", currentStep === index);
|
||
|
indicator.classList.toggle("done", currentStep > index);
|
||
|
});
|
||
|
|
||
|
// Update steps container
|
||
|
stepsContainer.style.height = `${steps[currentStep].offsetHeight}px`;
|
||
|
|
||
|
steps.forEach((step, index) => {
|
||
|
step.style.transform = `translateX(${currentStep * -100}%)`;
|
||
|
step.classList.toggle("current", currentStep === index);
|
||
|
});
|
||
|
|
||
|
updateButtons();
|
||
|
};
|
||
|
|
||
|
// Update button visibility
|
||
|
const updateButtons = () => {
|
||
|
prevButton.hidden = currentStep === 0;
|
||
|
nextButton.hidden = currentStep >= steps.length - 1;
|
||
|
submitButton.hidden = currentStep < steps.length - 1;
|
||
|
editButton.hidden = currentStep !== 2;
|
||
|
};
|
||
|
|
||
|
const isValidStep = () => {
|
||
|
const fields = steps[currentStep].querySelectorAll("input, textarea, select");
|
||
|
let valid = true;
|
||
|
fields.forEach((field) => {
|
||
|
const errorMessage = field.nextElementSibling;
|
||
|
|
||
|
if (field.id === "fullname" && field.value.trim().length < 3) {
|
||
|
valid = false;
|
||
|
if (errorMessage)
|
||
|
errorMessage.textContent = "Minimum 3 letters required.";
|
||
|
} else if (field.id === "phone" && !/^\d{10}$/.test(field.value)) {
|
||
|
valid = false;
|
||
|
if (errorMessage)
|
||
|
errorMessage.textContent = "Phone number must be 10 digits.";
|
||
|
} else {
|
||
|
if (errorMessage) errorMessage.textContent = "";
|
||
|
}
|
||
|
|
||
|
if (!field.checkValidity()) {
|
||
|
valid = false;
|
||
|
}
|
||
|
});
|
||
|
return valid;
|
||
|
};
|
||
|
|
||
|
// Save form data to localStorage
|
||
|
const saveData = () => {
|
||
|
const fields = steps[currentStep].querySelectorAll("input, textarea, select");
|
||
|
fields.forEach((field) => {
|
||
|
formData[field.name] = field.value;
|
||
|
});
|
||
|
localStorage.setItem("formData", JSON.stringify(formData));
|
||
|
};
|
||
|
|
||
|
// Display data
|
||
|
const displayData = () => {
|
||
|
const reviewSection = document.getElementById("review");
|
||
|
reviewSection.innerHTML = "";
|
||
|
|
||
|
// Iterate over all the steps to collect and display data
|
||
|
steps.forEach((step) => {
|
||
|
const inputs = step.querySelectorAll("input, select, textarea");
|
||
|
inputs.forEach((input) => {
|
||
|
if (input.type === "radio" && !input.checked) return; // Skip unchecked radios
|
||
|
if (input.type === "checkbox") {
|
||
|
// Handle checkboxes
|
||
|
if (!formData[input.name]) formData[input.name] = [];
|
||
|
if (input.checked) formData[input.name].push(input.value);
|
||
|
} else {
|
||
|
// Handle other input types
|
||
|
formData[input.name] = input.value;
|
||
|
}
|
||
|
|
||
|
// Determine label for the field (use placeholder or aria-label if available)
|
||
|
const label =
|
||
|
input.placeholder ||
|
||
|
input.ariaLabel ||
|
||
|
input.closest("label")?.textContent ||
|
||
|
input.name;
|
||
|
|
||
|
// Display field data in the review section
|
||
|
const p = document.createElement("p");
|
||
|
if (Array.isArray(formData[input.name])) {
|
||
|
p.textContent = `${label}: ${formData[input.name].join(", ")}`;
|
||
|
} else {
|
||
|
p.textContent = `${label}: ${formData[input.name]}`;
|
||
|
}
|
||
|
reviewSection.appendChild(p);
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
|
||
|
prevButton.addEventListener("click", (e) => {
|
||
|
e.preventDefault();
|
||
|
if (currentStep > 0) {
|
||
|
saveData();
|
||
|
currentStep--;
|
||
|
updateProgress();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
nextButton.addEventListener("click", (e) => {
|
||
|
e.preventDefault();
|
||
|
if (isValidStep()) {
|
||
|
saveData();
|
||
|
if (currentStep < steps.length - 1) {
|
||
|
currentStep++;
|
||
|
updateProgress();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
submitButton.addEventListener("click", (e) => {
|
||
|
e.preventDefault();
|
||
|
if (isValidStep()) {
|
||
|
saveData();
|
||
|
displayData();
|
||
|
form.querySelector(".completed").hidden = false;
|
||
|
stepsContainer.hidden = true;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
editButton.addEventListener("click", () => {
|
||
|
const fields = steps[currentStep].querySelectorAll("input, textarea, select");
|
||
|
fields.forEach((field) => {
|
||
|
if (formData[field.name]) {
|
||
|
field.value = formData[field.name];
|
||
|
}
|
||
|
});
|
||
|
currentStep = 1;
|
||
|
updateProgress();
|
||
|
});
|
||
|
|
||
|
updateProgress();
|