3

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/javascript" 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?

Lorenzo
  • 29,081
  • 49
  • 125
  • 222
  • From my understanding, the client-side validation does indeed occur on the browser and the request is NOT sent to the server, even though you've clicked the "submit" button. Essentially, it prevents the submit request if validation fails on the browser. It sounds like you simply need the validation to be triggered on each input's blur event instead of the submit event of the form, yes? – kdawg Nov 16 '10 at 19:15
  • @kdawg: Right! Finally someone did understand it :) – Lorenzo Nov 16 '10 at 19:24

5 Answers5

5

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.

Community
  • 1
  • 1
Lorenzo
  • 29,081
  • 49
  • 125
  • 222
1

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.

kdawg
  • 2,019
  • 21
  • 31
  • thanks a lot for posting this. It is interesting. I would try it if I cant find a standard solution. Again, thanks – Lorenzo Nov 17 '10 at 01:59
1

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.

kdawg
  • 2,019
  • 21
  • 31
  • Standing on the documentation, that I have read another time after your post, those option properties are enabled by default. When you say `You MAY need to tweak...` what do you mean exactly? – Lorenzo Nov 17 '10 at 01:56
  • 1
    They are enabled by default, but nothing is enabled at all until you call validate() on the form. The way MicrosoftMvcJQueryValidation is wired up, validate() will only be called when you click submit. Notice after clicking submit, validation does indeed occur on the blur event. So it sounds like you need to call validate() on the loading of the form if you want onblur validation, but that will mark all empty inputs as invalid at the very beginning. – kdawg Nov 17 '10 at 16:21
  • I've got it working finally. Please read my answer for details. Thanks very much for helping on this – Lorenzo Nov 18 '10 at 21:07
0

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>
LeftyX
  • 35,328
  • 21
  • 132
  • 193
  • @vandalo: hello your answer is not related to my question. Did you read it? I am asking about inline validation not validation summary – Lorenzo Nov 15 '10 at 13:36
  • I am sorry. I must have an example for that. – LeftyX Nov 15 '10 at 17:19
  • I've updated my code. There's still a problem. The inline validation starts to work after you tried to submit the form. After that it starts to work :-s – LeftyX Nov 15 '10 at 17:46
  • Maybe I am still not clear in my question but I am not using any ValidationSummary. I just need to have Validation messages around my input.... – Lorenzo Nov 16 '10 at 14:30
  • It doesn't display messages in the ValidationSummary. Which MVC version are you using? – LeftyX Nov 16 '10 at 14:59
  • and I've tried with Fiddler and HttpFox and I can confirm it doesn't submit to the server. I am testing it with MVC2, jQuery 1.4.2, jQuery validation plug-in 1.7 – LeftyX Nov 16 '10 at 15:37
  • MVC 2.0 RTM, jQuery 1.4.3 and validation 1.7. I am using the MicrosoftMvcJQueryValidation.js of the MVC Futures library available here: `http://aspnet.codeplex.com/releases/view/41742` – Lorenzo Nov 16 '10 at 19:26
  • I've downloaded MicrosoftMvcJQueryValidation.js from "MVC Futures" and setup a MVC2 sample with jQuery 1.4.3 and validation 1.7. I've used fiddler and HttpFox to debug and I can confirm that everything works fine: there's no post until you fill the form properly. I've tried with IE8, Opera 10.63, Safari 5.0.2, FF 3.6.12 and Chrome 7.0.517. – LeftyX Nov 17 '10 at 10:12
  • I've got it working finally. Please read my answer for details. Thanks very much for helping on this – Lorenzo Nov 18 '10 at 21:08
-1

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.

DIMMACK
  • 189
  • 6
  • Thank you for your answer but I think that you've missed the real question. I know how validation works in MVC. I just asked how to enable "inline" validation on the client with jquery. – Lorenzo Nov 14 '10 at 16:27