I am implementing client side validation in mvc3.
I got my form showing via jquery dialog, and submit via ajax post
I am not sure is it necessary, but i created a partial class in my Model to customize the validation:
[MetadataType(typeof (FoodMetaData))]
public partial class FOOD
{
[Bind(Exclude="FoodID")]
public class FoodMetaData
{
[ScaffoldColumn(false)]
public object FoodID { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Please enter a name")]
public object FoodName { get; set; }
[Range(1, 200, ErrorMessage = "Please enter a valid amount")]
public object FoodAmount { get; set; }
public object StorageDate { get; set; }
public object ExpiryDate { get; set; }
Currently I only get the validation shown at the amount field if i enter a string or a number out of the range. However, If i empty the Name field, nothing happen.
This is my first try on client side validation and got no idea what is happening. Can anyone please give me some advice??
Appreciate any help, thanks...
Here's an example of how you could implement a partial form with jQuery dialog.
As always start with a view model:
public class MyViewModel
{
[Required]
public string SomeProperty { get; set; }
}
then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Edit()
{
return PartialView(new MyViewModel());
}
[HttpPost]
public ActionResult Edit(MyViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
// TODO: validation passed => process the model and return a JSON success
return Json(true);
}
}
and then a ~/Views/Home/Index.cshtml
view which will contain only a link to the dialog:
@Html.ActionLink("click me for dialog", "edit", null, new { id = "showDialog" })
<div id="dialog"></div>
and a ~/Views/Home/Edit.cstml
partial which will contain the form that we want to be shown in the dialog:
@model MyViewModel
@using (Html.BeginForm())
{
@Html.LabelFor(x => x.SomeProperty)
@Html.EditorFor(x => x.SomeProperty)
@Html.ValidationMessageFor(x => x.SomeProperty)
<button type="submit">Save</button>
}
All that is left now is to wire up. So we import the necessary scripts:
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<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>
and then write our own to make the dialog live:
$(function () {
$('#showDialog').click(function () {
$('#dialog').dialog().load(this.href, function (result) {
ajaxify(this);
});
return false;
});
});
function ajaxify(dialog) {
// we need to parse client validation rules
// because the form was injected into the DOM later as
// part of the dialog. It was not present initially
// See here for more info: http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx
$.validator.unobtrusive.parse($(dialog));
// AJAXify the form
$('form', dialog).submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result === true) {
// The controller action returned a JSON result
// inidicating the success
alert('thank you for submitting');
$(dialog).dialog('close');
} else {
// there was a validation error => we refresh the dialog
// and reajaxify it as we have now modified the DOM
dialog.html(result);
ajaxify(dialog);
}
}
});
return false;
});
}
Now you could adapt this to any view model you want with any editor templates and validation rules.
I just found out that jquery client side validation is only triggered after 1st form submission after i gone through the example here: http://weblogs.asp.net/imranbaloch/archive/2011/04/30/eagerly-performing-asp-net-mvc-3-unobtrusive-client-side-validation.aspx
A great one! It helps to solve my weird problem by editing the jquery.validate.unobtrusive(.min).js file by this:
options: { // options structure passed to jQuery Validate's validate() method
errorClass: "input-validation-error",
errorElement: "span",
errorPlacement: $.proxy(onError, form),
invalidHandler: $.proxy(onErrors, form),
messages: {},
rules: {},
success: $.proxy(onSuccess, form),
onfocusout: function (element) { $(element).valid(); }
}
Thanks for every help!