I'm facing a problem with wizard validation in MVC. I want the code to check if a field is empty or not before jumping to the next page. I am using this wizard in my project. Here is my .cshtml page:
<div class="col-sm-12 text-right bottom-prev-next">
<button id="vnBtnNext" type="button" class="btn btn-primary btn-sm btn-next" data-attr="{{currentStepIndex==steps.length-1?currentStepIndex:currentStepIndex}}">{{currentStepIndex==steps.length-1?'Finish':'Next'}}<i class="fa fa-arrow-right"></i></button>
<button id="vnBtnPrev" type="button" class="btn btn-primary btn-sm btn-prev pull-left"><i class="fa fa-arrow-left"></i>Prev</button>
</div>
<script type="text/javascript">
$(document).on("click", "#vnBtnNext", function (e) {
if ($('#vnBtnNext').html().indexOf("Next") != -1 && $('#vnBtnNext').attr('data-attr') == "1") {
if ($('input[name=FirstName]').val() == "") {
$("input[name=FirstName]").css("background-color", "lightyellow");
$('input[name=FirstName]').focus();
alert('Please enter the First Name in English');
}
}
else {
return;
}
});
</script>
The reason you are still going to next page is following line of codes in your wizard library.
//line no. 29-33
var btnNexts = document.querySelectorAll( '.btn-next' );
for (var j = 0; j < btnNexts.length; ++j) {
angular.element(btnNexts[j]).attr('ng-click','showNextStep()');
angular.element(btnNexts[j]).attr('ng-disabled', '!hasNext() && !isFinish()');
}
and showNextStep
is as follow.
$scope.showNextStep = function(){$scope.toggleSteps($scope.currentStepIndex + 1, true);}
You need to change showNextStep
implementation in such a way that it does not toggle until all validations are passed. Basically what I'm saying is you need to execute the following line conditionally if and only if all validations are passed in the current step.
//line no. 74
$scope.toggleSteps($scope.currentStepIndex + 1, true);
I guess this is fairly enough to get you started with.
EDIT There are a number of ways you can make this change either by extending this library which will take validator for each step. Or you can modify line no. 74 to include your validator. Specified repo allows you to freely use and edit source code. Following is an example
$scope.showNextStep = function(){
var validationPassed = true; // make validator for each step and call that validor based on step which will return true/false or if you want sophistication then let them return object with validation message.
// This is proof of concept and needs to be in function.
if ($('input[name=FirstName]').val() == "") {
$("input[name=FirstName]").css("background-color", "lightyellow");
$('input[name=FirstName]').focus();
alert('Please enter the First Name in English');
validationPassed = false;
}
if(validationPassed)
$scope.toggleSteps($scope.currentStepIndex + 1, true);
else
//Do not toggle step and show validation message.
}
I guess you get the idea.
Or you can try e.preventDefault(), and e.stopPropogation() in your custom event handler you have written in your question. I don't know how angular behave to this but you can try this as well.