Reputation: 33
I am creating a multi-step form based on this tutorial here: https://www.phpflow.com/php/multi-step-form-using-php-bootstrap-jquery/
It's working perfectly fine if I need to simply navigate back and forth throughout the form. However, I need to be able to skip some steps depending on the users selection.
I have two buttons for the purpose of the demo, they are named step 3 and step 4.
When the user clicks on either they should be directed to the corresponding fieldset.
I am just learning jQuery and have been struggling with this for days. If anyone could point in the direction, I would be so grateful.
I have created a fiddle which I hope helps.
https://jsfiddle.net/0pf6xavq/
HTML
<div class="container">
<div class="py-5 text-center">
<h2>Application form</h2>
</div>
<div class="row">
<div class="col-md-12">
<!--<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div>
</div>-->
<form id="applicationForm" class="needs-validation" novalidate>
<fieldset>
<h4 class="mb-3">Site Details</h4>
<div class="row">
<div class="col-md-6 mb-3">
<label for="clientName">Name</label>
<input type="text" class="form-control" id="clientName" placeholder="" value="" required>
<div class="invalid-feedback">
Valid Name is required.
</div>
</div>
</div>
<div class="mb-3 mt-4">
<label for="address">Address</label>
<input type="text" class="form-control" id="address" required>
<div class="invalid-feedback">
Please enter site address.
</div>
</div>
<div class="mb-3">
<label for="address2">Address <span class="text-muted">(Optional)</span></label>
<input type="text" class="form-control" id="address2">
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="town">Town</label>
<input type="text" class="form-control" id="town" required>
<div class="invalid-feedback">
Town is required.
</div>
</div>
<div class="col-md-4 mb-3">
<label for="county">County</label>
<input type="text" class="form-control" id="county" required>
<div class="invalid-feedback">
County is required.
</div>
</div>
<div class="col-md-4 mb-3">
<label for="postcode">Post Code</label>
<input type="text" class="form-control" id="postcode" placeholder="" required>
<div class="invalid-feedback">
Post Code is required.
</div>
</div>
</div>
<hr class="mb-4">
<input type="button" name="password" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset>
<h4 class="mb-3">Description</h4>
<div class="row">
<div class="col-md-12 mb-3">
<label for="localAuthority">Description </label>
<textarea maxlength="100" class="form-control" id="localAuthoirty"></textarea>
</div>
</div>
<div class="row">
<input type="button" name="step3" class=" btn btn-default" value="Step 3" />
<input type="button" name="step4" class=" btn btn-primary" value="Step 4" />
</div>
<hr class="mb-4">
<input type="button" name="previous" class="previous btn btn-default" value="Previous" />
<input type="button" name="next" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset id="step3">
<h4 class="mb-3">Step 3</h4>
<div class="row">
<div class="col-md-12 mb-3">
This is step 3
</div>
</div>
<hr class="mb-4">
<input type="button" name="previous" class="previous btn btn-default" value="Previous" />
<input type="button" name="next" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset id="step4">
<h4 class="mb-3">Step 4</h4>
<div class="row">
<div class="col-md-12 mb-3">
This is step 4
</div>
</div>
<hr class="mb-4">
<input type="button" name="previous" class="previous btn btn-default" value="Previous" />
<input type="button" name="next" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset id="terms">
<h4 class="mb-3">Final Step of the form</h4>
<p>All routes lead to this final step</p>
</fieldset>
</form>
</div>
</div>
</div>
JS
$(document).ready(function(){
var current = 1,current_step,next_step,steps;
steps = $("fieldset").length;
//$(".next").click(function(){
$(document).on("click",".next",function(){
current_step = $(this).parent("fieldset");
next_step = $(this).parent("fieldset").next();
next_step.show();
current_step.hide();
//setProgressBar(++current);
});
//$(".previous").click(function(){
$(document).on("click",".previous",function(){
current_step = $(this).parent("fieldset");
next_step = $(this).parent("fieldset").prev();
next_step.show();
current_step.hide();
//setProgressBar(--current);
});
I will continue to try and figure this out myself but any advice would be appreciated.
My apologies if I haven't explained it well. My brain is frazzled from this!
Many thanks
Upvotes: 2
Views: 13264
Reputation: 178
I created a new fiddle based off of yours.
https://jsfiddle.net/5o0g43k7/
I added step-3 and step-4 buttons classes and added click events to them that do similar logic to your next and previous click events.
<input type="button" name="step3" class=" btn btn-default step-3" value="Step 3" />
<input type="button" name="step4" class=" btn btn-primary step-4" value="Step 4" />
I am using closest() instead of parent() which will look for the first parent that is a "fieldset", so you could put those step-3 and step-4 buttons anywhere in the fieldset and not have to modify this code. To get next_step I just select the element with id "step3", since I saw you already had id attributes on those fieldsets.
$(document).on("click",".step-3",function(){
current_step = $(this).closest("fieldset");
next_step = $("#step3");
next_step.show();
current_step.hide();
//setProgressBar(--current);
});
$(document).on("click",".step-4",function(){
current_step = $(this).closest("fieldset");
next_step = $("#step4");
next_step.show();
current_step.hide();
//setProgressBar(--current);
});
Obviously if you need to skip steps based on user input I assume you'll check that input when they click Next and then need to skip...so that will be a little different but the logic to hide the current step and show the next step should be the same.
I hope this helps you.
Edit: Add logic to store steps in an array and navigate to the next or previous step based on the array.
The below snippet will simulate needing to skip Step 3. It works via removing 3 from the stepIds array. This logic could be used by first initializing stepIds with all of the steps (1-5) and then based on user input removing steps from the array or inserting them back in the proper location maintaining sort order.
I wasn't sure if you actually needed Step 3 and Step 4 buttons. I removed the Step 3 button in my example. If you were going to have those in your finished logic you would also need to show and hide those buttons as well as add and remove the step id from the stepIds array.
var stepIds = [1, 2, 4, 5 ]
$(document).ready(function(){
var current = 1,current_step,next_step,steps;
steps = $("fieldset").length;
//$(".next").click(function(){
$(document).on("click",".next",function(){
current_step = $(this).closest("fieldset").data("id");
next_step = stepIds[stepIds.indexOf(current_step)+1];
$('fieldset[data-id="' + current_step + '"]').hide();
$('fieldset[data-id="' + next_step + '"]').show();
});
$(document).on("click",".previous",function(){
current_step = $(this).closest("fieldset").data("id");
next_step = stepIds[stepIds.indexOf(current_step)-1];
$('fieldset[data-id="' + current_step + '"]').hide();
$('fieldset[data-id="' + next_step + '"]').show();
});
$(document).on("click",".step-3",function(){
current_step = $(this).closest("fieldset").data("id");
next_step = stepIds[stepIds.indexOf(3)];
if (next_step) {
$('fieldset[data-id="' + current_step + '"]').hide();
$('fieldset[data-id="' + next_step + '"]').show();
}
});
$(document).on("click",".step-4",function(){
current_step = $(this).closest("fieldset").data("id");
next_step = stepIds[stepIds.indexOf(4)];
if (next_step) {
$('fieldset[data-id="' + current_step + '"]').hide();
$('fieldset[data-id="' + next_step + '"]').show();
}
});
});
form#applicationForm fieldset:not(:first-of-type), #plotTable {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="py-5 text-center">
<h2>Application form</h2>
</div>
<div class="row">
<div class="col-md-12">
<form id="applicationForm" class="needs-validation" novalidate>
<fieldset data-id="1">
<h4 class="mb-3">Site Details</h4>
<div class="row">
<div class="col-md-6 mb-3">
<label for="clientName">Name</label>
<input type="text" class="form-control" id="clientName" placeholder="" value="" required>
<div class="invalid-feedback">
Valid Name is required.
</div>
</div>
</div>
<div class="mb-3 mt-4">
<label for="address">Address</label>
<input type="text" class="form-control" id="address" required>
<div class="invalid-feedback">
Please enter site address.
</div>
</div>
<div class="mb-3">
<label for="address2">Address <span class="text-muted">(Optional)</span></label>
<input type="text" class="form-control" id="address2">
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="town">Town</label>
<input type="text" class="form-control" id="town" required>
<div class="invalid-feedback">
Town is required.
</div>
</div>
<div class="col-md-4 mb-3">
<label for="county">County</label>
<input type="text" class="form-control" id="county" required>
<div class="invalid-feedback">
County is required.
</div>
</div>
<div class="col-md-4 mb-3">
<label for="postcode">Post Code</label>
<input type="text" class="form-control" id="postcode" placeholder="" required>
<div class="invalid-feedback">
Post Code is required.
</div>
</div>
</div>
<hr class="mb-4">
<input type="button" name="password" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset data-id="2">
<h4 class="mb-3">Description</h4>
<div class="row">
<div class="col-md-12 mb-3">
<label for="localAuthority">Description </label>
<textarea maxlength="100" class="form-control" id="localAuthoirty"></textarea>
</div>
</div>
<div class="row">
<input type="button" name="step4" class=" btn btn-primary step-4" value="Step 4" />
</div>
<hr class="mb-4">
<input type="button" name="previous" class="previous btn btn-default" value="Previous" />
<input type="button" name="next" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset id="step3" data-id="3">
<h4 class="mb-3">Step 3</h4>
<div class="row">
<div class="col-md-12 mb-3">
This is step 3
</div>
</div>
<hr class="mb-4">
<input type="button" name="previous" class="previous btn btn-default" value="Previous" />
<input type="button" name="next" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset id="step4" data-id="4">
<h4 class="mb-3">Step 4</h4>
<div class="row">
<div class="col-md-12 mb-3">
This is step 4
</div>
</div>
<hr class="mb-4">
<input type="button" name="previous" class="previous btn btn-default" value="Previous" />
<input type="button" name="next" class="next btn btn-primary" value="Next" />
</fieldset>
<fieldset id="terms" data-id="5">
<h4 class="mb-3">Final Step of the form</h4>
<p>All routes lead to this final step</p>
</fieldset>
</form>
</div>
</div>
</div>
Upvotes: 2