开发者

Inline client side validation with MVC and jQuery

I have setup a simple example to show a form inside a jquery UI dialog and wish to enable inline client side validation on that form

I have then added the scripts to my master page

<script type="text/javascrip开发者_StackOverflow社区t" src="<%: Url.Content( "~/_assets/js/jquery-1.4.3.min.js" )%>"></script>
<script type="text/javascript" src="<%: Url.Content( "~/_assets/js/jquery.validate.min.js" )%>"></script>
<script type="text/javascript" src="<%: Url.Content( "~/_assets/js/MicrosoftMvcJQueryValidation.js" ) %>"></script> 

and then I have enabled Client Side Validation through the following code

<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm() { %>
<% } %>

Then, I dont know how to enable inline validation for every input so when the user leaves the focus from any of them validation occurs.

The client side validation seems to work only after I have done a submit. But that is not a "client side validation" as the attributes get validated from my server code...

Any suggestion?


Finally I have got through the solution.

First of all, my forms were never binded to validation callbacks provided by the code inside the MicrosoftMvcJQueryValidation.js script. This because I am using jQuery dialogs and the form is inside the dialog while the script included in the master page.

My first attempt toward the solution has been to modify the MicrosoftMvcJQueryValidation.js. In particular I have added a function EnableClientSideValidation() where I moved the code that was in the $(document).ready function as in the following code sample

function EnableClientSideValidation() {
    var allFormOptions = window.mvcClientValidationMetadata;
    if (allFormOptions) {
        while (allFormOptions.length > 0) {
            var thisFormOptions = allFormOptions.pop();
            __MVC_EnableClientValidation(thisFormOptions);
        }
    }
}

$(document).ready(function () {
    EnableClientSideValidation();
});

Then I have called the same function inside a script block that I have placed in the dialog markup code $(document).ready() function

With the help of firebug I have placed a breakpoint inside the EnableClientSideValidation() function and then experienced the fact that was called only when the main page was ready but not from the dialog. This was due to the fact that I had my "dialog" script block inside the <form>...</form> tag and so the script did not worked.

Code like this

<% using (Html.BeginForm()) { %>

    //DIALOG FORM CODE WAS HERE

    <script type="text/javascript">
    $(document).ready(function () {
        EnableClientSideValidation();
    });
    </script>
<% } %>

has been changed to

<% using (Html.BeginForm()) { %>

    //DIALOG FORM CODE WAS HERE

<% } %>

<script type="text/javascript">
$(document).ready(function () {
    EnableClientSideValidation();
});
</script>

Finally everything started working! I would like to thanks vandalo and kdawg for helping in finding a solution. There was something still missed but your answers have stimulated my head.

I am posting this for other that can have the same problem.


OK, so here's what I did to get MicrosoftMvcJQueryValidation to work for me in an AJAX/PartialView environment. It's relevant, because essentially both instances (my AJAX/PartialView stuff and your onBlur triggering) require explicit control of when the validation methods are called. I'll try my best to capture everything you need to do, because I ended up having to edit my MicrosoftMvcJQueryValidation.js file to get it AJAX-enabled. However, I don't believe any of my edits are required for what you want.

The key lies in being able to access the validation functions that MicrosoftMvcJQuery generates. Fortunately, it adds it to the form element via a property called validationCallbacks.

In my custom submit function, I access and call these callbacks like this (form is the DOM element, not a jQuery object):

// this taps into the mvc clientside validation functionality.
// this is a roundabout way of calling jquery.validate() as
// that is what's going on the in callback() function
validationCallbacks = form.validationCallbacks;
if (validationCallbacks) {
    for (i = 0; i < validationCallbacks.length; i += 1) {
        callback = validationCallbacks[i];
        if (!callback()) {
            // subsequent submit handlers should check for 
            // this value before executing
            event.cancelBubble = true;
            return false;
        }
    }
}

I then have my context-specific submit functions check event.cancelBubble before continuing.

For your case, you could have this code be called on the blur event for each input in your form. Granted, it's not the most efficient solution, as each function in the validationCallbacks array validates the entire form, but it will trigger validation on each blur. (validationCallbacks is an array to support multiple forms that require validation.)

Sorry it's not super specific to your situation, but it should get what you need.


I have my earlier answer about how to manually call the validation callbacks created by MicrosoftMvcJQueryValidation.js, however, there may be a simpler answer. (I'm leaving my first answer as future reference for anyone.)

The options for jQuery's Validation plug-in give you the ability to change which event triggers validation. From http://docs.jquery.com/Plugins/Validation/validate#toptions, we have the following option properties: onsubmit, onfocusout, and onkeyup. You should be able assign these options values appropriately and have jQuery Validation behave like you want.

You MAY need to tweak MicrosoftMvcJQueryValidation.js to allow for the setting of options for when it calls validation. I had to do that with my edited copy.


You can follow this example:

There's a problem with the script in MicrosoftMvcJQueryValidation.js which must be updated. Change the script MicrosoftMvcValidation.js in the step 3.

Model:

Namespace Models

    Public Class Customer

        Private _Name As String = ""
        <DisplayName("Name")> _
        <Required(ErrorMessage:="{0}: Mandatory field.")> _
        <StringLength(10, ErrorMessage:="{0}: Max lenght 10.")> _
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property

        Private _Surname As String = ""
        <DisplayName("Surname")> _
        <Required(ErrorMessage:="{0}: Mandatory field.")> _
        <StringLength(10, ErrorMessage:="{0}: Max lenght 10.")> _
        Public Property Surname() As String
            Get
                Return _Surname
            End Get
            Set(ByVal value As String)
                _Surname = value
            End Set
        End Property

    End Class

End Namespace



   <%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of MvcApplication1.Models.Customer)" %>
    <%@ Import Namespace="MvcApplication1.jQuery" %>

    ...
    <% Html.EnableClientValidation()%>
    <%  Using (Html.BeginForm())%>
        <fieldset id="FormEditSet">
            <div>
                <div>
                    <%=Html.LabelFor(Function(m) m.Name)%>
                    <%=Html.EditorFor(Function(m) m.Name)%>
                     <%=Html.ValidationMessageFor(Function(m) m.Name, "*")%>
                </div>                    
                <div>
                    <%=Html.LabelFor(Function(m) m.Surname)%>
                    <%=Html.EditorFor(Function(m) m.Surname)%>
                     <%=Html.ValidationMessageFor(Function(m) m.Surname, "*")%>
                </div>
            </div>
        </fieldset>
        <input type="image" src="<%=Url.Content("~/Content/Images/page_save_big.png")%>"
                    value="Save" title="Save" style="border: none;" />
        <%End Using%>

Html.ValidationSummaryJQuery is a new extension method you have to define (follow the example). Remember to put the script at the bottom of the page:

<script src="<%=Url.Content("~/Scripts/MicrosoftAjax/MicrosoftMvcJQueryValidation.min.js")%>" type="text/javascript"></script>


You need to bind your input fields to properties in your controller, then use the Required attribute on your properties - see http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx for an example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