2013-06-05 117 views
67

我正在使用此方法:http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview只驗證模糊上的字段。這工作正常,但我也想驗證它們(並因此顯示這些字段的錯誤,如果有的話),當用戶點擊'提交'按鈕(不是一個真正的提交,而是一個數據ng單擊調用一個函數)觸發驗證角度表單中的所有字段提交

當點擊該按鈕時,是否有某種方法可以在所有字段上再次觸發驗證?

+0

PLUNK中的按鈕在哪裏? – callmekatootie

+0

對不起,我的代碼是基於我的代碼。我做了一個分叉以更加類似於我的情況:http://plnkr.co/edit/VfvCSmjlzpIgUH4go2Jn?p=preview – Maarten

回答

37

什麼工作,我用的是$setSubmitted功能,這在1.3.20版本的角度Docs的出現。

在我想觸發驗證的單擊事件,我做了以下內容:

vm.triggerSubmit = function() { 
    vm.homeForm.$setSubmitted(); 
    ... 
} 

這是所有花了我。根據文檔,它「將表單設置爲提交狀態。」它提到了here

+4

當你使用'ng-messages'並且只在* $ error * && * $ dirty *時才顯示它們,這不起作用。 – JobaDiniz

+0

@JobaDiniz你有沒有試過$ setDirty函數?這也是從我的答案鏈接中提到:https://code.angularjs.org/1.3.20/docs/api/ng/type/form.FormController 希望有幫助! – developering

+2

它不適用於'form' ...我必須遍歷所有輸入,並在它們上調用'$ setDirty()'。 – JobaDiniz

11

那麼,角度的方式就是讓它處理驗證,因爲它在每次模型更改時都會執行 - 並且只在需要時向用戶顯示結果。

在這種情況下,你決定何時顯示錯誤,你只需要設置一個標誌: http://plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p=preview

據我所知,申請到的角度,讓我們有更先進的形式控制問題。由於它沒有解決,我會使用這個,而不是重新創建所有現有的驗證方法。

編輯:但是,如果你堅持你的方式,這裏是你的修改提琴前提交驗證小提琴。 http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview 控制器在單擊按鈕時廣播事件,並且該指令執行驗證魔術。

+0

這在這個例子中起作用,但是如果我,就像我對我的情況(但不是在那個plunkr.sorry!),多於一個指令就像電子郵件一樣。我會不知何故必須將驗證移出指令到單獨的驗證類,然後調用此表單的所有驗證方法,或者我可以以其他方式以所有指令的方式觸發驗證。由於驗證是由模糊觸發的,甚至可能觸發代碼模糊,但這看起來很可怕。 – Maarten

+0

哦,我知道這個問題。不幸的是,它還沒有進入測試階段,我談論的工作流程是該公司的必需工作流程 – Maarten

+0

廣播事件將在每個指令中觸發$ on回調,因爲它們都在控制器的範圍之內。 – Oliver

8

一種方法是強制所有屬性變髒。你可以在每個控制器中做到這一點,但它變得非常混亂。有一個通用的解決方案會更好。

我能想到的最簡單的方法是使用一個指令

  • 將處理表單提交屬性
  • 它通過所有表單域迭代,並標誌着質樸領域髒
  • 它會檢查形式調用提交功能

這裏是指令

之前是有效的
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

0

我喜歡this approach在按鈕的點擊處理驗證。

  1. 無需調用來自控制器東西,

  2. 這一切都與一個指令處理。

github

12

可以使用角驗證做你想做什麼。這很愚蠢,簡單易用。

它會:

  • ,只確認等領域開展$dirtysubmit
  • 防止表單被提交,如果它是無效的
  • 後場
  • 顯示自定義錯誤消息是$dirty或提交表格

See the demo

<form angular-validator 
     angular-validator-submit="myFunction(myBeautifulForm)" 
     name="myBeautifulForm"> 
     <!-- form fields here --> 
    <button type="submit">Submit</button> 
