jquery client side validation only works at certai

2019-06-09 20:20发布

问题:

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...

回答1:

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.



回答2:

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!