【问题标题】:Unobtrusive validation not working on dynamically-added partial view不显眼的验证不适用于动态添加的局部视图
【发布时间】:2012-03-08 10:15:12
【问题描述】:

我目前在动态添加内容后遇到验证问题。

我有一个模型(Order)的强类型视图。这个订单可以有很多项目。该模型如下所示:

public class Order
{
    [Key]
    [HiddenInput]
    public int id { get; set; }

    [Display(Name = "Order Number")]
    public string number { get; set; }

    [Display(Name = "Order Date")]
    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime date { get; set; }

    [Required(ErrorMessage = "Beneficiary is required.")]
    [Display(Name = "Beneficiary")]
    public int beneficiary_id { get; set; }

    [Display(Name = "Beneficiary")]
    public Beneficiary beneficiary { get; set; }

    [Display(Name = "Items")]
    public List<Item> items { get; set; }

    [Display(Name = "Payment Method")]
    public List<PaymentMethod> payment_methods { get; set; }
}

我输入订单信息以及该特定订单的商品。我尝试了几种动态添加内容的方法,最后选择了Steven Sanderson's way

在我看来,我有常规的订单信息,然后是商品,我的模型看起来像这样:

@model trackmeMvc.Models.Model.Order
@{
    ViewBag.Title = "Create";
    Html.EnableClientValidation();
    Html.EnableUnobtrusiveJavaScript();
}

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

