userNick userNick - 3 months ago 14
ASP.NET (C#) Question

Having issues with validation - clicking submit button changes focus and won't submit till the second click

This is the relevant code that I am using:

View

<div id="PasswordExpired">
@using (Html.BeginForm("ChangeExpiredPassword", "Home", FormMethod.Post, new { id = "PasswordExpiredForm", name = "PasswordExpiredForm"}))
{
@*AJAX modal content loaded here*@
}
</div>


Form

<div class="modal fade" id="PasswordExpiredModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div id="PasswordExpiredModalContent" class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title error-text">Password Expired</h4>
<p>The password for this account has expired, please create a new password</p>
<div id="processingError"></div>
</div>
<div class="modal-body">
<div class="form-group">
<div class="error">@Html.ValidationMessageFor(model => model.LoginEmail)</div>
@Html.LabelFor(model => model.LoginEmail)
@Html.TextBoxFor(model => model.LoginEmail, new { @class = "form-control", placeholder = "Email Address", type = "text", maxlength = "55" })
</div>
<div class="form-group">
<div class="error">@Html.ValidationMessageFor(model => model.CurrentPassword)</div>
@Html.LabelFor(model => model.CurrentPassword)
@Html.TextBoxFor(model => model.CurrentPassword, new { @class = "form-control", type = "password", maxlength = "55" })
</div>
<div class="form-group">
<div class="error">@Html.ValidationMessageFor(model => model.NewPassword)</div>
@Html.LabelFor(model => model.NewPassword)

@if (utility.Overrides.HasType(UtilityOverrideType.PasswordComplexity))
{
string messageAndRegEx = utility.Overrides.GetArgument(UtilityOverrideType.PasswordComplexity);
int pipePosition = messageAndRegEx.IndexOf("|");
string errorMessage = messageAndRegEx.Substring(0, pipePosition);
@Html.TextBoxFor(model => model.NewPassword, new { @class = "form-control", placeholder = errorMessage, type = "password", maxlength = "55" })
}
else
{
@Html.TextBoxFor(model => model.NewPassword, new { @class = "form-control", placeholder = "6 or more characters/case sensitive", type = "password", maxlength = "55" })
}
</div>
<div class="form-group">
<div class="error">@Html.ValidationMessageFor(model => model.ConfirmNewPassword)</div>
@Html.LabelFor(model => model.ConfirmNewPassword)
@Html.TextBoxFor(model => model.ConfirmNewPassword, new { @class = "form-control", type = "password", maxlength = "55" })
</div>
</div>
<div class="modal-footer">
<div class="btnWrap">
<a id="ChangePassword" href="#" class="genericBtn">Change Password</a>
</div>
</div>
</div>
</div>




Javascript

<script type="text/javascript">
var someVar = someVar || {};
someVar.home = (function(module, $) {
module.launchModal = function () {
$('#PasswordExpiredModal').modal('hide');
$('#PasswordExpiredModal').modal({
show: true,
backdrop: 'static'
});
$('#ChangePassword').on('click', function() {
var form = $('#PasswordExpiredForm');
form.validate();

processAjax({ 'url': '/Home/ChangeExpiredPassword', 'data': $(this).closest('form').serialize() });
});
}
return module;
}( someVar.home || {}, jQuery));
</script>


When I test the validation in certain orders clicking on the submit button fails to submit but instead removes the focus from the field that was just populated and places it on the button. Most of the time clicking the button submits the for properly. I can't figure out for the life of me how to get it to attempt submission whenever the button is clicked.

Edit: It looks like if a field errors because it is blank and then you populate that field and submit. By clicking submit the focus leaves the field and the error goes away.Then you are left to submit.

Answer

Instead of

$('#ChangePassword').on('click', function() {
    var form = $('#PasswordExpiredForm');
    form.validate();

    processAjax({ 'url': '/Home/ChangeExpiredPassword', 'data': $(this).closest('form').serialize() });
});

Try

$("#PasswordExpiredForm").validate({
    submitHandler: function(form) {
        processAjax({ 'url': '/Home/ChangeExpiredPassword', 'data': $(form).serialize() });
    }
});

With <button id="ChangePassword" class="genericBtn">Change Password</button>

You may also want to consider the possibility that when the validation elements are made visible the tend to move a submit button on the bottom of a form down by the height of the validation element. This can cause issues with the button being clicked.

Comments