AngularJS フォーム送信時の検証: $dirty、$valid、$invalid

⚡ スマートサマリー

AngularJSにおけるフォーム検証は、フォームに入力されたデータがサーバーに送信される前に、そのデータが正確かつ完全であることを確認します。ここでは、HTML5の属性、スコーププロパティ、自動検証モジュールなど、4つのアプローチについて解説します。

  • 🧩 HTML5属性: 必須属性と、メールアドレス、パスワード、数値の入力タイプは、スクリプトを使わずにブラウザネイティブのチェックを提供します。
  • 🔍 州の所有物: AngularJS は、名前付きフォーム内のすべての名前付きコントロールに対して、$dirty、$pristine、$valid、および $invalid を公開します。
  • 🏷️ 命名要件: フォームと各コントロールの両方に名前属性が必要です。検証状態は formName.controlName として扱われるためです。
  • 🚫 ネイティブポップアップを抑制する: フォームに novalidate を追加すると、ブラウザによる送信の傍受が防止され、AngularJS が処理できるようになります。
  • 💬 メッセージ表示: ngMessagesモジュールは、積み重ねられたng-showディレクティブを置き換え、優先度順に一度に1つのエラーを表示します。
  • ⚙️ 自動検証: jcs-autoValidateモジュールは、カスタムマークアップなしで、すべてのコントロールに対してエラーメッセージを生成します。
  • 🔘 提出物に関するフィードバック: Laddaのボタンは、送信処理中にスピナーを表示し、ユーザーに処理の進捗状況を知らせます。

AngularJS でのフォーム検証

フォームの検証 AngularJSにおける検証とは、フォームに入力されたデータが正確かつ完全であるかどうかを確認するプロセスです。ユーザーがフォームを送信すると、まず検証が行われ、その後詳細がサーバーに送信されます。この検証プロセスにより、入力フィールドが可能な限り正しく入力されていることが保証されます。

実際の例を挙げると、完全なアクセス権を付与する前に登録フォームへの記入が必要なサイトを想定してみましょう。登録ページには、ユーザー名、パスワード、メールアドレスなどの入力欄があります。

例えば、メールアドレスは常に次の形式である必要があります。 ユーザー名@サイト.ドメインユーザー名のみを入力した場合、検証は失敗します。検証では、詳細情報がサーバーに送信されてさらに処理される前に、これらの基本的なチェックが実行されます。

⚠️ バージョンに関する注記: AngularJS(1.xブランチ)は2021年12月31日にサポートが終了し、セキュリティパッチは提供されなくなりました。以下の手法はレガシーアプリケーションには引き続き有効ですが、最新のAngularではテンプレート駆動型またはリアクティブフォームを使用して同様の処理が可能です。

HTML5を使用したフォーム検証

フォーム検証とは、Webフォームに入力された情報をサーバーに送信する前に、事前に検証するプロセスです。クライアント側で検証を行う方が、往復通信後にフォームを再度表示するよりもはるかにオーバーヘッドが少ないため、望ましいと言えます。

以下の例は、ユーザーがユーザー名、パスワード、メールアドレス、年齢を入力するシンプルな登録フォームを示しています。このフォームには、入力された情報が正しく入力されていることを確認するための検証機能が備わっています。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <link rel="stylesheet" href="lib/bootstrap.css">
    <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script>
</head>
<body ng-app="sampleApp">
<h1>Guru99 Global Event</h1>

<form>
    Enter your user name:
    <input type="text" name="name" required><br><br>

    Enter your password:
    <input type="password" name="password"><br><br>

    Enter your email:
    <input type="email" name="email"><br><br>

    Enter your age:
    <input type="number" name="age"><br><br>

    <input type="submit" value="Submit">
</form>
</body>
</html>

⚠️ このページに掲載されているすべての項目に修正が適用されました。 オリジナルは宣言した chrset="UTF 8"これは有効な属性でも有効なエンコーディングでもなく、AngularJSを3回ロードしました。 angular-route.js まず、ルートモジュールがロードされていないフレームワークに登録されるため、エラーが発生します。 angular.min.js (NAIST) と angular.js同じ図書館を2回利用した。 bootstrap.css スルー <script> タグのため、スタイルは適用されませんでした。各リストは、バージョン 1.8.3 のライブラリを 1 つ読み込み、スタイルシートを正しくリンクします。レイアウトのパディングは、繰り返しから構築されます。 &nbsp; エンティティが削除されました。

