Alnedru
Alnedru

Reputation: 2655

MVC3 Editor template doesn't generate client side validation

I have an issue, basically i have a form with lots of fields in it, and all of them have a required attribute set, so when you just leave it empty and click ok, you get client side validation and it becomes red. It words fine for everything exept EditorTemplate.

My model is following:

public class MyModel
{
  [Required]
  public string Username{get;set;}

  public Location Loc{get;set;}
}

public class Location
{
    [Required]
  public string Loc1{get;set;}
    [Required]
  public string Loc2{get;set;}
}

I have following in my main view:

@Html.EditorFor(m => m.Location, Model.Location)

And here is my EditorTemplate:

<tr>
    <td class="editor-label">
        @Html.LabelFor(m => m.Loc1)
    </td>
    <td class="editor-field">
        @Html.DropDownListFor(m => m.Loc1, Model.Locs==null?Enumerable.Empty<SelectListItem>():Model.Locs, "---select--", new { @class = "location-ddl" })
    </td>
    <td>
        @Html.ValidationMessageFor(m => m.Loc1)
    </td>
</tr>

...

After investigating it thouroughtly i noticed that HTML it prodcues is following:

<select name="Location.Loc1" id="Location_Loc1">

As you can see it lacks some attributes for the client side validation, normally it should be like this:

<select name="Loc1" id="Loc1" data-val-required="The Loc1field is required." data-val="true">

My question is, why the editor template doesn't generate the correct html output with the validation on client side, and how to fix it?

Just for a note it does work server side, so if those selects are empty on server side it will be marked as not filled in and sent back. But still, i would like to understand the behaviour of the editorform and the way to fix it.

Thanks

Upvotes: 4

Views: 903

Answers (2)

AlexMelw
AlexMelw

Reputation: 2624

I think that the usage of Html.GetUnobtrusiveValidationAttributes() should be explained in more detail.

Assuming that your Editor Template model is Location, you had to add the following block of code at the top of file:

@{
     IDictionary<string, Object> htmlAttributeValuePairsLoc1 = Html.GetUnobtrusiveValidationAttributes(Html.NameFor(m=>m.Loc1).ToHtmlString());
     htmlAttributeValuePairsLoc1.Add("class","location-ddl");

     IDictionary<string, Object> htmlAttributeValuePairsLoc2 = Html.GetUnobtrusiveValidationAttributes(Html.NameFor(m=>m.Loc1).ToHtmlString());
     htmlAttributeValuePairsLoc2.Add("class","location-ddl");
}

Now you can inject the appropriate dictionary into your HtmlHelpers, like this:

<tr>
    <td class="editor-label">
        @Html.LabelFor(m => m.Loc1)
    </td>
    <td class="editor-field">
        @Html.DropDownListFor(m => m.Loc1,
              Model.Locs??Enumerable.Empty<SelectListItem>(),
              "---select--",
              htmlAttributeValuePairsLoc1)
    </td>
    <td>
        @Html.ValidationMessageFor(m => m.Loc1)
    </td>
</tr>

P.S. Html.NameFor() appeared in MVC4, but you can obtain property's name using Reflection.

Upvotes: 0

Kirix
Kirix

Reputation: 41

You can use Html.GetUnobtrusiveValidationAttributes("Location.Loc1") to obtain validation attributes. See documentation here.

Upvotes: 1

Related Questions