私はこの方法を使用しています:http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p = previewはぼかしのフィールドのみを検証します。これは正常に機能しますが、ユーザーが[送信]ボタン(実際の送信ではなく、関数へのdata-ng-click呼び出し)をクリックしたときに、それらを検証します(したがって、これらのフィールドのエラーがあれば表示します)。
そのボタンをクリックしたときに、すべてのフィールドで検証を再度トリガーする方法はありますか?
私はこの方法を使用しています:http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p = previewはぼかしのフィールドのみを検証します。これは正常に機能しますが、ユーザーが[送信]ボタン(実際の送信ではなく、関数へのdata-ng-click呼び出し)をクリックしたときに、それらを検証します(したがって、これらのフィールドのエラーがあれば表示します)。
そのボタンをクリックしたときに、すべてのフィールドで検証を再度トリガーする方法はありますか?
回答:
ng-messages
、$ error && $ dirtyの場合にのみ表示されます。
form
...私はすべての入力をループし$setDirty()
てそれらを呼び出す必要がありました。
答えるには少し遅すぎますが、あなたがする必要があるのは、すべてのフォームを強制的に汚すだけです。次のスニペットを見てください。
angular.forEach($scope.myForm.$error.required, function(field) {
field.$setDirty();
});
次に、以下を使用してフォームが有効かどうかを確認できます。
if($scope.myForm.$valid) {
//Do something
}
そして最後に、すべてが良さそうな場合は、ルートを変更することをお勧めします。
$location.path('/somePath');
編集:送信イベントがトリガーされるまで、フォームはスコープに登録されません。ng-submitディレクティブを使用して関数を呼び出し、上記をその関数でラップするだけで、機能するはずです。
ng-submit
ディレクティブをトリガーする例を提供できますか?
ng-submit
は、関数を送信イベントにバインドするだけです。その関数を呼び出すだけではどうでしょうか。
誰かが後でこれに戻ってきた場合に備えて...上記のどれも私にはうまくいきませんでした。そこで、角度フォーム検証の本質を掘り下げて、特定のフィールドでバリデーターを実行するためにそれらが呼び出す関数を見つけました。このプロパティは便利にと呼ばれ$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のAngularドキュメントから:
登録された各バリデーターを実行します(最初に同期バリデーター、次に非同期バリデーター)。有効性が無効に変更された場合、ngModelOptions.allowInvalidがtrueでない限り、モデルは未定義に設定されます。有効性がvalidに変更されると、モデルは最後に使用可能な有効な$ modelValue、つまり最後に解析された値またはスコープから設定された最後の値に設定されます。
したがって、無効なモデル値を使用して何かを行うことを計画している場合(そのように通知するメッセージをポップするなど)、モデルに対してallowInvalid
がに設定さtrue
れていることを確認する必要があり ます。
allowInvalid
ここで読むことができます:github.com/angular/angular.js/issues/10035
Angular-Validatorを使用して、必要なことを実行できます。使い方はばかげています。
そうなる:
$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の作者です
まあ、角度のある方法は、検証を処理させることです-それはすべてのモデル変更で行うので-そしてあなたが望むときだけユーザーに結果を表示します。
この場合、エラーを表示するタイミングを決定するには、フラグを設定する必要があります:http: //plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p = preview
私の知る限り、より高度なフォーム制御を可能にするためにAngularに提出された問題があります。解決されていないので、既存のすべての検証方法を再発明する代わりにこれを使用します。
編集:しかし、あなたが途中で主張するならば、これは提出する前に検証されたあなたの修正されたフィドルです。http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview コントローラーは、ボタンがクリックされたときにイベントをブロードキャストし、ディレクティブは検証マジックを実行します。
1つのアプローチは、すべての属性を強制的にダーティにすることです。各コントローラーでそれを行うことができますが、非常に面倒になります。一般的な解決策がある方がよいでしょう。
私が考えることができる最も簡単な方法は、ディレクティブを使用することでした
これがディレクティブです
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
これは、フォームのエラーメッセージを表示するための私のグローバル関数です。
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);
}
ティラックの答えに基づいて、私はこの解決策を思いつくことができました...
フォームフィールドには、フィールドが無効な場合にのみ検証メッセージが表示され、ユーザーが触れたため、ボタンによってトリガーされるこのコードを使用して、無効なフィールドを表示することができました。
// 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 -->
注:これがハックであることは知っていますが、単純なメカニズムを提供していなかったAngular1.2以前では役に立ちました。
検証は変更イベントで開始されるため、プログラムで値を変更するなどのいくつかのことはそれをトリガーしません。ただし、変更イベントをトリガーすると、検証がトリガーされます。たとえば、jQueryの場合:
$('#formField1, #formField2').trigger('change');
angular way
。
あなたはこれを試すことができます:
// 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%;
}