Angularjsの動的ngパターン検証


84

チェックボックスがfalseの場合、ng-requiredディレクティブを使用してテキスト入力の検証を強制するフォームがあります。チェックボックスがtrueの場合、フィールドは非表示になり、ng-requiredはfalseに設定されます。

問題は、入力で指定された検証用の正規表現もあり、ng-patternangularディレクティブを利用していることです。私が直面している問題は、ユーザーが無効な電話番号を入力した場合、その入力を無効にするチェックボックスをオンにすると(したがって、それ以上の検証は必要ありません)、ng-patternに基づいて無効であるため、フォームは送信を許可しません。

ng-change関数を追加して入力モデルをnullに設定することでこの問題を解決しようとしましたが、ng-pattern、したがってフィールドはチェックボックスの初期セットでfalseに設定されたままです。ただし、チェックボックスをオフにして、すべてを最初のフォームの読み込みに戻し、もう一度チェックボックスをオンにすると、フォームは有効になり、送信できるようになります。何が欠けているのかわかりません。これが私がこれまでに持っているng-changeコードです:

    var phoneNumberRegex = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    $scope.phoneNumberPattern = phoneNumberRegex;
    $scope.removeValidation = function() {
        if ($scope.cell._newUser === false) {
            $scope.request._number = '';
            $scope.phoneNumberPattern = /[0-9a-zA-Z]?/;
        } else {
            $scope.phoneNumberPattern = phoneNumberRegex;
        }
    };

回答:


175

これは興味深い問題であり、複雑なAngular検証です。次のフィドルはあなたが望むものを実装します:

http://jsfiddle.net/2G8gA/1/

詳細

rpatternAngularng-requiredng-patternからのコードを組み合わせた新しいディレクティブを作成しましたinput[type=text]。それが行うことはrequired、フィールドの属性を監視し、正規表現で検証するときにそれを考慮に入れることですvalid-pattern。つまり、必須でない場合は、フィールドをとしてマークします。

ノート

  • ほとんどのコードはAngularからのものであり、このニーズに合わせて調整されています。
  • チェックボックスがチェックされている場合、フィールドは必須です。
  • 必須チェックボックスがfalseの場合、フィールドは非表示になりません。
  • デモでは正規表現が簡略化されています(有効なのは3桁です)。

汚れた(しかし小さい)ソリューションは、あなたが新しいディレクティブをしたくない場合は、のようになります。

$scope.phoneNumberPattern = (function() {
    var regexp = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    return {
        test: function(value) {
            if( $scope.requireTel === false ) {
                return true;
            }
            return regexp.test(value);
        }
    };
})();

また、HTMLでは変更は必要ありません。

<input type="text" ng-model="..." ng-required="requireTel"
    ng-pattern="phoneNumberPattern" />

この実際の呼び出しに角度トリック私たちの test()方法を、代わりにRegExp.test()とり、required考慮に。


2
関数の前後の丸括弧が何をするのか知りたいです。それらなしでは機能しません
NeedHack 2014年

5
関数を直接呼び出し、その戻り値を変数に効果的に配置します。Javascriptでは、特定のコンポーネントの実装の詳細で外部スコープを汚染しないようにするために非常に一般的です。たとえば、モジュールパターンを見てください。
Nikos Paraskevopoulos 2014年

6
JSの「ダックタイピング」に基づいてAngularJSでトリックを実行するという汚い解決策は、私が今日見た中で最も素晴らしいコードです。本当に賢い解決策!
フロリアンロッホ

素晴らしいコードに感謝しますが、まだあまり明確ではありません。1)docs.angularjs.org/api/ng/directive/inputによると、「式がRegExpオブジェクトに評価される場合、これは直接使用されます。式が評価される場合文字列に変換すると、RegExpに変換されます」が、phoneNumberPatternは、返されるときにオブジェクトであると思いますか?これはRegxpObjであるはずですか?2)そして、関数(値){}ストアのテストでは、パラメータ「値」はどこから来ていますか?返信に感謝します!
user2499325 2015年