@using (Html.BeginForm("Create", "Order", FormMethod.Post, new { @id = "create_order" }))
    {
    @Html.ValidationSummary(true, "Order creation was unsuccessful. Please correct the errors and try again.")

    <div class="editor-label">
        @Html.LabelFor(m => m.date)<req>*</req>
    </div>
    <div class="editor-field">
        @Html.TextBoxFor(m => m.date, new { @id = "order_date" })<br />
        @Html.ValidationMessageFor(m => m.date)
    </div>

...

<script type="text/javascript">

    $(document).ready(function () {

        $("#addItem").click(function () {

            var formData = $("#main_div").closest("form").serializeArray();

            $.ajax({
                url: "/IPO/BlankItemRow",
                type: "POST",
                //data: formData,
                cache: false,
                success: function (html) {
                    $("#editorRows").append(html);
                        //$.validator.uobtrusive.parseDynamicContent("form *");
                        //$("#editorRows").removeData("validator");
                        //$("#editorRows").removeData("unobtrusiveValidation");
                        //$.validator.unobtrusive.parse("#editorRows");
                        //$.validator.unobtrusive.parse("#create_ipo");
                        //$.validator.unobtrusive.parseDynamicContent($(this).first().closest("form"));
                        //$.validator.unobtrusive.parse($("#new_ipo_item"));

                        //$.validator.unobtrusive.parseElement($("#editorRows").find(".editRow:last").children().find("select"));
                           //$("#editorRows").find(".editRow:last").find("select").each(function () {
                           //alert($(this).attr("id"));
                           //$.validator.unobtrusive.parseElement($(this));
                           //$.validator.unobtrusive.parseDynamicContent($(this));
                           //$.validator.unobtrusive.parseDynamicContent($(this).attr("name"));
                       //});
                           //$("#editorRows").children().find(".editRows:last").find("*").each(function () {
                           //  alert($(this).attr('id'));

                           //$.validator.unobtrusive.parseDynamicContent('input');
                       //});
                       //var form = $(this).closest("form").attr("id");
                       //$(form).removeData("validator");
                       //$(form).removeData("unobtrusiveValidation");
                       //$.validator.unobtrusive.parse(form);
                    }
                });
            return false;
        });
    });

</script>

这些是我尝试过的一些东西,但没有任何效果。

我从Applying unobtrusive jquery validation to dynamic content in ASP.Net MVC 获得了parseDynamicContent。我在我能想到的所有场景中都尝试了它,但仍然没有运气。

我也尝试了常规解析,从表单中删除验证然后再次应用它,但仍然没有验证新添加的元素:

<div id="editorRows">
    @foreach (var item in Model.items)
    {
        @Html.Partial("_NewItem", item)
    }
</div>

...我的部分视图看起来像这样:

@model trackmeMvc.Models.Model.Item 

@{
    Layout = "";    
    Html.EnableClientValidation(true);

    if (this.ViewContext.FormContext == null)
    {
        this.ViewContext.FormContext = new FormContext();
    }
}

<div class="editRow">

@using (Html.BeginCollectionItem("order_items"))
{

    @Html.DropDownListFor(m => m.item_id, @items, "None", new { @style = "width:205px;", @id = "ddlItems", @class="ddlItem", @name="ddlItemList" })
    @Html.ValidationMessageFor(m => m.item_id)

    ...

}

</div>

所以发生的事情是,默认情况下,我有一个空项目从控制器发送到视图,以显示一个空行。该项目已验证,但是当我单击添加项目时,会出现另一行,从该部分开始,但我无法对其进行验证。我试图将验证放在局部视图中(在主窗体中准备好文档之前),并且我应用的所有阅读内容都以相同的方式结束:验证第一行,而不是其他行。我尝试了为此目的对 Steven Sanderson 进行的验证 - 仍然没有运气 - 甚至是对部分的验证,发现 at this link 以及随后特定于部分验证的页面......

我应该怎么做才能让这个验证生效?

【问题讨论】:

标签: asp.net-mvc razor partial-views unobtrusive-validation dynamically-generated


【解决方案1】:

对我有用的是在调用加载局部视图后重新应用验证器。就我而言,我使用的是 $.post().then(),但您可以使用 AJAX 调用的 .always() 回调来做类似的事情。

$.post(url, model, function (data) {
    //load the partial view
    $("#Partial").html(data);
}).then(function () {
    $("form").each(function () { $.data($(this)[0], 'validator', false); });
    $.validator.unobtrusive.parse("form");
});

【讨论】:

    【解决方案2】:

    好的,我将在这里重新开始一个新的答案。

    在调用 $.validator.unobtrusive.parse 之前,请从表单中删除原始验证器和不显眼的验证,如下所示:

    var form = $("#main_div").closest("form");
    form.removeData('validator');
    form.removeData('unobtrusiveValidation');
    $.validator.unobtrusive.parse(form);
    

    here 记录了相同的答案。

    【讨论】:

    • 您好,感谢您的回复。我正在使用 MVC 3,对“order_items”感到抱歉,它实际上是“items”,只是一个错字。 @items 是一个选择列表,我从所有项目的数据库中获取。在订单类的 List 项目中,所有项目属性都是必需的,发生的事情是在我的控制器中我放了一个空项目默认情况下,该行在客户端被验证。所以我已经替换了脚本,不按照你的建议使用缩小版本。现在我已经检查了 data-val="true" 以及所有被添加到动态添加的控件的内容。继续...
    • 因此,当我尝试删除不显眼的验证时,它消失了,当我尝试将其放回原处时,它只验证第一个页面加载时的项目,没有动态添加任何内容..我已经尝试使用 chrome 进行调试,但是当我点击 $.validator.unobtrusive.parse($("#main_div").closest("form"));它到达函数的末尾,命中脚本文件“jquery-1.5.1.min.js”,它不应该进入验证器脚本吗?我对这个 chrome 调试的东西不太熟悉.. 但是缺少的链接在哪里?因为当我删除验证器并重新添加它们时,它们会再次工作
    • 这意味着它正在被调用,但由于某种原因,它不会影响动态添加的内容,它只是在添加任何控件之前验证所有内容。那会是什么?
    • 我按照你说的把断点放在那里,我检查了一下,它也在动态添加的元素上运行,它不起作用吗?怎么了?
    • 我已经使用您的代码构建了一个类似的场景,并且验证对我有用。一定还有其他你遗漏的东西。 Chrome 调试器是否报告任何错误?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2013-12-28
    • 1970-01-01
    相关资源
    最近更新 更多