我有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; }
}
答案 0 :(得分:1)
首先要澄清你的一些误解。
当您重新解析$.validator
时,您指示jquery.validate.unobtrusive.js
解析DOM并读取表单控件中的data-val-*
属性(由属性验证属性生成)并将规则添加到jquery.validate.js
。这是在首次加载表单时已经完成的,并且只有在您动态添加新表单控件(例如,通过ajax)时才需要再次执行此操作(您的Quantity
控件已经存在)。无论如何,您需要解析<form>
元素,而不是json对象。请参阅this answer了解正确用法。
其次,min
和max
属性仅用于HTML-5验证,与jQuery验证无关。实际上,由于jquery.validate.js
将novalidate="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