In Laravel 8 app which uses vuejs and jquery I found wizard made with html like :
<div class="content__inner"> <div class="ccontainer overflow-hiddenn"> <!--multisteps-form--> <div class="multisteps-form"> <div class="multisteps-form__progress"> <button class="multisteps-form__progress-btn js-active" type="button" title="Add Project Info" > Project Info </button> <button class="multisteps-form__progress-btn" type="button" title="Add Product" > Product Details 22222 </button> <button class="multisteps-form__progress-btn" type="button" title="Project Budget & Diagram" > Project Budget & Diagram </button> <button class="multisteps-form__progress-btn" type="button" title="Video & Website Link" > Video & Website Link </button> </div> <form class="multisteps-form__form"> <!--single form panel--> <div class="multisteps-form__panel shadow p-4 rounded bg-white js-active" data-animation="scaleIn" > <!-- <h3 class="multisteps-form__title">Your User Info</h3> --> <div class="multisteps-form__content"> <div class="row"> <div class="col-xl-4"> <div class="submit-field"> <h5> Project Name <span>*</span> </h5> <input type="text" class="with-border" id="name_project" v-model="project.name" /> </div> </div> <div class="col-xl-4"> <div class="submit-field"> <h5> Choose Categories <span>*</span> </h5> <b-form-select class="tzselectpicker" v-model="project.category" :options="project_category" ></b-form-select> </div> </div>
and inited js function
setStepForm() { //DOM elements const DOMstrings = { stepsBtnClass: "multisteps-form__progress-btn", stepsBtns: document.querySelectorAll( `.multisteps-form__progress-btn` ), stepsBar: document.querySelector(".multisteps-form__progress"), stepsForm: document.querySelector(".multisteps-form__form"), stepsFormTextareas: document.querySelectorAll( ".multisteps-form__textarea" ), stepFormPanelClass: "multisteps-form__panel", stepFormPanels: document.querySelectorAll( ".multisteps-form__panel" ), stepPrevBtnClass: "js-btn-prev", stepNextBtnClass: "js-btn-next" }; console.log(" setStepForm DOMstrings::"); console.log(DOMstrings); //remove class from a set of items const removeClasses = (elemSet, className) => { elemSet.forEach(elem => { elem.classList.remove(className); }); }; //return exect parent node of the element const findParent = (elem, parentClass) => { let currentNode = elem; while (!currentNode.classList.contains(parentClass)) { currentNode = currentNode.parentNode; } return currentNode; }; //get active button step number const getActiveStep = elem => { return Array.from(DOMstrings.stepsBtns).indexOf(elem); }; //set all steps before clicked (and clicked too) to active const setActiveStep = activeStepNum => { //remove active state from all the state removeClasses(DOMstrings.stepsBtns, "js-active"); //set picked items to active DOMstrings.stepsBtns.forEach((elem, index) => { if (index <= activeStepNum) { elem.classList.add("js-active"); } }); }; //get active panel const getActivePanel = () => { let activePanel; DOMstrings.stepFormPanels.forEach(elem => { if (elem.classList.contains("js-active")) { activePanel = elem; } }); return activePanel; }; //open active panel (and close unactive panels) const setActivePanel = activePanelNum => { //remove active class from all the panels removeClasses(DOMstrings.stepFormPanels, "js-active"); //show active panel DOMstrings.stepFormPanels.forEach((elem, index) => { if (index === activePanelNum) { elem.classList.add("js-active"); setFormHeight(elem); } }); }; //set form height equal to current panel height const formHeight = activePanel => { const activePanelHeight = activePanel.offsetHeight; DOMstrings.stepsForm.style.height = `${activePanelHeight}px`; }; const setFormHeight = () => { const activePanel = getActivePanel(); formHeight(activePanel); }; //STEPS BAR CLICK FUNCTION DOMstrings.stepsBar.addEventListener("click", e => { //check if click target is a step button const eventTarget = e.target; if ( !eventTarget.classList.contains( `${DOMstrings.stepsBtnClass}` ) ) { return; } //get active button step number const activeStep = getActiveStep(eventTarget); //set all steps before clicked (and clicked too) to active setActiveStep(activeStep); //open active panel setActivePanel(activeStep); }); //PREV/NEXT BTNS CLICK DOMstrings.stepsForm.addEventListener("click", e => { const eventTarget = e.target; //check if we clicked on `PREV` or NEXT` buttons if ( !( eventTarget.classList.contains( `${DOMstrings.stepPrevBtnClass}` ) || eventTarget.classList.contains( `${DOMstrings.stepNextBtnClass}` ) ) ) { return; } //find active panel const activePanel = findParent( eventTarget, `${DOMstrings.stepFormPanelClass}` ); let activePanelNum = Array.from( DOMstrings.stepFormPanels ).indexOf(activePanel); //set active step and active panel onclick if ( eventTarget.classList.contains( `${DOMstrings.stepPrevBtnClass}` ) ) { activePanelNum--; } else { activePanelNum++; } setActiveStep(activePanelNum); setActivePanel(activePanelNum); setTimeout(() => { var body = $(".dashboard-content-container"); body.stop().animate( { scrollTop: 0 }, 500, "swing", function() {} ); }, 100); }); setTimeout(() => { setFormHeight(); }, 500); //SETTING PROPER FORM HEIGHT ONLOAD window.addEventListener("load", setFormHeight, false); //SETTING PROPER FORM HEIGHT ONRESIZE window.addEventListener("resize", setFormHeight, false); //changing animation via animation select !!!YOU DON'T NEED THIS CODE (if you want to change animation type, just change form panels data-attr) const setAnimationType = newType => { DOMstrings.stepFormPanels.forEach(elem => { elem.dataset.animation = newType; }); }; //selector onchange - changing animation const animationSelect = document.querySelector( ".pick-animation__select" ); if (animationSelect != null) { animationSelect.addEventListener("change", () => { const newAnimationType = animationSelect.value; setAnimationType(newAnimationType); }); } },
By clicking on “Next” button next step is opened, but I need to validate inputs before moving to next step. Please any hints how can I make validation here ? Also is it some library? I searched in net but drowned…
Thanks!
Advertisement
Answer
Each wizard view send wizard position in ajax.In backend based on wizard position validate fields .since you know which and all field exist in each wizard view.
For example consider you have 3 wizard steps.
Step 1
has 3 input fields
Step 2
has 2 input fields
Step 3
has 1 input fields
Suppose if you send current step is 1 then you can only validate those fields.
$validations=[ 'step1'=>[ //field validation array ], 'step3'=>[ //field validation array ], 'step3'=>[ //field validation array ], ]
then based on request wizard step you can easily fetch validation rules
Validation::make($validations[$request->step]);
Or you can make all fields validate only if exists in the request