如何通过客户端验证要求数组至少有一个项目?
How can I require an array to have at least one item by means of client-side validation?
我有一个表单,用户可以在其中通过文本区域输入问题。通过点击一个按钮,他可以动态地生成更多的文本字段来输入问题。我将 Knockout 与问题绑定到的客户端视图模型一起使用。
我的简化视图(Razor)如下:
<div data-bind="foreach: openQuestions">
<div class="form-group">
<input type="hidden" data-bind="value: currentIndex" name="openQuestions.Index" />
<textarea class="form-control" rows="3" data-bind="value: question, attr: { name: 'openQuestions[' + $data.currentIndex + '].Question' }"/>
</div>
</div>
@Html.ValidationMessageFor(m => m.OpenQuestions)
Knockout VM 的一部分:
function OpenQuestion() {
var self = this;
self.currentIndex = GetRandomIndex();
self.question = ko.observable();
}
function QuestionViewModel() {
var self = this;
self.openQuestions = ko.observableArray();
self.addOpenQuestion = function () {
self.openQuestions.push(new OpenQuestion());
}
}
应该进行两次验证:
- 'OpenQuestions' 列表不应为空(因此 != null 且 >= 1 个条目)
- 上述列表中的每个问题都不能为空或为空
我很难连接 jQuery 验证器来验证数组的最小长度。我认为问题在于加载页面时,没有名称为 'OpenQuestions' 的元素,因为还没有问题。如果您此时提交,验证器找不到任何要验证的元素,并简单地假设所有内容都有效,但事实并非如此。
我尝试创建自定义 "minimum length array required" 验证属性,但我 运行 遇到了同样的问题 - 你将它连接到哪个元素?
基本上,此方法会检查它是否可以找到与提供的名称类似的任何元素(例如 'openquestions',但 'openquestions[123456]' 也可以)并将该长度与所需的最小长度进行比较。
$.validator.addMethod("minarraylength",
function (value, element, parameters) {
var minLength = parameters["minlength"];
if (element) {
var elementName = $(element).attr("name").toLowerCase();
var actualLength = $("input").filter(function () {
var currentName = $(this).attr("name");
return currentName != undefined && currentName.toLowerCase().indexOf(elementName);
}).length;
return actualLength >= minLength;
}
return true;
}
);
像这样将其与隐藏字段组合
@Html.HiddenFor(m => m.OpenQuestions)
将触发验证,但会导致模型绑定器在提交时失败,因为出于某种原因它会从隐藏字段中取出值并忽略其他所有内容。
所以问题是,如何将 jQuery 验证器连接到我动态生成的列表中,确保模型绑定在回发时有效,但防止提交空列表?
提前致谢!
您可以简单地扩展您的 KO 对象,见下文:
第 1 步:为至少 1 个要求的数组创建自定义 KO 规则
ko.validation.rules["atLeastOne"] = {
validator: function(value, validate) {
if (validate && Array.isArray(value)) {
return !!value.length;
}
return true;
},
message: "Please add at least one."
};
第 2 步更新您的代码:
function OpenQuestion() {
var self = this;
self.currentIndex = GetRandomIndex();
self.question = ko.observable().extend({
required: true,
minLength: 1
});
}
function QuestionViewModel() {
var self = this;
self.openQuestions = ko.observableArray().extend({
atLeastOne: {
message: "Please add at least one."
}
});
self.addOpenQuestion = function () {
self.openQuestions.push(new OpenQuestion());
}
}
我有一个表单,用户可以在其中通过文本区域输入问题。通过点击一个按钮,他可以动态地生成更多的文本字段来输入问题。我将 Knockout 与问题绑定到的客户端视图模型一起使用。
我的简化视图(Razor)如下:
<div data-bind="foreach: openQuestions">
<div class="form-group">
<input type="hidden" data-bind="value: currentIndex" name="openQuestions.Index" />
<textarea class="form-control" rows="3" data-bind="value: question, attr: { name: 'openQuestions[' + $data.currentIndex + '].Question' }"/>
</div>
</div>
@Html.ValidationMessageFor(m => m.OpenQuestions)
Knockout VM 的一部分:
function OpenQuestion() {
var self = this;
self.currentIndex = GetRandomIndex();
self.question = ko.observable();
}
function QuestionViewModel() {
var self = this;
self.openQuestions = ko.observableArray();
self.addOpenQuestion = function () {
self.openQuestions.push(new OpenQuestion());
}
}
应该进行两次验证:
- 'OpenQuestions' 列表不应为空(因此 != null 且 >= 1 个条目)
- 上述列表中的每个问题都不能为空或为空
我很难连接 jQuery 验证器来验证数组的最小长度。我认为问题在于加载页面时,没有名称为 'OpenQuestions' 的元素,因为还没有问题。如果您此时提交,验证器找不到任何要验证的元素,并简单地假设所有内容都有效,但事实并非如此。
我尝试创建自定义 "minimum length array required" 验证属性,但我 运行 遇到了同样的问题 - 你将它连接到哪个元素?
基本上,此方法会检查它是否可以找到与提供的名称类似的任何元素(例如 'openquestions',但 'openquestions[123456]' 也可以)并将该长度与所需的最小长度进行比较。
$.validator.addMethod("minarraylength",
function (value, element, parameters) {
var minLength = parameters["minlength"];
if (element) {
var elementName = $(element).attr("name").toLowerCase();
var actualLength = $("input").filter(function () {
var currentName = $(this).attr("name");
return currentName != undefined && currentName.toLowerCase().indexOf(elementName);
}).length;
return actualLength >= minLength;
}
return true;
}
);
像这样将其与隐藏字段组合
@Html.HiddenFor(m => m.OpenQuestions)
将触发验证,但会导致模型绑定器在提交时失败,因为出于某种原因它会从隐藏字段中取出值并忽略其他所有内容。
所以问题是,如何将 jQuery 验证器连接到我动态生成的列表中,确保模型绑定在回发时有效,但防止提交空列表?
提前致谢!
您可以简单地扩展您的 KO 对象,见下文:
第 1 步:为至少 1 个要求的数组创建自定义 KO 规则
ko.validation.rules["atLeastOne"] = {
validator: function(value, validate) {
if (validate && Array.isArray(value)) {
return !!value.length;
}
return true;
},
message: "Please add at least one."
};
第 2 步更新您的代码:
function OpenQuestion() {
var self = this;
self.currentIndex = GetRandomIndex();
self.question = ko.observable().extend({
required: true,
minLength: 1
});
}
function QuestionViewModel() {
var self = this;
self.openQuestions = ko.observableArray().extend({
atLeastOne: {
message: "Please add at least one."
}
});
self.addOpenQuestion = function () {
self.openQuestions.push(new OpenQuestion());
}
}