Code 説明

  1. テキスト入力タイプの場合、 required この属性は、フォーム送信時にテキストボックスが空であってはならないことを意味します。
  2. 次の入力タイプはパスワードです。タイプがパスワードとして指定されているため、フィールドに入力されたテキストはマスクされます。
  3. 入力タイプがメールとして指定されているため、ボックス内のテキストはパターンに一致する必要があります。 名前@サイト.ドメイン.
  4. 入力タイプが数値として指定されている場合、キーボードから入力された文字は入力欄で受け付けられません。

出力

検証の動作を確認するには、何も入力せずに「送信」をクリックしてください。

入力が必要な項目があることを知らせるポップアップが表示されるため、必須項目としてマークされたコントロールが空欄のままだと送信がブロックされます。

パスワード入力欄に値を入力すると、文字が「*」記号で隠されます。

不正なメールアドレスを入力して「送信」をクリックすると、「@」記号の入力を求めるポップアップが表示されます。また、年齢入力欄には数字しか入力できないため、入力した文字は表示されません。

ブラウザのポップアップは簡単に設定できますが、文言やスタイルを変更することはできません。そこでAngularJSの検証プロパティが役立ちます。

$dirty、$valid、$invalid、$pristine を使用したフォーム検証

AngularJS 検証のために独自のプロパティを提供します。以下のプロパティは、名前付きコントロールすべてに公開されています。

  • $ダーティ – ユーザーがコントロールを操作しました
  • $有効 – フィールドの内容は有効です
  • $無効 – フィールドの内容が無効です
  • $原始的な – ユーザーはまだコントロールを操作していません

以下に、AngularJSの検証を実行する手順を示します。

ステップ1) novalidate フォームを宣言する際に使用するプロパティです。これにより、ブラウザに対して検証処理がAngularJSによって行われることが伝えられます。

ステップ2) フォームには必ず名前が付けられていることを確認してください。その名前は検証状態に到達するために使用されます。

ステップ3) 各コントロールにも name 属性についても同様です。名前のないコントロールはフォームに登録されません。

ステップ4) NG-ショー $dirty、$invalid、$valid プロパティをチェックする指示。

以下の例では、ユーザーがトピック名を入力するテキストフィールドが1つあります。このフィールドが空白のままの場合、検証エラーが発生し、メッセージが表示されます。

<form ng-app="DemoApp" ng-controller="DemoController"
      name="myForm" novalidate>
    <p>Topic Name:<br>
        <input type="text" name="user" ng-model="user" required>

        <span style="color:red"
              ng-show="myForm.user.$dirty && myForm.user.$invalid">
            <span ng-show="myForm.user.$error.required">Username is required</span>
        </span>
    </p>
    <p>
        <input type="submit" ng-disabled="myForm.$invalid">
    </p>
</form>

<script>
    var app = angular.module("DemoApp", []);

    app.controller("DemoController", function($scope) {
        // Seed the textbox so the form starts in a valid state
        $scope.user = "AngularJS";
    });
</script>

⚠️ 2つの論理エラーを修正しました。 元のボタンは無効にしました ng-disabled="myForm.user.$dirty && myForm.user.$invalid"。 なぜなら $dirty ユーザーがフィールドをタッチするまではfalseのままで、ボタンはそのままです。 使用可能 手つかずの空の用紙に、まさにそれが阻止しようとしていたケースが記入されている。 myForm.$invalid 両方をカバーしています。オリジナルはデフォルト値もラップしていました。 $scope.Display = function () { $scope.user = 'Angular'; }関数が呼び出されなかったため、テキストボックスには「AngularJS」と表示されているにもかかわらず、テキストボックスは空のまま開きました。現在は、周囲のテキストが引用する値を使用して、直接代入が行われています。

Code 説明

  1. フォームには「myForm」という名前が付けられています。これは、フォームの検証コントロールにアクセスするために必要です。
  2. その novalidate このプロパティはブラウザによる検証を停止するため、代わりにAngularJSが検証を行うことができます。
  3. ng-showディレクティブは、「$dirty」と「$invalid」プロパティをチェックします。テキストボックスが変更されている場合は、$dirtyがtrueになります。値が空の場合は、$invalidがtrueになります。両方がtrueの場合、赤いテキストが表示されたspan要素が表示されます。
  4. ネストされたチェックは「$error.required」プロパティを読み取ります。これは、必須コントロールに値がない場合は常にtrueとなり、「ユーザー名は必須です」と表示されます。
  5. 送信ボタンは無効になっています ng-disabled フォーム全体が無効な場合。
  6. コントローラーは初期テキストボックスの値を「AngularJS」に設定するため、フォームは有効な状態で開き、テキストが削除される際の検証状況を容易に確認できます。

