在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$dirtysubmit的字段
  • 如果无效,请阻止提交表单
  • 显示自定义错误消息后领域$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的方法 。

  1. 没有必要从控制器调用任何东西,

  2. 它都是用指令处理的。

在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');