In an MVC3 application using unobtrusive jquery validation and view / model using the [Remote] validator: I try to disable the submit button and display a wait icon during remote validation and when a valid form is submitted to the server. I thought I had it nailed until I tried it in IE8.
The problem was that GC and FF did not fire the form submit event when the form was invalid, so I just turned off the submit button during this event. However, IE8 fires this event when the form is invalid, as a result of which the user will never be able to click it again. (IE8 does not submit the form, but the event fires.)
I tried to bind the function to the submit button click event. There I turned off the submit button, showed a wait icon and had the following:
$('[data-app-form-submit-button="true"]').live('click', function (e) { var form = $(this).parents('form'); var icon = form.find('[data-app-form-submitting-icon="true"]'); icon.show(); $(this).attr('disabled', 'disabled'); $.ajaxSetup({ async: false }); var isValid = form.valid(); $.ajaxSetup({ async: true }); alert(isValid); });
The problem is that the ajax configuration call does not disable asynchronous mode. This happens if I get it out of the click function, but then it disables asynchronous tuning for everything. Instead, the page immediately reports βtrueβ, verified by setting a breakpoint in the remote validation action method.
Any ideas?
Additional Note:
I forgot to mention that in IE8, a send event is fired only when the text field in question cannot perform validation, which can happen on the client. For example, if this fails or regex, send (). For a remote validation action method, it does not start. However, as soon as it fails to validate the client, subsequent remote checks also fire the IE8 send event.
Reply to Russ Cam (Comment # 1)
Here is the relevant code in the viewmodel:
public class SignUpForm : IValidatableObject { [DataType(DataType.EmailAddress)] [Display(Name = "Email Address")] [Required(ErrorMessage = "Email Address is required.")] [RegularExpression(@"^(email regex here)$", ErrorMessage = "This is not a valid email address.")] [Remote("Validate", "ControllerName", "AreaName", HttpMethod = "POST")] public string EmailAddress { get; set; } public IEnumerable<ValidationResult> Validate( ValidationContext validationContext) {
I'm glad you made me take a look at the <form> rendering. The form tag and input elements are as follows:
<form action="/post-action-method" method="post" novalidate="novalidate"> ... <input class="text-box single-line" data-app-focus="true" data-val="true" data-val-regex="This is not a valid email address." data-val-regex-pattern="^(email regex here)$" data-val-remote="&#39;Email Address&#39; is invalid." data-val-remote-additionalfields="*.EmailAddress" data-val-remote-type="POST" data-val-remote-url="/validate-action-method" data-val-required="Email Address is required." id="EmailAddress" name="EmailAddress" type="text" value=""> ... <input type="submit" value="Submit this form" data-app-form-submit-button="true" />
I still have not seen the attribute novalidate = "novalidate". Here's what it looks like in the cshtml file:
@using (Html.BeginForm()) { @Html.EditorForModel() @Html.AntiForgeryToken("assault") }
I also use an anti-fake token, if that matters. Thanks.