在Angular Form提交中触发所有字段的validation
我使用这种方法: http : //plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview只validation模糊领域。 这工作正常,但我也想validation他们(并因此显示这些字段的错误,如果有的话),当用户点击“提交”button(不是一个真正的提交,而是一个数据ng单击调用一个函数)
点击该button时,是否有某种方法可以再次触发所有字段的validation?
对我来说有效的是使用$setSubmitted
函数,它首先在1.3.20版本的angular度文档中出现。
在我想触发validation的点击事件中,我做了以下操作:
vm.triggerSubmit = function() { vm.homeForm.$setSubmitted(); ... }
这就是我所需要的一切。 根据文档,它“将表单设置为提交状态”。 这里提到。
我知道,回答有点晚了,但是你需要做的就是强迫所有forms变得肮脏。 看看下面的代码片段:
angular.forEach($scope.myForm.$error.required, function(field) { field.$setDirty(); });
然后你可以检查你的表单是否有效使用:
if($scope.myForm.$valid) { //Do something }
最后,我想,如果一切都看起来不错,你会想改变你的路线:
$location.path('/somePath');
编辑 :表单将不会在自己的范围注册,直到提交事件触发。 只需使用ng-submit指令来调用一个函数,并将上述函数包装在该函数中,它就可以工作。
你可以使用Angular-Validator来做你想做的事情。 这是愚蠢的使用简单。
它会:
- 只validation
$dirty
或submit
的字段 - 如果无效,请阻止提交表单
- 显示自定义错误消息后领域
$dirty
或表单提交
看演示
例
<form angular-validator angular-validator-submit="myFunction(myBeautifulForm)" name="myBeautifulForm"> <!-- form fields here --!> <button type="submit">Submit</button> </form>
如果该字段没有通过validator
则用户将无法提交表单。
查看angular-validator用例和示例以获取更多信息。
免责声明:我是Angular-Validator的作者
如果有人稍后回来…以上都没有为我工作。 所以我深入到了angular度表单validation的内核,并find了他们在给定字段上执行validation器的函数。 这个属性被称为$validate
。
如果你有一个命名的formsmyForm
,你可以编程调用myForm.my_field.$validate()
来执行字段validation。 例如:
<div ng-form name="myForm"> <input required name="my_field" type="text" ng-blur="myForm.my_field.$validate()"> </div>
请注意,调用$validate
会影响您的模型。 从ngModelCtrl的angular度文档。$ validate:
运行每个注册的validation器(第一个同步validation器,然后是asynchronousvalidation器)。 如果有效性更改为无效,则模型将设置为undefined,除非ngModelOptions.allowInvalid为true。 如果有效性更改为有效,则会将模型设置为最后一个可用的有效$ modelValue,也就是最后parsing的值或从范围中设置的最后一个值。
所以如果你打算用无效的模型值做一些事情(比如popup一条消息告诉它们),那么你需要确保你的模型的allowInvalid
设置为true
。
那么,angular度的方法就是让它处理validation,因为它在每次模型更改时都会执行 – 只在需要时才显示结果给用户。
在这种情况下,您决定何时显示错误,您只需设置一个标志: http : //plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p=preview
据我所知,有一个问题提交给angular,让我们有更先进的forms控制。 由于它没有解决,我会用这个而不是重新创build所有现有的validation方法。
编辑:但是,如果你坚持你的方式,这是你的修改提琴之前提交validation小提琴。 http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview控制器广播一个事件,当button被点击时,指令执行validation魔术。;
一种方法是强制所有属性变脏。 你可以在每个控制器中做到这一点,但它变得非常混乱。 有一个通用的解决scheme会更好。
我能想到的最简单的方法是使用指令
- 它将处理表单提交属性
- 它遍历所有的表单域,并将原始域标记为脏
- 它会在调用提交函数之前检查表单是否有效
这是指令
myModule.directive('submit', function() { return { restrict: 'A', link: function(scope, formElement, attrs) { var form; form = scope[attrs.name]; return formElement.bind('submit', function() { angular.forEach(form, function(field, name) { if (typeof name === 'string' && !name.match('^[\$]')) { if (field.$pristine) { return field.$setViewValue(field.$value); } } }); if (form.$valid) { return scope.$apply(attrs.submit); } }); } }; });
并更新您的表单html,例如:
<form ng-submit='justDoIt()'>
变为:
<form name='myForm' novalidate submit='justDoIt()'>
在这里查看完整的示例: http : //plunker.co/edit/QVbisEK2WEbORTAWL7Gu?p=preview
基于Thilak的回答,我能够想出这个解决scheme…
由于我的表单字段只显示validation消息,如果一个字段是无效的,并已被用户触及我能够使用这个代码触发一个button来显示我的无效字段:
// Show/trigger any validation errors for this step angular.forEach(vm.rfiForm.stepTwo.$error, function(error) { angular.forEach(error, function(field) { field.$setTouched(); }); }); // Prevent user from going to next step if current step is invalid if (!vm.rfiForm.stepTwo.$valid) { isValid = false; }
<!-- form field --> <div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }"> <!-- field label --> <label class="control-label">Suffix</label> <!-- end field label --> <!-- field input --> <select name="Parent_Suffix__c" class="form-control" ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes" ng-model="rfi.contact.Parent_Suffix__c" /> <!-- end field input --> <!-- field help --> <span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched"> <span ng-message="required">this field is required</span> </span> <!-- end field help --> </div> <!-- end form field -->
这是我的全局函数,用于显示表单错误消息。
function show_validation_erros(form_error_object) { angular.forEach(form_error_object, function (objArrayFields, errorName) { angular.forEach(objArrayFields, function (objArrayField, key) { objArrayField.$setDirty(); }); }); };
而在我的任何控制器中,
if ($scope.form_add_sale.$invalid) { $scope.global.show_validation_erros($scope.form_add_sale.$error); }
我喜欢这种处理button点击validation的方法 。
-
没有必要从控制器调用任何东西,
-
它都是用指令处理的。
在github上
你可以试试这个:
// The controller $scope.submitForm = function(form){ //Force the field validation angular.forEach(form, function(obj){ if(angular.isObject(obj) && angular.isDefined(obj.$setDirty)) { obj.$setDirty(); } }) if (form.$valid){ $scope.myResource.$save(function(data){ //.... }); } }
<!-- FORM --> <form name="myForm" role="form" novalidate="novalidate"> <!-- FORM GROUP to field 1 --> <div class="form-group" ng-class="{ 'has-error' : myForm.field1.$invalid && myForm.field1.$dirty }"> <label for="field1">My field 1</label> <span class="nullable"> <select name="field1" ng-model="myresource.field1" ng-options="list.id as list.name for list in listofall" class="form-control input-sm" required> <option value="">Select One</option> </select> </span> <div ng-if="myForm.field1.$dirty" ng-messages="myForm.field1.$error" ng-messages-include="mymessages"></div> </div> <!-- FORM GROUP to field 2 --> <div class="form-group" ng-class="{ 'has-error' : myForm.field2.$invalid && myForm.field2.$dirty }"> <label class="control-label labelsmall" for="field2">field2</label> <input name="field2" min="1" placeholder="" ng-model="myresource.field2" type="number" class="form-control input-sm" required> <div ng-if="myForm.field2.$dirty" ng-messages="myForm.field2.$error" ng-messages-include="mymessages"></div> </div> </form> <!-- ... --> <button type="submit" ng-click="submitForm(myForm)">Send</button>
我做了一些以下的工作。
<form name="form" name="plantRegistrationForm"> <div ng-class="{ 'has-error': (form.$submitted || form.headerName.$touched) && form.headerName.$invalid }"> <div class="col-md-3"> <div class="label-color">HEADER NAME <span class="red"><strong>*</strong></span></div> </div> <div class="col-md-9"> <input type="text" name="headerName" id="headerName" ng-model="header.headerName" maxlength="100" class="form-control" required> <div ng-show="form.$submitted || form.headerName.$touched"> <span ng-show="form.headerName.$invalid" class="label-color validation-message">Header Name is required</span> </div> </div> </div> <button ng-click="addHeader(form, header)" type="button" class="btn btn-default pull-right">Add Header </button> </form>
在你的控制器,你可以做;
addHeader(form, header){ let self = this; form.$submitted = true; ... }
你也需要一些CSS;
.label-color { color: $gray-color; } .has-error { .label-color { color: rgb(221, 25, 29); } .select2-choice.ui-select-match.select2-default { border-color: #e84e40; } } .validation-message { font-size: 0.875em; } .max-width { width: 100%; min-width: 100%; }
注意:这个答案对于Angular 1.2和更早的版本来说是有用的,它没有提供一个简单的机制。
validation启动了更改事件,所以有些事情如编程改变值不会触发它。 但触发更改事件将触发validation。 例如,用jQuery:
$('#formField1, #formField2').trigger('change');