Reputation: 9866
I just completed the visualization logic for my form and now I want to get use of the client side validation that asp.net mvc 3 provides. However even though I'm following some examples I can't make it work and I don't know what might be the reason.
Here is my main view :
@model List<DataAccess.MCS_DocumentFields>
@{
ViewBag.Title = "Documents";
}
<div id="drawForm">
@using (Html.BeginForm("RecieveDataFromDocument", "Forms", FormMethod.Post))
{
@Html.ValidationSummary(true)
<table border="1">
<colgroup>
<col span="1" style="width: 10%;" />
<col span="1" style="width: 40%;" />
<col span="1" style="width: 25%;" />
<col span="1" style="width: 25%;" />
</colgroup>
@Html.Partial("_PartialHeader", Model)
@Html.Partial("_PartialDrawing", Model)
@Html.Partial("_PartialBody", Model)
@Html.Partial("_PartialFooter", Model)
</table>
if (ViewBag.Status == 1)
{
<button type="submit">Save</button>
}
else
{
@Html.ActionLink("Back", "Index")
}
}
</div>
Not too much here actually. Most of the logic is in my partials. I use data annotations so I thought that I'll have some client-side validation by default but it seems to not be the case. What I have done is making sure I have
<appSettings>
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
added to my web.config. Also in my view you can see that I've added
@Html.ValidationSummary(true)
not sure if this is the right place for it but it's there. Also in the example that I'm looking from there is :
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
I don't have such <div>
tags and such class names however when I start my application in the viewsource I can see for each input this :
Name comes from DB
<input data-val="true" data-val-required="The FieldValue field is required." name="[4].FieldValue" type="hidden" value="Name comes from DB" />
which I thought is enough for client side validation to take place. But because I did not get any I added in one of my partial views just for test the following :
<div class="editor-label">
@Html.DisplayFor(x => Model[i].QuestionText)
</div>
<div class="editor-field">
@Html.TextBox("datepicker", "", new { @class = "datepicker" })
@Html.ValidationMessageFor(x => Model[i].QuestionText)
</div>
@Html.HiddenFor(x => Model[i].Id)
//...some code...
<div class="editor-field">
@Html.EditorFor(x => Model[i].FieldValue)
@Html.ValidationMessageFor(x => Model[i].FieldValue)
</div>
@Html.HiddenFor(x => Model[i].Id)
//...more code..
But even those two fields doesn't generate error when validation fails. So I guess I'm either missing something or I'm doing something wrong. I doubt if this kind of validation even works this way - with partials?
Upvotes: 1
Views: 5533
Reputation: 444
in order to get the client side validation in mvc (I work on mvc4 but I think it's the same in your case), there are some steps to check:
In Web.config
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
Scripts to have in the layout (or master page)
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
Give the model validation attributes with error messages to display (for example)
public class ContactForm
{
[Display(Name = "Mail :"),
Required(AllowEmptyStrings = false, ErrorMessage = "Mail required"),
RegularExpression("^(|[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+[.][a-zA-Z]{2,3})$", ErrorMessage = "Mail not valid"),
Remote("IsValidMail", "Validate", HttpMethod="GET")] /* remote validation */
public string Mail { get; set; }
[Display(Name = "Message :"),
Required(AllowEmptyStrings = false, ErrorMessage = "Message required"),
StringLength(maximumLength: 400, ErrorMessage="Message too long")]
public string Message { get; set; }
public ContactForm() { }
}
In the view, show the error message
@Html.ValidationMessageFor(x=>x.Mail)
or
@Html.ValidationSummary(false, null, new { @id = "ValidationSummary" })
as you did.
Actually, it works like that, but in case of ajax forms within partial view, you need to rebind the validation on the page load (in the success event of the ajax call or $(function(){} of the partial view)
///because the page is loaded with ajax, the validation rules are lost, we have to rebind them:
$('#form').removeData('validator');
$('#form').removeData('unobtrusiveValidation');
$("#form").each(function () { $.data($(this)[0], 'validator', false); }); //enable to display the error messages
$.validator.unobtrusive.parse("#form");
Be careful with partial views not to double the scripts and to enable the validation. Best regards
Upvotes: 7
Reputation: 7172
just out of interest, have you tried replacing
@Html.Partial("_PartialHeader", Model)
@Html.Partial("_PartialDrawing", Model)
@Html.Partial("_PartialBody", Model)
@Html.Partial("_PartialFooter", Model)
with
@Html.EditorFor(m => Model, "_PartialHeader")
@Html.EditorFor(m => Model, "_PartialDrawing")
@Html.EditorFor(m => Model, "_PartialBody")
@Html.EditorFor(m => Model, "_PartialFooter")
Upvotes: 0
Reputation: 21
Try adding these files, maybe that can help you:
<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/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="/@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="/@Url.Content("~/Scripts/MicrosoftMvcValidation.js")" type="text/javascript"></script>
Upvotes: 0