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