4

値 1、2、または 3 のみを入力できる入力フィールドが必要なので、これらの値と一致しない場合にモデルへのすべての変更を防止するディレクティブを作成しようとしています。
たとえば、値が 1 で、5 に変更しても 1 のままである必要があります。

小さなフィドルhttp://jsfiddle.net/kannix/Q5YKE/をまとめましたが、 $parsers を使用するのはおそらく間違っています。

app.directive('myvalidator', function () {
    return {
        require: 'ngModel',
        link: function (scope, elm, attrs, ctrl) {
            var validValues = [1,2,3];
            ctrl.$parsers.push(function (value) {
                if (validValues.indexOf(value) === -1){
                    //what to do here? should refuse wrong value and leave the old one
                }   
            });
        }
    }   

})
4

4 に答える 4

24

私は最近、このためだけにディレクティブを書きました。着信キーの押下を検証し、有効な場合にのみ許可する regExp オブジェクトを受け取ります。

// forces keystrokes that satisfy the regExp passed
app.directive("regExpRequire", function() {

    var regexp;
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            regexp = eval(attrs.regExpRequire);

            var char;
            elem.on("keypress", function(event) {
                char = String.fromCharCode(event.which)
                if(!regexp.test(elem.val() + char))
                    event.preventDefault();
            })
        }
    }

})

テンプレートの使用法:<input type="text" reg-exp-require="/^[a-zA-Z]$/">

またはあなたの場合:<input type="text" reg-exp-require="/^[1-3]*$/">

于 2013-08-15T02:22:17.090 に答える
6

ng-pattern-restrictディレクティブを使用することをお勧めします。

ライブラリを取得し、次のように入力を装飾するだけです。

<input type="text" pattern="[0-9]+" ng-pattern-restrict />

GitHub: AlphaGit/ng-pattern-restrict

于 2015-12-18T11:11:59.443 に答える
4

いつでもkeypressイベントを聞いて、キャラクターが通過するのを防ぐことができます. こちらがプランカー

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.validValues = ['a','1','2'];
});

app.directive('myValidator', function ($parse) {
    return {
        scope: {
          validValues: '=validValues'
        },
        link: function (scope, elm, attrs) {
          elm.bind('keypress', function(e){
            var char = String.fromCharCode(e.which||e.charCode||e.keyCode), matches = [];
            angular.forEach(scope.validValues, function(value, key){
              if(char === value) matches.push(char);
            }, matches);
            if(matches.length == 0){
              e.preventDefault();
              return false;
            }
          });
        }
    }   
});
于 2013-08-14T21:40:18.063 に答える
2

私は実際に、Ian Haggerty の回答フォームを基にして修正する必要がありました。私が別の方法でテストを開始するまで、彼のコードはうまく機能していました。特に 100 未満の値をテストしようとしましたが、奇妙な結果が得られました。

入力に ​​100 があり、10.0 にするために 10 進数を挿入しようとした場合、Ian の修正はこれを考慮せず、私の正規表現と一致しないと言いました (小数点以下 2 つまで許可していますが)。途中で挿入していたにもかかわらず、テスト中の文字列の最後に押した文字が常に追加されていることがわかりました。

私の変更は、「keypress」で元の値を保存し、次に「keyup」(または必要に応じて「change」) で新しい値のチェックを行うことでした。無効な場合は、元に戻します。

残念ながら、モデルは簡単に更新されますが、少なくとも入力値の途中または最初に文字を入力しても、正規表現と正しく一致させることができます。Angular 1.3 では、おそらく ng-model-options="{debounce:250}" を使用してこれに対抗できます。このモデル変更に依存するコードをべき等にすることは、非常に役立ちます。

usage: <input ... validate-with="/^([\d]{1,2}\.[\d]{1,2}|\.?[\d]{1,2}|100)?$/" />

.directive("validateWith", [function(){
    return {
        restrict: "A",
        link: function($scope, $el, $attrs){
            var regexp = eval($attrs.validateWith);
            var origVal;
            // store the current value as it was before the change was made
            $el.on("keypress", function(e){
                origVal = $el.val();
            });

            // after the change is made, validate the new value
            // if invalid, just change it back to the original
            $el.on("keyup", function(e){
                if(!regexp.test($el.val())){
                    $el.val(origVal);
                }
            });
        }
    }
}]);
于 2014-06-05T20:41:26.217 に答える