1
1)「式がRegExpに評価される場合」句は、取得するものにtestメソッドがあるかどうかをチェックすることにより、Angularによって実装されます。そのためtest()、基本的にネイティブJSをエミュレートして、独自のカスタムでオブジェクトを提供しますRegExp。2)valueもちろん、実際の妥当性チェックを実行するときにAngularによって渡されます。
Nikos Paraskevopoulos 2015年

25

ニコスの素晴らしい答えから何も奪うことなく、おそらくこれをもっと簡単に行うことができます:

<form name="telForm">
  <input name="cb" type='checkbox' data-ng-modal='requireTel'>
  <input name="tel" type="text" ng-model="..." ng-if='requireTel' ng-pattern="phoneNumberPattern" required/>
  <button type="submit" ng-disabled="telForm.$invalid || telForm.$pristine">Submit</button>
</form>

2番目の入力に注意してくださいng-if。フォームのレンダリングと検証を制御するためにを使用できます。requireTel変数が設定されていない場合、2番目の入力は非表示になるだけでなく、まったくレンダリングされないため、フォームは検証に合格し、ボタンが有効になり、必要なものが得られます。


1
利点は、それは簡単です。欠点は、ng-if式がfalseの場合に削除される入力は、後でng-ifがtrueと評価されると、その中のテキストがすべて削除されることです。それでも、簡単にするために+1します。
ブラッド

追加したかったのですが、このルートに行く場合は、ng-if内のすべて(たとえばdivに配置した場合)が独自のスコープを持つようになることを理解してください。
ブラッド

5

使用パターン:

 ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"

使用した参照ファイル:

 '<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>'

入力の例:

 <input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">

2

 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
<input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">


2

先日、これに出くわしました。

上記よりも簡単に思えますが、スコープの変数にパターンを設定し、ビューのng-patternでそれを参照することです。

「チェックボックスがオフになっている」場合、onChangedコールバックで正規表現の値を/.*/に設定するだけです(チェックを外す場合)。ng-patternは変化を拾い上げ、「OK、あなたの価値は大丈夫です」と言います。フォームが有効になりました。また、フィールドから不良データを削除して、明らかに不良な電話番号がそこにないようにします。

ng-requiredに関する追加の問題があり、同じことをしました。チャームのように働いた。


0

ngModel $ viewValueが、属性値で指定されたAngular式を評価して見つかったRegExpと一致しない場合に、パターン検証エラーキーを設定します。式がRegExpオブジェクトに評価される場合、これは直接使用されます。式が文字列に評価される場合、^文字と$文字でラップした後、正規表現に変換されます。

この質問で最も投票された回答を更新する必要があるようです。試してみると、test機能が適用されず、検証が機能しないためです。

Angularドキュメントの例は私にとってうまく機能します:

組み込みバリデーターの変更

html

<form name="form" class="css-form" novalidate>
  <div>
   Overwritten Email:
   <input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
   <span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
   Model: {{myEmail}}
  </div>
</form>

js

var app = angular.module('form-example-modify-validators', []);

app.directive('overwriteEmail', function() {
    var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;

    return {
        require: 'ngModel',
        restrict: '',
        link: function(scope, elm, attrs, ctrl) {
            // only apply the validator if ngModel is present and Angular has added the email validator
            if (ctrl && ctrl.$validators.email) {

                // this will overwrite the default Angular email validator
                ctrl.$validators.email = function(modelValue) {
                    return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
                };
             }
         }
     };
 });

プランカー


-1

あなたはサイトhttps://regex101.com/を使うことができますをして、国ごとに独自のパターンを構築。

たとえば、ポーランド:

-pattern = xxxxxxxxx OR xxx-xxx-xxx OR xxx xxx xxx 
-regexp ="^\d{9}|^\d{3}-\d{3}-\d{3}|^\d{3}\s\d{3}\s\d{3}"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.