Client side validation with jquery in orchard 1.3

Topics: Troubleshooting, Writing modules
Jun 26, 2012 at 10:04 AM

Hi,

I am trying to implement some client side validation on one of my forms, but i can´t get it to work properly. Read about some problem regarding this on the forum in thread http://orchard.codeplex.com/discussions/278362. However i don´t understand where i should put the class and how it should be called that is written about last in the post.

public class RegisterValidationProviders : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            ModelValidatorProviders.Providers.Clear();
            ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
            ModelValidatorProviders.Providers.Add(new DataErrorInfoModelValidatorProvider());
            ModelValidatorProviders.Providers.Add(new ClientDataTypeModelValidatorProvider());
        }
    }

can somebody help me explain that?

Developer
Jun 26, 2012 at 1:24 PM

You can put that class anywhere in your module. Autofac will find it and execute the Load method.

Jun 27, 2012 at 10:17 AM

Hi, you are right got it to work. However i don´t manage to get it to work when i have a viewmodel that contains a collection, for example

public class Person 
{ 
     public string name {get;set;} 
     public List<PhoneNumber> phoneNumbers{ get; set;} 
} 

public class PhoneNumbers 
{ 
    [Required]
    public string type {get; set;} 
    [Required]
    public int number{get;set;}
}

In my view i never gets any validation on the collection of phonenumbers, does anyone know how to bind the validation correctly for a collection?

Developer
Jun 27, 2012 at 10:34 AM

Could you show us how that view looks like? Maybe something not right with the name or id of the input elements. Does it work for the name property of the person when you set that one as required (just as a test)?

Jun 27, 2012 at 12:23 PM

Yes, i have tried to set the property name as required and got no validation error. I am opening the view in a jquery dialog, i don´t know if that has something to do with the problem because i have implemented client side validation on other forms that doesn´t open in dialogs and it work perfectly.

Anyway here is a my two views:


@model Module.Models.Person 
@{ 

    Script.Require("jQuery").AtHead();
    Script.Require("jQueryUI_Core").AtHead();
    Script.Include("~/Modules/OrderWagonModule/Script/jquery-ui-timepicker-addon.js").AtHead();
    Script.Include("~/Modules/OrderContainerModule/Script/jquery.validate.min.js").AtHead();
    Script.Include("~/Modules/OrderContainerModule/Script/jquery.validate.unobtrusive.min.js").AtHead();

}
@using (Html.BeginForm("SaveCustomerInfo", "Home", FormMethod.Post )) { ViewContext.FormContext.ValidationSummaryId = "valSumId"; @Html.ValidationSummary(false, "Ordern kunde inte skapas, �terg�rda felen", new Dictionary<string, object> { { "id", "valSumId" } }) @Html.TextBoxFor(model => model.name) @Html.EditorFor(model => model.phoneNumbers) <div style="float:left; margin-top:20px; width:1000px"> <input type="submit" name="Value" value="Spara" id="Save" /> </div> }


@model Module.Models.PhoneNumbers

<div class="PhoneNumber">
    <label>
        Type:
        @Html.TextBoxFor(x => x.type)
    </label>
    <label>
        Number:
        @Html.TextBoxFor(x => x.number)
</div>


 

Jun 27, 2012 at 12:26 PM

hmm posting the first view again.. something got very wrong...

@model Module.Models.Person 
@{ 

    Script.Require("jQuery").AtHead();
    Script.Require("jQueryUI_Core").AtHead();
    Script.Include("~/Modules/OrderWagonModule/Script/jquery-ui-timepicker-addon.js").AtHead();
    Script.Include("~/Modules/OrderContainerModule/Script/jquery.validate.min.js").AtHead();
    Script.Include("~/Modules/OrderContainerModule/Script/jquery.validate.unobtrusive.min.js").AtHead();

}


@using (Html.BeginForm("SaveCustomerInfo", "Home", FormMethod.Post ))  { 
     
ViewContext.FormContext.ValidationSummaryId = "valSumId";
      
@Html.ValidationSummary(false, "Ordern kunde inte skapas, &#65533;terg&#65533;rda felen", new Dictionary<string, object> { { "id", "valSumId" } })          
 @Html.TextBoxFor(model => model.name)     @Html.EditorFor(model => model.phoneNumbers)                

<div style="float:left; margin-top:20px; width:1000px">         
<input type="submit" name="Value" value="Spara" id="Save" />     
</div>  
}

