In this article, we will see multi step form wizard jquery validation. Here, we will learn jquery validation for multi step form wizard. Sometimes we required multi step form to register user details, personal details, job details, etc. But we required validation for specific form fields. So, we will validate multi step form using validate js.
So, let's see the jquery multi step form wizard with validation, multi step form validation javascript, multi step form using jquery, validate multi step form using jquery, and jquery validation plugin.
Add HTML:
<section class="multi-step-form">
<h4>Multi Step Form Wizard jQuery Validation - Websolutionstuff</h4>
<div class="steps">
<button class="active" type="button" disabled>Step One</button> |
<button type="button" disabled>Step Two</button> |
<button type="button" disabled>Step Three</button>
</div>
<form action="#" method="post">
<fieldset aria-label="Step One" tabindex="-1" id="step-1">
<h2>Step One</h2>
<p>
<label for="first-name">First Name</label>
<input class="form-control" type="text" name="first-name" id="first-name" required>
</p>
<p>
<label for="last-name">Last Name</label>
<input class="form-control" type="text" name="last-name" id="last-name" required>
</p>
<p>
<button class="btn btn-default btn-next" type="button" aria-controls="step-2">Next</button>
</p>
</fieldset>
<fieldset aria-label="Step Two" tabindex="-1" id="step-2">
<h2>Step Two</h2>
<p>
<label for="email-address">Email Address</label>
<input class="form-control" type="email" name="email-address" id="email-address" required>
</p>
<p>
<label for="phone-number">Phone Number <span class="optional">(optional)</span></label>
<input class="form-control" type="tel" name="phone-number" id="phone-number">
</p>
<p>
<button class="btn btn-default btn-prev" type="button" aria-controls="step-1">Previous</button>
<button class="btn btn-default btn-next" type="button" aria-controls="step-3">Next</button>
</p>
</fieldset>
<fieldset aria-label="Step Three" tabindex="-1" id="step-3">
<h2>Step Three</h2>
<p>
<label for="message"></label>
<textarea class="form-control" rows="3" name="message" id="message" required></textarea>
</p>
<p>
<button class="btn btn-success" type="submit">Submit</button>
<button class="btn btn-default btn-edit" type="button">Edit</button>
<button class="btn btn-danger" type="reset">Start Over</button>
</p>
</fieldset>
</form>
</section>
Add CSS:
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet" type="text/css">
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/cosmo/bootstrap.min.css" rel="stylesheet" type="text/css">
.no-js .multi-step-form fieldset button, .multi-step-form.edit-form fieldset button, .no-js .multi-step-form h2, .multi-step-form.edit-form h2 {
display: none !important;
}
.no-js .multi-step-form fieldset, .multi-step-form.edit-form fieldset {
display: block !important;
}
.no-js .multi-step-form [type="submit"], .multi-step-form.edit-form [type="submit"], .no-js .multi-step-form [type="reset"], .multi-step-form.edit-form [type="reset"] {
display: inline-block !important;
}
.no-js .multi-step-form .steps, .multi-step-form.edit-form .steps {
display: none;
}
.multi-step-form fieldset {
display: none;
}
.multi-step-form fieldset:first-of-type {
display: block;
}
.multi-step-form fieldset.hidden {
display: none;
}
.multi-step-form fieldset.visible {
display: block;
}
.multi-step-form .steps button {
border: 0;
}
.multi-step-form .steps [disabled] {
background: none;
}
.multi-step-form .steps .active {
background: #eee;
}
body {
padding: 1em;
max-width: 35em;
margin: 0 auto;
}
.error {
color: red;
}
label .optional {
font-weight: normal;
font-size: 90%;
}
h4{
font-weight:600;
font-size:18px;
margin-bottom:30px;
}
Add jQuery:
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.0/jquery.validate.min.js"></script>
<script>
document.documentElement.className = document.documentElement.className.replace("no-js","js");
</script>
var app = {
init: function(){
this.cacheDOM();
this.setupAria();
this.nextButton();
this.prevButton();
this.validateForm();
this.startOver();
this.editForm();
this.killEnterKey();
this.handleStepClicks();
},
cacheDOM: function(){
if($(".multi-step-form").size() === 0){ return; }
this.$formParent = $(".multi-step-form");
this.$form = this.$formParent.find("form");
this.$formStepParents = this.$form.find("fieldset"),
this.$nextButton = this.$form.find(".btn-next");
this.$prevButton = this.$form.find(".btn-prev");
this.$editButton = this.$form.find(".btn-edit");
this.$resetButton = this.$form.find("[type='reset']");
this.$stepsParent = $(".steps");
this.$steps = this.$stepsParent.find("button");
},
htmlClasses: {
activeClass: "active",
hiddenClass: "hidden",
visibleClass: "visible",
editFormClass: "edit-form",
animatedVisibleClass: "animated fadeIn",
animatedHiddenClass: "animated fadeOut",
animatingClass: "animating"
},
setupAria: function(){
// set first parent to visible
this.$formStepParents.eq(0).attr("aria-hidden",false);
// set all other parents to hidden
this.$formStepParents.not(":first").attr("aria-hidden",true);
// handle aria-expanded on next/prev buttons
app.handleAriaExpanded();
},
nextButton: function(){
this.$nextButton.on("click", function(e){
e.preventDefault();
// grab current step and next step parent
var $this = $(this),
currentParent = $this.closest("fieldset"),
nextParent = currentParent.next();
// if the form is valid hide current step
// trigger next step
if(app.checkForValidForm()){
currentParent.removeClass(app.htmlClasses.visibleClass);
app.showNextStep(currentParent, nextParent);
}
});
},
prevButton: function(){
this.$prevButton.on("click", function(e){
e.preventDefault();
// grab current step parent and previous parent
var $this = $(this),
currentParent = $(this).closest("fieldset"),
prevParent = currentParent.prev();
// hide current step and show previous step
// no need to validate form here
currentParent.removeClass(app.htmlClasses.visibleClass);
app.showPrevStep(currentParent, prevParent);
});
},
showNextStep: function(currentParent,nextParent){
// hide previous parent
currentParent
.addClass(app.htmlClasses.hiddenClass)
.attr("aria-hidden",true);
// show next parent
nextParent
.removeClass(app.htmlClasses.hiddenClass)
.addClass(app.htmlClasses.visibleClass)
.attr("aria-hidden",false);
// focus first input on next parent
nextParent.focus();
// activate appropriate step
app.handleState(nextParent.index());
// handle aria-expanded on next/prev buttons
app.handleAriaExpanded();
},
showPrevStep: function(currentParent,prevParent){
// hide previous parent
currentParent
.addClass(app.htmlClasses.hiddenClass)
.attr("aria-hidden",true);
// show next parent
prevParent
.removeClass(app.htmlClasses.hiddenClass)
.addClass(app.htmlClasses.visibleClass)
.attr("aria-hidden",false);
// send focus to first input on next parent
prevParent.focus();
// activate appropriate step
app.handleState(prevParent.index());
// handle aria-expanded on next/prev buttons
app.handleAriaExpanded();
},
handleAriaExpanded: function(){
/*
Loop thru each next/prev button
Check to see if the parent it conrols is visible
Handle aria-expanded on buttons
*/
$.each(this.$nextButton, function(idx,item){
var controls = $(item).attr("aria-controls");
if($("#"+controls).attr("aria-hidden") == "true"){
$(item).attr("aria-expanded",false);
}else{
$(item).attr("aria-expanded",true);
}
});
$.each(this.$prevButton, function(idx,item){
var controls = $(item).attr("aria-controls");
if($("#"+controls).attr("aria-hidden") == "true"){
$(item).attr("aria-expanded",false);
}else{
$(item).attr("aria-expanded",true);
}
});
},
validateForm: function(){
// jquery validate form validation
this.$form.validate({
ignore: ":hidden", // any children of hidden desc are ignored
errorElement: "span", // wrap error elements in span not label
invalidHandler: function(event, validator){ // add aria-invalid to el with error
$.each(validator.errorList, function(idx,item){
if(idx === 0){
$(item.element).focus(); // send focus to first el with error
}
$(item.element).attr("aria-invalid",true); // add invalid aria
})
},
submitHandler: function(form) {
alert("form submitted!");
// form.submit();
}
});
},
checkForValidForm: function(){
if(this.$form.valid()){
return true;
}
},
startOver: function(){
var $parents = this.$formStepParents,
$firstParent = this.$formStepParents.eq(0),
$formParent = this.$formParent,
$stepsParent = this.$stepsParent;
this.$resetButton.on("click", function(e){
// hide all parents - show first
$parents
.removeClass(app.htmlClasses.visibleClass)
.addClass(app.htmlClasses.hiddenClass)
.eq(0).removeClass(app.htmlClasses.hiddenClass)
.eq(0).addClass(app.htmlClasses.visibleClass);
// remove edit state if present
$formParent.removeClass(app.htmlClasses.editFormClass);
// manage state - set to first item
app.handleState(0);
// reset stage for initial aria state
app.setupAria();
// send focus to first item
setTimeout(function(){
$firstParent.focus();
},200);
}); // click
},
handleState: function(step){
this.$steps.eq(step).prevAll().removeAttr("disabled");
this.$steps.eq(step).addClass(app.htmlClasses.activeClass);
// restart scenario
if(step === 0){
this.$steps
.removeClass(app.htmlClasses.activeClass)
.attr("disabled","disabled");
this.$steps.eq(0).addClass(app.htmlClasses.activeClass)
}
},
editForm: function(){
var $formParent = this.$formParent,
$formStepParents = this.$formStepParents,
$stepsParent = this.$stepsParent;
this.$editButton.on("click",function(){
$formParent.toggleClass(app.htmlClasses.editFormClass);
$formStepParents.attr("aria-hidden",false);
$formStepParents.eq(0).find("input").eq(0).focus();
app.handleAriaExpanded();
});
},
killEnterKey: function(){
$(document).on("keypress", ":input:not(textarea,button)", function(event) {
return event.keyCode != 13;
});
},
handleStepClicks: function(){
var $stepTriggers = this.$steps,
$stepParents = this.$formStepParents;
$stepTriggers.on("click", function(e){
e.preventDefault();
var btnClickedIndex = $(this).index();
// kill active state for items after step trigger
$stepTriggers.nextAll()
.removeClass(app.htmlClasses.activeClass)
.attr("disabled",true);
// activate button clicked
$(this)
.addClass(app.htmlClasses.activeClass)
.attr("disabled",false)
// hide all step parents
$stepParents
.removeClass(app.htmlClasses.visibleClass)
.addClass(app.htmlClasses.hiddenClass)
.attr("aria-hidden",true);
// show step that matches index of button
$stepParents.eq(btnClickedIndex)
.removeClass(app.htmlClasses.hiddenClass)
.addClass(app.htmlClasses.visibleClass)
.attr("aria-hidden",false)
.focus();
});
}
};
app.init();
Output:
You might also like:
- Read Also: Laravel 9 Phone Number Validation Using Regex
- Read Also: How To Validate Multi Step Form Using jQuery
- Read Also: How to Clear Form Data Using jQuery
- Read Also: Laravel 8 Form Class Not Found