</form> 

如果該字段沒有通過validator那麼用戶將不能夠提交表單。

查看angular-validator use cases and examples瞭解更多信息。

免責聲明:我是角驗證的作者

38

我知道,這是一個稍微有點來不及回答,但所有你需要做的是,強制所有形式的髒。看看下面的代碼片段:

angular.forEach($scope.myForm.$error.required, function(field) { 
    field.$setDirty(); 
}); 

,然後你可以檢查你的形式使用是有效的:

if($scope.myForm.$valid) { 
    //Do something 
} 

最後,我想,你想改變,如果一切看起來路線好:

$location.path('/somePath'); 

編輯:形式不會對範圍註冊本身,直到提交事件觸發。只需使用ng-submit指令來調用一個函數,並將上面的代碼封裝在該函數中,它就可以工作。

+1

您能否提供以編程方式觸發'ng-submit'指令的示例? – chovy

+0

@chovy ng-submit只是將一個函數綁定到提交事件,爲什麼不直接調用該函數呢? –

+0

我有一個指令嵌入到表單中,更新指令外的表單字段....驗證器沒有被應用,除非我點擊並模糊我想驗證的表單字段。 – chovy

0

你可以試試這個:

// The controller 
 

 
$scope.submitForm = function(form){ 
 
    \t \t //Force the field validation 
 
    \t \t angular.forEach(form, function(obj){ 
 
    \t \t \t if(angular.isObject(obj) && angular.isDefined(obj.$setDirty)) 
 
    \t \t \t { 
 
    \t \t \t \t obj.$setDirty(); 
 
    \t \t \t } 
 
    \t \t }) 
 
     
 
     if (form.$valid){ 
 
\t \t 
 
\t \t \t $scope.myResource.$save(function(data){ 
 
\t \t  \t //.... 
 
\t \t \t }); 
 
\t \t } 
 
}
<!-- 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>

2

基於Thilak的答案,我能想出這種解決方案

因爲我的表單字段只顯示驗證消息如果一個字段是無效的,並且被用戶觸及,我可以使用這個由一個按鈕觸發的代碼來顯示我的無效字段:

// 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 -->

-1

注:這個答案是一個黑客位,這是對角1.2有用的早些時候,沒有提供一個簡單的機制。

驗證啓動更改事件,所以有些事情如編程改變值不會觸發它。但觸發更改事件將觸發驗證。例如,使用jQuery:

$('#formField1, #formField2').trigger('change'); 
+0

這種方法很簡單。另外它的優點是可以在Angular的舊版本(所有版本)上運行。 –

+3

不是'角度的方式'。 – Dementic

2

這是我的全局函數,用於顯示錶單錯誤消息。

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); 
} 
+1

這不回答問題。 – Dementic

+0

我改變了我的答案。請立即檢查 – Namal

13

,以防有人回來稍後......以上爲我工作無。所以我深入瞭解了角度表單驗證的內容,並發現他們調用的函數在給定字段上執行驗證器。該物業便利地被稱爲$validate

如果您有指定的表單myForm,則可以通過編程方式調用myForm.my_field.$validate()來執行字段驗證。例如:

<div ng-form name="myForm"> 
    <input required name="my_field" type="text" ng-blur="myForm.my_field.$validate()"> 
</div> 

請注意,致電$validate對您的模型有影響。從ngModelCtrl的角度文檔。$ validate:

運行每個註冊的驗證器(第一個同步驗證器,然後是異步驗證器)。如果有效性更改爲無效,則模型將設置爲undefined,除非ngModelOptions.allowInvalid爲true。如果有效性更改爲有效,它會將模型設置爲最後一個可用的有效$ modelValue,即最後解析的值或從範圍中設置的最後一個值。

所以,如果你打算做一些與無效的模型值(如彈出一條消息,告知他們如此),那麼你需要確保allowInvalid設置爲true爲你的模型。

0

我做了一些以下的工作。

<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%; 
    } 
相關問題