出力

フォームが最初に表示されたとき、テキストボックスには「AngularJS」と表示され、送信ボタンが有効になっています。テキストが削除されるとすぐにエラーメッセージが表示され、ボタンが無効になります。

上記のスクリーンショットには、次の2つのことが示されています。

  • 送信ボタンは無効になっています
  • トピックテキストボックスにトピック名が入力されていないため、「ユーザー名が必要です」というエラーメッセージが表示されます。

ngMessagesを使用して検証エラーを表示する方法

上記のパターンは機能しますが、拡張性がありません。4 つの制約を持つフィールドには、4 つのネストされた ng-show スパンがあり、複数のスパンが同時に故障すると、すべてのメッセージがまとめて表示されます。 ngMessages AngularJSチームが別途提供しているモジュールは、両方の問題を解決します。メッセージが書き込まれた順序で、一度に1つのメッセージを表示します。

モジュールをロードし、依存関係として追加します。

<script src="https://code.angularjs.org/1.8.3/angular-messages.js"></script>
<script>
    angular.module("DemoApp", ["ngMessages"]);
</script>

すると、マークアップは条件の羅列ではなく、ルールのリストとして読み取れるようになる。

<input type="text" name="user" ng-model="user"
       required ng-minlength="4" ng-maxlength="20">

<div style="color:red" ng-messages="myForm.user.$error"
     ng-if="myForm.user.$dirty">
    <div ng-message="required">A topic name is required</div>
    <div ng-message="minlength">Use at least 4 characters</div>
    <div ng-message="maxlength">Use no more than 20 characters</div>
</div>

3つの詳細が、これが実際にうまく機能する理由です。 ng-messages 属性はコントロールの $error ブール値ではなくオブジェクトなので、条件を繰り返す必要はありません。最初の一致のみ ng-message つまり、空白のフィールドは長さに関するエラーメッセージを表示するのではなく、必須項目であると報告します。 ng-messages-multiple すべての失敗を本当にリストアップする必要がある場合は、その動作を逆転させる。

ラップping ブロック ng-if="myForm.user.$dirty" ユーザーが実際に何かを入力するまでフォームを非表示にします。 $touched$dirty フォーカスがフィールドから外れるまでメッセージの表示をさらに遅らせるため、長い登録フォームでは通常、より親切な選択肢となります。

注意点: ngMessages 別ファイルとして提供されるため、スクリプトタグやモジュールの依存関係を忘れると、ブロックは何もレンダリングされず、それを説明するコンソールエラーも表示されません。

手書きでメッセージを作成するのは正確ではあるものの、単調な作業です。次のセクションでは、メッセージを自動生成するモジュールについて説明します。

AngularJS Auto Validate を使用したフォーム検証

AngularJS は、検証やエラーメッセージのためのカスタムコードを記述することなく、フォーム上のすべてのコントロールを自動的に検証できます。これは、「jcs-autoValidate」というコミュニティモジュールを組み込むことで実現されます。

このモジュールを導入すれば、検証の実行やメッセージの表示に特別なコードは必要ありません。すべてjcs-autoValidate内部で処理されます。

以下の例は、必須入力欄が1つだけあるシンプルなフォームです。入力欄に何も入力されていない場合は、エラーメッセージが表示されます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <link rel="stylesheet" href="lib/bootstrap.css">
    <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script>
    <script src="lib/jcs-auto-validate.min.js"></script>
</head>
<body>
<h1>Guru99 Event</h1>

<div ng-app="DemoApp">
    <form name="myForm" novalidate>
        <div class="form-group">
            <label for="user">Topic Name:</label>
            <input class="form-control" type="text"
                   id="user" name="user" ng-model="user" required>
        </div>
        <div class="form-group">
            <input type="submit">
        </div>
    </form>
</div>

<script>
    var app = angular.module('DemoApp', ['jcs-autoValidate']);
</script>
</body>
</html>

⚠️訂正: オリジナルではコントロールを識別し、 id="user" jcs-autoValidate はフォームを介してコントロールにアクセスするため、 name 属性は必須であり、それがないとメッセージは表示されませんでした。また、元のコードでは 2 つの異なる AngularJS バージョン 1.6.4 がロードされていました。 Google CDNは1.6.9と並行して使用され、リンクされたことはありません。 Bootstrap 例がそれに依存しているとしても form-group (NAIST) と form-control エラーテキストの位置を指定するためのクラス。

💡注: jcs-autoValidate はコミュニティ プロジェクトであり、現在は積極的にメンテナンスされていません。既存の AngularJS アプリケーションでは引き続き使用できますが、組み込みの ngMessages 先に示してきたアプローチは、新しいことに取り組む際にはより安全な選択肢である。

