如何使用ajax更新特定字段后触发范围验证

时间:2017-11-07 03:10:59

标签: asp.net-mvc asp.net-ajax unobtrusive-validation razorengine

我有2个字段总数量,它在下拉列表选择中更新,而字段输入的数量应该小于或等于总数量。下拉选择通过ajax调用获取数据。我知道DOM中的动态更新值需要强制再次解析验证。但它似乎不起作用。所有其他验证在表单中正常工作。 SO中提到的类似问题SO1 SO2 代码尝试了:

   @using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">       
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.PurchaseOrderID, "PurchaseOrderID", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-4">
                @Html.DropDownListFor(u => u.PurchaseOrderID, Model.PurchaseOrders, "--Select--")
                @Html.ValidationMessageFor(model => model.PurchaseOrderID, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.POTotalQuantity, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-4">
                @Html.EditorFor(model => model.POTotalQuantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })

            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Quantity, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-4">
                @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @type = "number", min = "1", max = Model.POTotalQuantity.ToString() } })
                @Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.ExpectedDeliveryDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-3">
                @Html.EditorFor(model => model.ExpectedDeliveryDate, "{0:dd/mm/yyyy}", new { htmlAttributes = new { @class = "form-control datepicker" } })
                @Html.ValidationMessageFor(model => model.ExpectedDeliveryDate, "", new { @class = "text-danger" })
            </div>
        </div>


        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </div>
    </div>
}

控制器:

 public JsonResult PopulatePODetails(int POID)
    {
        var purchaseOrder = db.PurchaseOrders.Find(POID);

        var poTotalQty = db.PurchaseOrderLineItems.Where(p => p.PurchaseOrderID == purchaseOrder.ID).Sum(q => q.Quantity);

        // Build an anonymous object 
        var data = new
        {
            POTotalQty = poTotalQty

        };
        return Json(data, JsonRequestBehavior.AllowGet);
    }

JS:

 $(document).ready(function () {
//Populating PO quantity on PO selection
    $('#PurchaseOrderID').change(function () {

        if (($(this).val() == "") || ($(this).val() == "0")) {
            //need to clear textbox values
            $('#POTotalQuantity').val('');

        }
        else {
            var poId = $(this).val();

            var url = '@Url.Action("PopulatePODetails", "DeliverySchedules")';
            $.getJSON(url, { POID: poId }, function (response) {
                $('#POTotalQuantity').val(response.POTotalQty);
                $.validator.unobtrusive.parse($(response));
            });
        }
    });


});

型号:

  public class DeliveryScheduleVM
    {
        public int ID { get; set; }
//omitted other properties 
        public IEnumerable<SelectListItem> PurchaseOrders { get; set; }
        [DisplayName("PO Total Qty")]
        public int POTotalQuantity { get; set; }// this is used as the upper limit 
        [Required]
        public int Quantity { get; set; }
    }

1 个答案:

答案 0 :(得分:1)

首先要澄清你的一些误解。

当您重新解析$.validator时,您指示jquery.validate.unobtrusive.js解析DOM并读取表单控件中的data-val-*属性(由属性验证属性生成)并将规则添加到jquery.validate.js。这是在首次加载表单时已经完成的,并且只有在您动态添加新表单控件(例如,通过ajax)时才需要再次执行此操作(您的Quantity控件已经存在)。无论如何,您需要解析<form>元素,而不是json对象。请参阅this answer了解正确用法。

其次,minmax属性仅用于HTML-5验证,与jQuery验证无关。实际上,由于jquery.validate.jsnovalidate="novalidate"属性添加到<form>元素,因为它们不能很好地协作,所以它们甚至无法工作。

客户端和服务器端验证所需要的是实现ValidationAttribute的条件IClientValidatable和相关脚本,以便Quantity的值可以与{的值进行比较{1}}。有关编写自己的条件验证属性的良好指南,我建议The Complete Guide To Validation In ASP.NET MVC 3 - Part 2。在您的情况下,您可能会编写一个像

一样使用的属性
POTotalQuantity

如果您不想编写自己的插件,也可以使用foolproof插件中的条件验证属性。

下载程序包(并在您的视图中包含[Required] [Bewteen(1, "POTotalQuantity")] public int Quantity { get; set; } 脚本)并使用

装饰您的属性
mvcfoolproof.unobtrusive.js
相关问题