我正在使用Angular和Bootstrap。以下是供参考的代码:
<form name="newUserForm" ng-submit="add()" class="" novalidate>
<input type="text" class="input" ng-model="newUser.uname" placeholder="Twitter" ng-pattern="/^@[A-Za-z0-9_]{1,15}$/" required></td>
<button type="submit" ng-disabled="newUserForm.$invalid" class="btn btn-add btn-primary">Add</button>
</form>
Bootstrap包含input:invalid {.... }
形式的无效字段样式;当田地空无一人时,这些就开始了。现在我也通过Angular进行了一些模式匹配。当“:invalid”关闭但是“.ng-invalid”打开时,这会产生奇怪的情况,这需要我为“.ng-invalid”类重新实现bootstrap CSS类。
我看到两个选项,但两个都有问题
Angular-Bootstrap指令不包括样式。
答案 0 :(得分:92)
使用Bootstrap的“错误”类进行样式设置。你可以少写代码。
<form name="myForm">
<div class="control-group" ng-class="{error: myForm.name.$invalid}">
<label>Name</label>
<input type="text" name="name" ng-model="project.name" required>
<span ng-show="myForm.name.$error.required" class="help-inline">
Required</span>
</div>
</form>
修改强> 正如其他答案和评论所指出的那样 - 在Bootstrap 3中,类现在是“has-error”,而不是“error”。
答案 1 :(得分:47)
Bootstrap 3中的类已经改变:
<form class="form-horizontal" name="form" novalidate ng-submit="submit()" action="/login" method="post">
<div class="row" ng-class="{'has-error': form.email.$invalid, 'has-success': !form.email.$invalid}">
<label for="email" class="control-label">email:</label>
<div class="col">
<input type="email" id="email" placeholder="email" name="email" ng-model="email" required>
<p class="help-block error" ng-show="form.email.$dirty && form.email.$error.required">please enter your email</p>
<p class="help-block error" ng-show="form.email.$error.email">please enter a valid email</p>
...
请注意'has-error'
和'has-success'
周围的引号:需要一段时间才能找到...
答案 2 :(得分:34)
另一个解决方案:Create指令根据子输入切换has-error
类。
app.directive('bsHasError', [function() {
return {
restrict: "A",
link: function(scope, element, attrs, ctrl) {
var input = element.find('input[ng-model]');
if (input.length) {
scope.$watch(function() {
return input.hasClass('ng-invalid');
}, function(isInvalid) {
element.toggleClass('has-error', isInvalid);
});
}
}
};
}]);
然后在模板中简单使用它
<div class="form-group" bs-has-error>
<input class="form-control" ng-model="foo" ng-pattern="/.../"/>
</div>
答案 3 :(得分:22)
@farincz's answer的小改进。我同意指令是最好的方法,但我不想在每个.form-group
元素上重复它,所以我更新了代码以允许将其添加到.form-group
或父级<form>
元素(将其添加到所有包含的.form-group
元素):
angular.module('directives', [])
.directive('showValidation', [function() {
return {
restrict: "A",
link: function(scope, element, attrs, ctrl) {
if (element.get(0).nodeName.toLowerCase() === 'form') {
element.find('.form-group').each(function(i, formGroup) {
showValidation(angular.element(formGroup));
});
} else {
showValidation(element);
}
function showValidation(formGroupEl) {
var input = formGroupEl.find('input[ng-model],textarea[ng-model]');
if (input.length > 0) {
scope.$watch(function() {
return input.hasClass('ng-invalid');
}, function(isInvalid) {
formGroupEl.toggleClass('has-error', isInvalid);
});
}
}
}
};
}]);
答案 4 :(得分:17)
@Andrew Smith答案的小改进。
我更改输入元素并使用require
关键字。
.directive('showValidation', [function() {
return {
restrict: "A",
require:'form',
link: function(scope, element, attrs, formCtrl) {
element.find('.form-group').each(function() {
var $formGroup=$(this);
var $inputs = $formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if ($inputs.length > 0) {
$inputs.each(function() {
var $input=$(this);
scope.$watch(function() {
return $input.hasClass('ng-invalid');
}, function(isInvalid) {
$formGroup.toggleClass('has-error', isInvalid);
});
});
}
});
}
};
}]);
答案 5 :(得分:11)
感谢@farincz提供了一个很好的答案。以下是我为了适应我的用例而进行的一些修改。
此版本提供三个指令:
bs-has-success
bs-has-error
bs-has
(方便您何时使用其他两个)我所做的修改:
element.find()
的字符串,因为Angular的element.find()
jQLite仅支持按标记名查找元素。element.find()
包裹在$timeout
中,以支持元素可能还没有将其呈现给DOM的情况(例如,如果元素的子元素标有{{} 1}})。ng-if
表达式以检查返回数组的长度(来自@farincz's answer的if
始终返回true,因为if(input)
的返回是jQuery数组)。 我希望有人觉得这很有用!
element.find()
用法:
angular.module('bs-has', [])
.factory('bsProcessValidator', function($timeout) {
return function(scope, element, ngClass, bsClass) {
$timeout(function() {
var input = element.find('input');
if(!input.length) { input = element.find('select'); }
if(!input.length) { input = element.find('textarea'); }
if (input.length) {
scope.$watch(function() {
return input.hasClass(ngClass) && input.hasClass('ng-dirty');
}, function(isValid) {
element.toggleClass(bsClass, isValid);
});
}
});
};
})
.directive('bsHasSuccess', function(bsProcessValidator) {
return {
restrict: 'A',
link: function(scope, element) {
bsProcessValidator(scope, element, 'ng-valid', 'has-success');
}
};
})
.directive('bsHasError', function(bsProcessValidator) {
return {
restrict: 'A',
link: function(scope, element) {
bsProcessValidator(scope, element, 'ng-invalid', 'has-error');
}
};
})
.directive('bsHas', function(bsProcessValidator) {
return {
restrict: 'A',
link: function(scope, element) {
bsProcessValidator(scope, element, 'ng-valid', 'has-success');
bsProcessValidator(scope, element, 'ng-invalid', 'has-error');
}
};
});
您还可以安装将所有这些捆绑在一起的Guilherme bower package。
答案 6 :(得分:4)
如果样式是问题,但您不想禁用本机验证,为什么不使用您自己的更具体的样式覆盖样式?
input.ng-invalid, input.ng-invalid:invalid {
background: red;
/*override any styling giving you fits here*/
}
使用CSS选择器特异性来解决您的问题!
答案 7 :(得分:2)
我对Jason Im的回答改进了以下内容,增加了两个新的指令show-validation-errors和show-validation-error。
'use strict';
(function() {
function getParentFormName(element,$log) {
var parentForm = element.parents('form:first');
var parentFormName = parentForm.attr('name');
if(!parentFormName){
$log.error("Form name not specified!");
return;
}
return parentFormName;
}
angular.module('directives').directive('showValidation', function () {
return {
restrict: 'A',
require: 'form',
link: function ($scope, element) {
element.find('.form-group').each(function () {
var formGroup = $(this);
var inputs = formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if (inputs.length > 0) {
inputs.each(function () {
var input = $(this);
$scope.$watch(function () {
return input.hasClass('ng-invalid') && !input.hasClass('ng-pristine');
}, function (isInvalid) {
formGroup.toggleClass('has-error', isInvalid);
});
$scope.$watch(function () {
return input.hasClass('ng-valid') && !input.hasClass('ng-pristine');
}, function (isInvalid) {
formGroup.toggleClass('has-success', isInvalid);
});
});
}
});
}
};
});
angular.module('directives').directive('showValidationErrors', function ($log) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var inputName = attrs['showValidationErrors'];
element.addClass('ng-hide');
if(!inputName){
$log.error("input name not specified!")
return;
}
$scope.$watch(function () {
return !($scope[parentFormName][inputName].$dirty && $scope[parentFormName][inputName].$invalid);
},function(noErrors){
element.toggleClass('ng-hide',noErrors);
});
}
};
});
angular.module('friport').directive('showValidationError', function ($log) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var parentContainer = element.parents('*[show-validation-errors]:first');
var inputName = parentContainer.attr('show-validation-errors');
var type = attrs['showValidationError'];
element.addClass('ng-hide');
if(!inputName){
$log.error("Could not find parent show-validation-errors!");
return;
}
if(!type){
$log.error("Could not find validation error type!");
return;
}
$scope.$watch(function () {
return !$scope[parentFormName][inputName].$error[type];
},function(noErrors){
element.toggleClass('ng-hide',noErrors);
});
}
};
});
})();
show-validation-errors可以添加到错误容器中,以便它根据表单字段的有效性显示/隐藏容器。
并且show-validation-error显示或隐藏基于该表单的元素字段对给定类型的有效性。
预期用途的一个例子:
<form role="form" name="organizationForm" novalidate show-validation>
<div class="form-group">
<label for="organizationNumber">Organization number</label>
<input type="text" class="form-control" id="organizationNumber" name="organizationNumber" required ng-pattern="/^[0-9]{3}[ ]?[0-9]{3}[ ]?[0-9]{3}$/" ng-model="organizationNumber">
<div class="help-block with-errors" show-validation-errors="organizationNumber">
<div show-validation-error="required">
Organization number is required.
</div>
<div show-validation-error="pattern">
Organization number needs to have the following format "000 000 000" or "000000000".
</div>
</div>
</div>
</form>
答案 8 :(得分:2)
我认为现在回答已经太晚了,但希望你会喜欢它:
CSS 您可以添加其他类型的控件,如选择,日期,密码等
input[type="text"].ng-invalid{
border-left: 5px solid #ff0000;
background-color: #FFEBD6;
}
input[type="text"].ng-valid{
background-color: #FFFFFF;
border-left: 5px solid #088b0b;
}
input[type="text"]:disabled.ng-valid{
background-color: #efefef;
border: 1px solid #bbb;
}
HTML :除了ng-required(
)之外,无需在控件中添加任何内容<input type="text"
class="form-control"
ng-model="customer.ZipCode"
ng-required="true">
试试它并在你的控件中键入一些文字,我觉得它非常方便和棒极了。
答案 9 :(得分:1)
如果没有小提琴,很难确定,但是看看angular.js代码它不会替换类 - 它只是添加并删除它自己的。因此,任何引导类(由引导程序UI脚本动态添加)都应该不受角度的影响。
也就是说,使用Bootstrap的JS功能与Angular同时进行验证是没有意义的 - 只使用Angular。我建议你使用bootstrap样式和角度JS,即使用自定义验证指令将bootstrap css类添加到元素中。
答案 10 :(得分:1)
<div class="form-group has-feedback" ng-class="{ 'has-error': form.uemail.$invalid && form.uemail.$dirty }">
<label class="control-label col-sm-2" for="email">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" ng-model="user.email" name="uemail" placeholder="Enter email" required>
<div ng-show="form.$submitted || form.uphone.$touched" ng-class="{ 'has-success': form.uemail.$valid && form.uemail.$dirty }">
<span ng-show="form.uemail.$valid" class="glyphicon glyphicon-ok-sign form-control-feedback" aria-hidden="true"></span>
<span ng-show="form.uemail.$invalid && form.uemail.$dirty" class="glyphicon glyphicon-remove-circle form-control-feedback" aria-hidden="true"></span>
</div>
</div>
</div>
答案 11 :(得分:1)
当我没有听到AngularJS本身的名字时,我知道这是一个非常古老的问题答案: - )
但是对于那些登陆此页面以便以干净自动的方式寻找Angular + Bootstrap表单验证的人来说,我已经编写了一个非常小的模块来实现相同的功能,而无需改变任何形式的HTML或Javascript。
结帐Bootstrap Angular Validation。
以下是三个简单的步骤:
bower install bootstrap-angular-validation --save
<script src="bower_components/bootstrap-angular-validation/dist/bootstrap-angular-validation.min.js"></script>
bootstrap.angular.validation
添加到您的应用中,就是这样! 适用于Bootstrap 3, jQuery 不需要。
这是基于jQuery验证的概念。此模块为验证错误提供了一些额外的验证和常见通用消息。