我有一张表格。为了验证字段(在客户端),我使用了一些HTML5和ng-message
来显示错误。
其中两个字段的行为与其他字段不同。
如果填写了这两个字段中的一个,则另一个字段也应填写。
另一方面,如果两者都没有填写,表格应该接受这两个字段为有效。
我希望在表单中有直接反馈,只要用户在两个字段之一中输入内容,另一个应该显示相应的消息。
以下代码中的2个字段为fWebsiteURL
和fWebsiteName
。
在我的指令/表单中实现这种逻辑的最佳方法是什么?
这是我部分的部分(使用jade和bootstrap 2.x.x)。
目前,只为每个字段进行了基本的required
验证,使其成为所有表单的必填项。
感谢您的帮助。
form.form-horizontal(name="scheduleForm")
.control-group(ng-class="{error: scheduleForm.fProjectName.$invalid}")
label.control-label.muted(for='fProjectName') Project
.controls
input.input-xxlarge(name="fProjectName", type='text', placeholder='Project name', ng-model="schedule.projectName", required)
small.help-inline(ng-messages="scheduleForm.fProjectName.$error")
div(ng-message="required")
| The project name is required.
.control-group(ng-class="{error: scheduleForm.fWebsiteName.$invalid}")
label.control-label.muted(for='fWebsiteName') Website name
.controls
input.input-xlarge(name="fWebsiteName", type='text', placeholder='Website name', ng-model="schedule.website.name", required)
small.help-inline(ng-messages="scheduleForm.fWebsiteName.$error")
div(ng-message="required")
| The website name is required if you entered a website link.
.control-group(ng-class="{error: scheduleForm.fWebsiteURL.$invalid}")
label.control-label.muted(for='fWebsiteURL') Website URL
.controls
input.input-xlarge(name="fWebsiteURL", type='text', placeholder='Website link', ng-model="schedule.website.url", required)
small.help-inline(ng-messages="scheduleForm.fWebsiteURL.$error")
div(ng-message="required")
| The website link is required if you entered a website name.
.control-group
.controls
button.btn.btn-primary(type='button', name='submit', ng-disabled="scheduleForm.$invalid", ng-click="update()") Save
button.btn(type='button', name='Cancel', ng-click="cancel()") Cancel
答案 0 :(得分:0)
这是一个插图,它说明了一个字段是否有效的简单示例取决于另一个字段的存在:
http://plnkr.co/edit/sr3qDWLk7jpEc520qiKs?p=preview
基本上你创建了一个验证函数:
var checkAndSet = function(first, second, scope){
if ( !_.isUndefined(first) && first !== ''){
var firstFilledSecondNot = (_.isUndefined(second) || second === '');
scope.firstFilledSecondNot = firstFilledSecondNot;
} else {
scope.firstFilledSecondNot = false;
}
};
此功能只是直接检查第一个输入何时填入,第二个输入是否填充。棘手的部分是您将验证结果放入您的范围以供隐藏输入使用:
<input name="fSecondInput" data-ng-model="firstFilledSecondNot" type="hidden" data-ui-validate="{firstInputFilledInButSecondNot: 'isFirstInputFilledInButSecondNot($value)'}">
正如您所看到的,此输入与“真实”第二个输入具有相同的名称,并具有作为范围的模型
firstFilledSecondNot
您在步骤1中的函数中公开的变量。然后您有
data-ui-validate="{firstInputFilledInButSecondNot: 'isFirstInputFilledInButSecondNot($value)'}"
阻止它获取此值并返回它。验证周期过后,你有
someForm.fSecondInput.$error.firstInputFilledInButSecondNot
你的范围内的对象,这是你想要的。
您可能刚刚使用了两个手表,然后将每个手表的结果放在scope.someForm.fSecondInputObject中,但我发现它更加丑陋:
var checkAndSet = function(first, second, scope){
if ( !_.isUndefined(first) && first !== ''){
var firstFilledSecondNot = (_.isUndefined(second) || second === '');
scope.someForm.fSecondInput.$error.firstFilledSecondNot = firstFilledSecondNot;
} else {
scope.someForm.fSecondInput.$error.firstFilledSecondNot = false;
}
};
第二位来自:
答案 1 :(得分:0)
根据@baba的评论,我认为我找到了解决问题的方法,这是我实施的逻辑。
我创建了一个负责执行验证的自定义指令。此验证程序称为coBothOrNoneValidator
。它需要2个参数,form
和other-field
。最后一个参数是与之比较的字段。
这是我的玉部分:
form.form-horizontal(name="scheduleForm")
.control-group(ng-class="{error: scheduleForm.fProjectName.$invalid}")
label.control-label.muted(for='fProjectName') Project
.controls
input.input-xxlarge(name="fProjectName", type='text', placeholder='Project name', ng-model="schedule.projectName", required)
small.help-inline(ng-messages="scheduleForm.fProjectName.$error")
div(ng-message="required")
| The project name is required.
.control-group(ng-class="{error: scheduleForm.fWebsiteName.$invalid}")
label.control-label.muted(for='fWebsiteName') Website name
.controls
input.input-xlarge(name="fWebsiteName", type='text', placeholder='Website name', ng-model="item.website.name", co-both-or-none-validator, form="scheduleForm", other-field="fWebsiteURL")
small.help-inline(ng-messages="scheduleForm.fWebsiteName.$error")
div(ng-message="bothOrNone")
| The website name is required if you entered a website link.
.control-group(ng-class="{error: scheduleForm.fWebsiteURL.$invalid}")
label.control-label.muted(for='fWebsiteURL') Website URL
.controls
input.input-xlarge(name="fWebsiteURL", type='text', placeholder='Website link', ng-model="item.website.url", co-both-or-none-validator, form="scheduleForm", other-field="fWebsiteName")
small.help-inline(ng-messages="scheduleForm.fWebsiteURL.$error")
div(ng-message="bothOrNone")
| The website link is required if you entered a website name.
.control-group
.controls
button.btn.btn-primary(type='button', name='submit', ng-disabled="scheduleForm.$invalid", ng-click="update()") Save
button.btn(type='button', name='Cancel', ng-click="cancel()") Cancel
最后,这是我的指令co-both-or-none-validator
:
angular.module('app').directive("coBothOrNoneValidator", function() {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, el, attrs, ctrl) {
var validateBothOrNone = function(value){
var form = scope[attrs.form];
var theOther = form[attrs.otherField];
var isNotValid = (value && (_.isUndefined(theOther.$modelValue) || theOther.$modelValue === ''))
ctrl.$setValidity('bothOrNone', !isNotValid);
theOther.$setValidity('bothOrNone', !isNotValid);
return value;
};
ctrl.$parsers.unshift(validateBothOrNone);
}
}
})
这是一个非常基本的demo
欢迎任何改进此代码的想法