Question

I have a "change password" page that needs to hash any passwords entered on the page via Javascript before sending. To complicate it, the page is loaded via a jQuery load() call, and is submitted by a jQuery.Form ajaxForm() call. Had everything working in MVC2, but MVC3 is giving me trouble.

That is, I have a page with a "Change Password" link that when clicked, loads the change password page into a jQuery modal popup, then the form on the change password page get's submitted via the jQuery.Form library (Essentially just wraps a $.ajax call), and returns it's result into the modal same modal popup.

Essentially, I have a model with two properties, OldPassword and NewPassword. I have two hidden fields generated by by view for these. They hold the hashed value of two other fields, PrehashOldPassword and PrehashNewPassword, and get updated via keyup events (I know, this means it does a whole SHA256 hash on every keyup... inefficient, but got the job doen for testing). The key here is that the regex validation and required field validation needs to be executed on these Prehash fields, which exist on the client side only (As obviously I don't want to transmit these fields to the server in any way).

So I manually create these two and add on the data-val-* attributes to the elements, i.e. they are NOT generated by the MVC helpers, etc. I am guessing that this is where I'm missing something. When the form submits with all fields empty, all of the errors popup that should, but the form goes right ahead and submits anyway.

==

So the things I've tried:

Yes, the unobtrusive library parse() method already get's called to parse the AJAX loaded form contents, and it appears to get all of the data validation stuff correctly, since I see the errors show up as fields blur(), and when I hit submit (before the ajax request completes and replaces the content of the popup).

Possible note: this call to the unobtrusive library's parse method happens AFTER the AJAX successfully loads the change password page into the popup... the AJAX form submit binding is put on document.ready of the loaded content, ergo, the AJAX form submission binding MAY be binding prior to, and thus firing before, the validation calls that the parse method may bind to the submit event...

However, (1) I am doing this same sort of thing in other places without issue, the ONLY DIFFERENCE being that I am manually putting these data-val-* attributes on elements I am creating manually! And (2), if I cause some kind of error on the OldPassword or NewPassword fields, i.e. a required field validation error by not loading a value into them, they display their error, and successfully STOP the form from submitting through the jQuery.Form method.

So I think something has to be wrong here:

<input id="PrehashNewPassword" type="password" name="PrehashNewPassword" data-val-required="The password field is required." data-val-regex-pattern="<%= RegexHelper.PasswordRegularExpression %>" data-val-regex="<%= RegexHelper.PasswordRegularExpressionError %>" data-val="true" />

I know that jquery.validate is getting the rules right, since I DO see the errors. It's just not stopping the form from submitting when their is an error in these manually generated elements, unless I do something like this, and add a pre-submit callback on the form's AJAX submission:

        $("#ChangePasswordForm").ajaxForm({
            beforeSubmit: function () { if (!$('#ChangePasswordForm').valid()) { return false; } },
            target: '#overlay'
        });

While this works, it is kind of ugly and I believe it causes the validation to be called twice... Not a huge deal, but less than ideal. So is there some other call that I need to make in the unobtrusive library to bind these?

Was it helpful?

Solution

Not sure if you found the problem, but you may try to return false in there if the form is not valid...

.
.
.
    if (!$('form').valid()) {
           return false;
    }

    // JSON POST...
.
.
.

If that doesn't work, then you could try to use:

$.validator.unobtrusive.parse($("#dynamicData"));

after dynamically adding your custom inputs. "dynamicData" is the ID of an element wrapped around the form

above found from here: http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx

OTHER TIPS

Out of interest, what happens if you just get the form to validate?

<script type="text/javascript">
    $("form").submit(function (evt) {

        // validate here should trigger invalid fields
        $('form').valid();

        // JSON POST...         

        // stop form submitting
        evt.preventDefault();
    });
</script>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top