Code 説明

  1. 自動検証機能をすべて含む「jcs-auto-validate.js」スクリプトが同梱されています。
  2. 各コントロールとその周囲のdiv要素は「form-group」クラス内に配置され、モジュールはそのクラス内にメッセージを挿入します。
  3. コントロールにはIDと name, Bootstrap を供給します form-control スタイリング。
  4. 「jcs-autoValidate」モジュールは、AngularJSモジュールの依存関係としてリストされています。

出力

デフォルトでは、フォームは記述されたとおりに表示されます。

空のフォームを送信すると、「このフィールドは必須です」というメッセージが表示されます。このメッセージはjcs-autoValidateによって完全に生成されます。フォームの検証が完了すると、残る問題は、送信中にユーザーに表示される内容です。

Ladda ボタンによるユーザー フィードバック

「Ladda」ボタンは、 Javaスクリプト ボタンが押されたときに視覚的な効果を与えるもの。

ボタンに「ladda」属性が付与され、押されると、回転エフェクトが表示されます。追加の視覚効果のために、さまざまなデータスタイルが利用可能です。

以下の例は、送信ボタンを備えたシンプルなフォームを示しています。ボタンが押されると、回転エフェクトが表示されます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <link rel="stylesheet" href="lib/bootstrap.css">
    <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script>
    <script src="lib/angular-ladda.min.js"></script>
</head>
<body>
<h1>Guru99 Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
    <form name="myForm" novalidate ng-submit="submit()">
        <button class="btn btn-primary" type="submit"
                ladda="submitting" name="sbutton"
                data-style="expand-right">Submit</button>
    </form>
</div>

<script>
    var app = angular.module('DemoApp', ['angular-ladda']);

    app.controller('DemoController', function($scope) {
        $scope.submitting = false;

        $scope.submit = function() {
            $scope.submitting = true;
        };
    });
</script>
</body>
</html>

⚠️訂正: オリジナルがロードされました angular-ladda.js (NAIST) と angular-ladda.min.js 一緒に登録すると、同じモジュールが2回登録され、また2つのAngularJSバージョンが取り込まれます。 jcs-autoValidate この例では使用されない依存関係として扱われます。ここでは各ライブラリのコピーが1つずつ読み込まれます。

Code 説明

  1. NG-送信このディレクティブは「submit」という名前の関数を呼び出し、ボタンのladda属性を変更します。
  2. ladda属性はLaddaフレームワークに属し、スピン効果を追加するものです。その値は submitting 変数に保存します.
  3. data-styleプロパティは、異なる視覚効果を選択するLaddaの別の属性です。
  4. フレームワークを動作させるには、「angular-ladda」モジュールをAngularJSアプリケーションに追加する必要があります。
  5. その submitting 変数がfalseに初期化されるため、ボタンは回転効果なしで起動します。
  6. 送信関数は submitting をtrueに設定すると、効果が適用されます。実際のアプリケーションでは、サーバーからの応答があるとfalseにリセットされます。そうしないと、ボタンが永遠に回転し続けます。

出力

フォームが最初に表示されたとき、送信ボタンは通常の形式で表示されます。

ボタンが押されると、 submitting 変数がtrueに設定されます。その値がボタンの「ladda」属性に渡され、回転効果が発生します。

よくあるご質問

$dirty は値が変更されると true になります。$touched はフィールドがフォーカスを失うと true になります。$touched を使用すると、ユーザーが移動するまでエラーを遅延させることができ、より穏やかな印象を与えます。ping.

ng-pattern ディレクティブに正規表現を追加します。例えば、ng-pattern=”/^[0-9]{6}$/”のように記述します。すると、エラーが $error.pattern として表示され、ngMessages は組み込みの制約と同様にこれを報告できます。

はい。AIツールはマークアップを読み取り、一致するrequired、ng-pattern、ngMessagesブロックを生成します。生成されたメールアドレスや電話番号のパターンは有効な入力を拒否することが多いため、正規表現は必ず確認してください。

AIアシスタントは、よくある3つの原因を迅速にチェックします。フォームまたはコントロールにname属性が欠落している、ng-modelが欠落している、novalidateが省略されているためブラウザが最初に送信を傍受する、といった原因です。

いいえ。確かにユーザーエクスペリエンスは向上し、通信回数も削減されますが、開発者ツールを使えば誰でも回避できてしまいます。ブラウザで適用されるルールはすべて、サーバー側でも再度適用する必要があります。