プログラムでフォームフィールドをダーティに設定するAngular.js


105

フォームの一部のフィールドをプログラムで値で更新しています$dirty。フィールドの状態をに設定したいと思います。次のようなことをする:

$scope.myForm.username.$dirty = true; 動作していないようです。

$setPristineフィールドの状態をリセットする方法はありますが、方法はありません$setDirtyか?

では、これをどのように行うのでしょうか?

私はこの投稿https://groups.google.com/forum/#!topic/angular/NQKGAFlsln4を見ましたが、$setDirtyメソッドを見つけることができないようです。Angularバージョン1.1.5を使用しています。


いくつかの(デフォルト)値を設定する必要があるだけですか?
チェルニフ2013

3
$ setDirtyメソッドについては、次のドキュメントを参照してください:docs.angularjs.org/api/ng.directive
David Lin

2
フォームレベルのようです。私$setDirtyはフィールドレベルで必要です。
super9 2013

ここで手足を踏み出しますが、これに対する1つの可能な、しかしかなりハッキリした解決策は、angularがそのタイプのフィールドにバインドするために使用するイベントリスナーを見つけ、更新直後にそのリスナーを手動で起動することです。</ uglyHack>
bguiz 2013

クラスをプログラムで変更することを考えていましたが、フォームフィールドの状態は、思っていた
とおりに

回答:


51

AngularJS 1.3.4以降$setDirty()、フィールド(ソース)で使用できます。たとえば、エラーがあり、必須とマークされているフィールドごとに、次の操作を実行できます。

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

87

あなたの場合、$scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue);トリックを行います-それはフォームとフィールドの両方をダーティにし、適切なCSSクラスを追加します。

正直なところ、あなたの質問のリンクからのトピックの新しい投稿でこの解決策を見つけました。それは私にとっては完璧に機能したので、簡単に見つけられるように、これをスタンドアロンの回答としてここに配置します。

編集:

上記のソリューションは、1.3.3までのAngularバージョンに最適です。1.3.4以降、$setDirty()から新しく公開されたAPIメソッドを使用する必要がありますngModel.NgModelController


これは、Angular 1.3.0-beta5と1.3.0の間で変更されたようです。$ 3.0は、$ viewValueが変更されない限り、フィールド$ pristineを保持します。私はしなければなりません$scope.myForm.myField.$pristine = false; $scope.myForm.myField.$setViewValue(...)でした。それは述べて以下の答えのように見えるfield.$setDirty()角度1.3.4で追加されたよりよい解決策になります
ヨハン

4
「1.3.3までは私の日を救ってくれたメモをありがとう。1.3.4からは、新しく公開されたAPIメソッドを使用する必要があります」
Ahmed Mahmoud

ユーザーrmag、および角度2はどうですか?
user5260143 2016年

17

手動で設定する必要があります$dirtytrueして$pristinefalseフィールドに。入力にクラスを表示する場合は、要素にクラスを手動で追加ng-dirtyおよび削除する必要ng-pristineがあります。$setDirty()フォームレベルでを使用して、フォーム自体でこれをすべて実行できますが、フォーム入力はできません。フォーム入力には$setDirty()、今述べたようにありません。

この回答は$setDirty()、入力に追加する必要があるため、将来変更される可能性があります。


3
$ setPristine()は入力フィールドレベルにありますが、1.2.26では$ setDirtyはまだありません:-(
Sebastian

10

NgModelControllerへのアクセス権がある場合(ディレクティブからのみアクセスできます)、次を呼び出すことができます

ngModel.$setViewValue("your new view value");
// or to keep the view value the same and just change it to dirty
ngModel.$setViewValue(ngModel.$viewValue);

ありがとうございました!まさに私が探していたもの。
dreyln 2014年

10

この問題を解決するあなたのためだけのjsFiddleを作成しました。単純に$ dirtyをtrueに設定しますが、$timeout 0DOMが読み込まれた後に実行されます。

ここでそれを見つけてください:JsFiddle

$timeout(function () {
  $scope.form.uName.$dirty = true;
}, 0);

6

これは私のために働いたものです

$scope.form_name.field_name.$setDirty()


5

仕事をするヘルパー関数:

function setDirtyForm(form) {
    angular.forEach(form.$error, function(type) {
        angular.forEach(type, function(field) {
            field.$setDirty();
        });
    });
    return form;
}

残念ながら、残念ながら誤ってこれに投票しました。元に戻すにはどうすればよいですか。..私が編集されて答えずに、これを行うことができない私に言ってそう
SMK

これはうまく機能します。'form。$ error'のチェックとして賛成すると、ユーザーが触れなかったが有効なフィールドを「ダーティ化」しないことが保証されます。
Sam T

ありがとうございました!簡単でシンプルなソリューション。最速ではないかもしれませんが、重いことは何もしないので、imoは問題ではありません。よくできました!
jwanglof 2017年

4

角度2

Angular 2で同じことをしたいと思っている人にとっては、フォームを手に入れることを除いて非常に似ています

<form role="form" [ngFormModel]="myFormModel" (ngSubmit)="onSubmit()" #myForm="ngForm">
<div class="form-group">
    <label for="name">Name</label>
    <input autofocus type="text" ngControl="usename" #name="ngForm" class="form-control" id="name" placeholder="Name">
    <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
        Name is required
    </div>
</div>
</form>
<button type="submit" class="btn btn-primary" (click)="myForm.ngSubmit.emit()">Add</button>

import { Component, } from '@angular/core';
import { FormBuilder, Validators } from '@angular/common';

@Component({
    selector: 'my-example-form',
    templateUrl: 'app/my-example-form.component.html',
    directives: []
})
export class MyFormComponent {
    myFormModel: any;

    constructor(private _formBuilder: FormBuilder) {
        this.myFormModel = this._formBuilder.group({
            'username': ['', Validators.required],
            'password': ['', Validators.required]
        });
    }

    onSubmit() {
        this.myFormModel.markAsDirty();
        for (let control in this.myFormModel.controls) {
            this.myFormModel.controls[control].markAsDirty();
        };

        if (this.myFormModel.dirty && this.myFormModel.valid) {
            // My submit logic
        }
    }
}

3

@rmagの回答に対する小さな追加メモ。ダーティにする空の必須フィールドがある場合は、次のようにします。

$scope.myForm.username.$setViewValue($scope.myForm.username.$viewValue !== undefined 
    ? $scope.myForm.username.$viewValue : '');

これがようやく私を助けた答えです!
カークLiemohn 16

-1

フィールドをダーティとマークしようとしている理由は正確にはわかりませんが、誰かが無効なフォームを送信しようとしたときに検証エラーを表示したかったため、同様の状況にありました。結局、jQueryを使用して.ng-pristineクラスタグを削除.ng-dirtyし、適切なフィールドにクラスタグを追加しました。例えば:

$scope.submit = function() {
    // `formName` is the value of the `name` attribute on your `form` tag
    if (this.formName.$invalid)
    {
        $('.ng-invalid:not("form")').each(function() {
            $(this).removeClass('ng-pristine').addClass('ng-dirty');
        });
        // the form element itself is index zero, so the first input is typically at index 1
        $('.ng-invalid')[1].focus();
    }
}

5
すでにAngularJSを使用していることを考えると、jQueryソリューションはやり過ぎのようです。多くの人々は、例えばAngularJSでjQueryを使用しないことを好みます。
StevenClontz 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.