您可以创建一个指令来拦截
FormController
的
$setSubmitted
方法。
您可以在
此处找到有关该方法的更多信息。
请在
此处找到可工作的示例。
当该指令拦截到
$setSubmitted
方法时,我们可以通知另一个指令,在
Bootstrap弹出窗口中显示验证错误。
我基于以下假设工作(请随时纠正我):
- 您将使用form标签
- 在您的form标签上,您将使用
ng-submit="nameOfForm.$valid && vm.onSubmit()"
该解决方案包含两个指令:
submitNotify
和
popoverValidation
submitNotify
在表单提交时通知
popoverValidation
,
popoverValidation
指令会显示表单错误(如果有)。
指令1:submitNotify
directive('submitNotify', function () {
return {
restrict: 'A',
require: 'form',
controller: function SubmitNotify() { },
link: function (scope, element, attrs, form) {
var $setSubmitted = form.$setSubmitted;
form.$setSubmitted = function () {
$setSubmitted.bind(form)();
scope.$broadcast('onSubmitNotify');
};
}
};
})
解释:
- 仅能用作属性指令
- 需要一个
form
标签或 ngForm
链接函数:
链接函数使用回调函数替换了 $setSubmitted
函数。回调函数通知 popoverValidation
指令表单已被提交。
指令2:popoverValidation
directive('popoverValidation', [function () {
return {
restrict: 'A',
require: ['ngModel', '^submitNotify'],
link: function (scope, element, attrs, require) {
scope.$on('onSubmitNotify', function () {
var ngModel = require[0];
if (!ngModel.$valid) {
showPopover(ngModel.$error);
}
});
function showPopover( $error) {
var options = {
content: getValidationErrorsHtml($error),
html: true,
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content popover-content-errors"></div></div>',
title: '<span class="text-info"><strong>Error</strong></span><button type="button" data-dismiss="popover" class="close">×</button>',
trigger: 'manual'
}
$(element).popover(options);
$(element).on('shown.bs.popover', hidePopover);
$(element).popover('show');
}
function hidePopover() {
$(this).next('.popover').find('button[data-dismiss="popover"]').click(function (e) {
$(element).popover('hide');
});
}
function getValidationErrorsHtml($error) {
var errors = [];
if ($error.required) {
errors.push(requiredErrorMessage());
}
if ($error.email) {
errors.push(invalidEmailAddress());
}
var errorHtml = '<ul class="list-group">';
for (var i = 0; i < errors.length; i++) {
errorHtml += '<li class="list-group-item">' + errors[i] + '</li>';
}
errorHtml += '</ul>';
return errorHtml;
}
function requiredErrorMessage() {
return 'This field is required';
}
function invalidEmailAddress() {
return 'Please enter a valid email address';
}
}
};
}]);
说明:
- 只能用作属性指令
- 需要在父级
form
上添加submitNotify
标签
链接函数:
popoverValidation
指令被通知表单已提交
- 它检查
ng-model
绑定的属性是否有效
- 如果无效,则显示弹出窗口
完整HTML:
<form name="myForm" ng-controller="MyFormController as vm" ng-submit="myForm.$valid && vm.onSubmit()" submit-notify="" novalidate>
<div class="panel panel-primary">
<div class="panel-heading">Form Validation with Popovers</div>
<div class="panel-body">
<div class="form-group">
<label>First name</label>
<input type="text" name="firstName" class="form-control" required ng-model="person.firstName" popover-validation="" />
</div>
<div class="form-group">
<label>Surname</label>
<input type="text" name="surname" class="form-control" required ng-model="person.surname" popover-validation="" />
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="person.email" popover-validation="" />
</div>
</div>
<div class="panel-footer">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
一些CSS:
<style type="text/css">
.popover-content-errors {
padding:0px;
}
.popover-content-errors .list-group {
margin-bottom:0px
}
.popover-content-errors .list-group-item {
border-left:none;
white-space:nowrap;
}
.popover-content-errors .list-group-item:first-child {
border-top:none;
}
.popover-content-errors .list-group-item:last-child {
border-bottom:none;
}
</style>
MyFormController
controller('MyFormController', ['$scope', function ($scope) {
var self = this;
$scope.person = {
email:'john.doe.com'
}
self.onSubmit = function () {
console.log('MyFormController.onSubmit');
};
}]);
uib-popover
不适合处理此类动态内容(例如错误验证)。我曾在一个项目中尝试过类似的方法,结果并不值得使用uib-popover
的麻烦。相反,我们只需使用 CSS 和ng-class
模拟气泡的感觉。然后,我们的指令只需要根据表单处理何时隐藏/显示“气泡”。 - ryanyuyu