jquery client side validation not working in MVC3 partial view
Asked Answered
T

2

20

I could not seem get client side validation work with the following partial view. This view is inside divTSettings div in the parent view. Tried lots of things from stackoverflow and other sites, nothing seems to work. Any ideas?

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>


@using (Ajax.BeginForm("CreateT", "TAdmin", null,
        new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "divTSettings"},
                       new { id = "CreateTForm" }))
{
    <div>
        <label>Name:</label>
        <input type="text" name="tName" id="tName"/>
        @Html.ValidationMessage("tName")
        <input type="submit" value="Submit"/>
    </div>
}

<script type="text/javascript">
$(function() {
    $('#CreateTForm').validate({
        rules: {
            tName: {
                required: true
            }
        },
        messages: {
            tName: {
                required: 'Name required'
            }
        }
    });
    $("#CreateTForm").removeData("validator");
    $("#CreateTForm").removeData("unobtrusiveValidation");
    $.validator.unobtrusive.parse("#CreateTForm");
});
</script>
Timtima answered 3/1, 2013 at 7:52 Comment(0)
H
95

Any ideas?

Yes, the very first thing you should do is to get rid of all those <script> tags from your partial view. Partial views should not contain any scripts. Partial views should contain only markup. I have repeated this many times and still see people putting scripts in-there. Scripts should be registered either in your Layout or the main View in which you have rendered the partial, probably by overriding some scripts section registered in your Layout so that all scripts get inserted into the end of your HTML document, just before the closing </body> tag. That's where they belong.

OK, now to the actual problem: unobtrusive validation doesn't work out-of-the-box with dynamically added elements to the DOM - such as for example sending an AJAX request to the server which returns a partial view and this partial view is then injected into the DOM.

In order to make it work you need to register those newly added elements with the unobtrusive validation framework. To do this you need to call the $.validator.unobtrusive.parse on the newly added elements:

$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

You should put this code inside the AJAX success handler that is injecting the partial into your DOM. Once you have injected the new elements simply call this function.

And if you are not writing your AJAX requests manually with jQuery ($.ajax, $.post, ...) but are relying on some Ajax.BeginForm and Ajax.ActionLink helpers do the job for you, you will need to subscribe to the OnSuccess callback in the AjaxOptions and put this code in there.

Hemi answered 3/1, 2013 at 7:58 Comment(11)
Thank you for your answer but the partial view is not loaded by AJAX, it is loaded by the parent using the parent's model. It makes AJAX post but validation doesn't work even for the first time load. And as you can see I have the validation initializations you mentioned in the document load handler.Timtima
Oh, you don't need to be doing those initializations on document.load. All you need to do is to include the jquery, jquery.validation and jquery.validation.unobtrusive scripts in your page. Also according to the code you have shown you seem to be subscribing to the .validate handler of the form and declaring some custom validation. But that's not at all how ASP.NET MVC and jquery unobtrusive validation works. You really have to choose between using data annotations on your view model (things like the [Required] attribute) or completely defining your custom client side validation rules.Hemi
If you decide to write your custom validation rules (subscribe to the .validate method of the form) then you should remove the jquery.unobtrusive.validation.js script from your page. Those 2 things are completely incompatible. So it's up to you to decide: either you use what's built-in ASP.NET MVC (and you use the validation attributes such as [Required] on your view model) or you use the jquery.validate plugin independently and you write your custom rules. But never mix the two because they are incompatible.Hemi
I didn't know they cannot mix. I simplified the version I posted here but I needed jquery validation for somewhat complicated front-end validation. I still check the same thing on the server but that requires a round-trip to the controller. Anyway, thanks for the quick reply.Timtima
Great. So, point is: "unobtrusive validation doesn't work out-of-the-box with dynamically added elements to the DOM" need to call the "$.validator.unobtrusive.parse"Britanybritches
Calling parse does absolutely nothing. Removing data attributes from form does nothing either.Enneastyle
@DarinDimitrov You saved my day.. :) was absolutely searching for validations on form loaded from partial views.. :) Thanks a bunch.. :)Brice
Guys , i'm trying this solution still i m facing this problem for server side validation, After error message inject in partial view , dropdown not working properly .. That means i unable to select the dropdown value. Any ideasSaddlebow
I'm filling the content of a modal using ajax and this solution worked for me, thanksAggarwal
@SergeyAkopov $.validator.unobtrusive.parse("form"); works. If it's not then you're doing something else wrongGreasepaint
How about if I am using @Html.Partial("CreditCardDetail_Partial") will it still workVicechancellor
M
0

If you want to fix at global level then this should help. I used at _layout.cstml.

  $(document).ajaxStart(function () {
                $.ajaxSetup({
                    converters: {
                        "text html": function (textValue) {
                            if (textValue) {
                                // Some parsing logic here
                                var script = "<script type='text/javascript' language='javascript' > $.validator.unobtrusive.parse(\"form\");";
                                var scriptend = "\<\/script>";
                                return script + scriptend + " " + textValue;
                            } else {
                                // This will notify a parsererror for current request
                                throw exceptionObject;
                            }
                        }
                    }
                });
            });
Manciple answered 9/3, 2018 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.