Developer
Jun 27, 2012 at 2:43 PM

So you're saying that if you use this view without the jQuery dialog it works fine? How are you showing this view in the jQuery dialog: using an AJAX call?

If the html is somehow injected into the DOM after the page has loaded, then the jQuery validators will not pick up the new elements, and thus they will not bind to their "changed" events. If this is the case, you could manually re-apply the jQuery validation event handlers: http://stackoverflow.com/questions/6110724/jquery-validate-with-generated-ids/6111057#6111057

Jun 28, 2012 at 8:52 AM

You have understand me correctly, i am loading the dialog using a ajax call. after the ajax call i use jquery delegate to inject the DOM with the new inputs ect. But i still can´t make my validation to work. Is there anyway to make sure that the delegate function executes correctly and binds the new elements to the DOM.

I have also tried to manually call jquery validate function on click submit. But it says that the form is valid. (But it shouldn´t be).

Developer
Jun 28, 2012 at 1:54 PM

That's weird, because that's exactly what you need to do: manually setup client side validation on the AJAX loaded html using the validate method. For example:

$.get(myUrl, function(html){
   var $html = $(html);

   // Append the loaded html to the elemnent of your choice (in this example it's the body element, but it could be any element of course)
   $("body").append($html);

   // Setup validation for the loaded html
   $html.validate();
});

If it doesn't work, then try and see if you can attach any event handler at all to one of your loaded html elements, just to make sure that you setup validation on the correct variable (which should be the jquery object used in appending the html to the DOM).


Jun 28, 2012 at 2:23 PM

thx for the reply, now i have rebuild my script for opening the dialog but still no validation. The dialog opens and everything looks nice, and when i view scource all fields have proper attributes according to the validation script, but still now validation when i post the form.

            $(function () {
                $("#result3").dialog({ width: 600, resizable: true, position: 'center', title: 'Komplettera lastinfo', autoOpen: false,
                    buttons: { "Stäng": function () { $(this).dialog("close"); } }
                });
            });

            $(function () {
                $('.dialogPopup').live("click", function () {
                    $.get(this.href, function (html) {
                        var $html = $(html);
                        $("#result3").append($html).dialog('open');
                        $html.validate();
                    });
                    return false;
                });
            });

 

 

Developer
Jun 28, 2012 at 2:37 PM

And what if you changed the code a bit like this:

$(function () {
                $('.dialogPopup').live("click", function () {
                    $.get(this.href, function (html) {
                        var $html = $(html);
                        $("#result3").append($html).dialog('open');
                        $("#result3").validate();
                    });
                    return false;
                });
            });

 

Jun 28, 2012 at 2:44 PM

Made now difference.. =(

Hmm i am starting to believe that i maby missed something in some other place. I will try render the same form i render in the dialog on a new page and see if the validation script works there. maby it can help me, because right now i got no clue on what the problem is. Thx for the help, i will come back when i have done a full investigation ;)

Jun 28, 2012 at 2:50 PM

hmm i have done some investigation, when i render whe view on a new page (not in a dialog) everything works lika a charm... but i realy need to get it to work in a dialog..

Jun 29, 2012 at 10:37 AM

Victory!!, finaly i got it to work. !!

Here is the script

"Main View"

<script type="text/javascript">
          $(function () {
                $("#result3").dialog({ width: 600, resizable: true, position: 'center', title: 'Komplettera lastinfo', autoOpen: false,
                    buttons: { "St�ng": function () { $(this).dialog("close"); } }
                });
            });

            $(function () {
                $('.modal3').live("click", function () {
                    $.get(this.href, function (html) {
                        var $html = $(html);
                        $('#result3').empty();
                        $("#result3").append($html);
                        $.validator.unobtrusive.parse("#result3");
                        $("#result3").dialog('open');
                    });
                    return false;
                });
            });
	</script>

And on the view that is render in dialog:

<script type="text/javascript">
             $("#Submit").click(function (event) {
                 event.preventDefault();

                 $("#testconfirmJQ2").validate();

                 if ($("#testconfirmJQ2").valid()) {
                     alert("valid");
		     // submit form... ect
                 }
             });
	</script>

Developer
Jun 29, 2012 at 12:11 PM

Nice, great job solving this!