94

AngularJSでngChangeを使用して、ユーザーが入力に追加した文字を削除するカスタム関数をトリガーしています。

<input type="text" name="inputName" data-ng-change="numbersOnly()"/>

numbersOnly()問題は、入力された文字を削除できるように、トリガーされた入力をターゲットにする必要があることです。私はグーグルで長くそして一生懸命見てきました、そしてこれに関して何も見つけることができませんでした。

私に何ができる?

4

17 に答える 17

106

簡単な方法で、ユースケースで機能する場合はtype="number"を使用します。

<input type="number" ng-model="myText" name="inputName">

別の簡単な方法: ng-patternを使用して、フィールドで許可されるものを制限する正規表現を定義することもできます。フォームに関する「クックブック」ページも参照してください。

ハック?方法、コントローラーの ng-model を $watch します。

<input type="text"  ng-model="myText" name="inputName">

コントローラ:

$scope.$watch('myText', function() {
   // put numbersOnly() logic here, e.g.:
   if ($scope.myText  ... regex to look for ... ) {
      // strip out the non-numbers
   }
})

最善の方法は、ディレクティブで $parser を使用することです。@pkozlowski.opensource によって提供された既に適切な回答を繰り返すつもりはないので、リンクは次のとおりです: https://stackoverflow.com/a/14425022/215945

上記のソリューションはすべて ng-model を使用するため、検索がthis不要になります。

ng-change を使用すると問題が発生します。AngularJSを参照してください- $scope.value のリセットはテンプレートの値を変更しません (ランダムな動作)

于 2013-01-30T23:51:31.020 に答える
66

ng-patternテキスト フィールドでの使用:

<input type="text"  ng-model="myText" name="inputName" ng-pattern="onlyNumbers">

次に、これをコントローラーに含めます

$scope.onlyNumbers = /^\d+$/;
于 2014-02-28T07:23:08.697 に答える
19

提案された解決策はどれもうまくいきませんでした。数時間後、ついに道を見つけました。

これは角度ディレクティブです:

angular.module('app').directive('restrictTo', function() {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var re = RegExp(attrs.restrictTo);
            var exclude = /Backspace|Enter|Tab|Delete|Del|ArrowUp|Up|ArrowDown|Down|ArrowLeft|Left|ArrowRight|Right/;

            element[0].addEventListener('keydown', function(event) {
                if (!exclude.test(event.key) && !re.test(event.key)) {
                    event.preventDefault();
                }
            });
        }
    }
});

入力は次のようになります。

<input type="number" min="0" name="inputName" ng-model="myModel" restrict-to="[0-9]">

正規表現は、値ではなく、押されたキーを評価します

type="number"また、値を変更できないため、入力でも完全に機能するため、キーは表示されず、モデルを台無しにしません。

于 2016-11-17T13:26:38.950 に答える
19

$parser@Mark Rajcok が最良の方法として推奨するソリューションの実装を次に示します。これは基本的に @pkozlowski.opensource のテキスト回答用の優れた $parser ですが、数値のみを許可するように書き直されています。すべての功績は彼にあります。これは、その回答を読んでから自分の回答を書き直す 5 分間を節約するためのものです。

app.directive('numericOnly', function(){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, modelCtrl) {

            modelCtrl.$parsers.push(function (inputValue) {
                var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'') : null;

                if (transformedInput!=inputValue) {
                    modelCtrl.$setViewValue(transformedInput);
                    modelCtrl.$render();
                }

                return transformedInput;
            });
        }
    };
});

そして、次のように使用します。

<input type="text" name="number" ng-model="num_things" numeric-only>

興味深いことに、英数字で囲まれていない限り、スペースはパーサーに到達しないため、必要に応じてそれを行う.trim()必要があります。また、このパーサーは では機能しませ<input type="number">。なんらかの理由で、非数値はパーサーで削除されることはありませんが、入力コントロール自体には含まれます。

于 2014-11-20T21:54:59.133 に答える
6

これは、への入力番号のみを許可するための非常に優れたソリューションinputです。

<input type="text" ng-model="myText" name="inputName" onkeypress='return event.charCode >= 48 && event.charCode <= 57'/>
于 2016-10-11T08:35:53.177 に答える
4

これを行うにはいくつかの方法があります。

使用できますtype="number"

<input type="number" />

別の方法として、正規表現を使用する再利用可能なディレクティブを作成しました。

HTML

<div ng-app="myawesomeapp">
    test: <input restrict-input="^[0-9-]*$" maxlength="20" type="text" class="test" />
</div>

Javascript

;(function(){
    var app = angular.module('myawesomeapp',[])
    .directive('restrictInput', [function(){

        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var ele = element[0];
                var regex = RegExp(attrs.restrictInput);
                var value = ele.value;

                ele.addEventListener('keyup',function(e){
                    if (regex.test(ele.value)){
                        value = ele.value;
                    }else{
                        ele.value = value;
                    }
                });
            }
        };
    }]);    
}());
于 2015-10-29T13:41:07.697 に答える
2

これは、上記の命題が処理しない状況を処理するPlunkerです。
$formatters と $parsers パイプラインを使用し、type="number" を避ける

そして、ここに問題/解決策の説明があります(Plunkerでも利用できます):

/*
 *
 * Limit input text for floating numbers.
 * It does not display characters and can limit the Float value to X numbers of integers and X numbers of decimals.
 * min and max attributes can be added. They can be Integers as well as Floating values.
 *
 * value needed    |    directive
 * ------------------------------------
 * 55              |    max-integer="2"
 * 55.55           |    max-integer="4" decimal="2" (decimals are substracted from total length. Same logic as database NUMBER type)
 *
 *
 * Input type="number" (HTML5)
 *
 * Browser compatibility for input type="number" :
 * Chrome : - if first letter is a String : allows everything
 *          - if first letter is a Integer : allows [0-9] and "." and "e" (exponential)
 * Firefox : allows everything
 * Internet Explorer : allows everything
 *
 * Why you should not use input type="number" :
 * When using input type="number" the $parser pipeline of ngModel controller won't be able to access NaN values.
 * For example : viewValue = '1e'  -> $parsers parameter value = "".
 * This is because undefined values are not allowes by default (which can be changed, but better not do it)
 * This makes it impossible to modify the view and model value; to get the view value, pop last character, apply to the view and return to the model.
 *
 * About the ngModel controller pipelines :
 * view value -> $parsers -> model value
 * model value -> $formatters -> view value
 *
 * About the $parsers pipeline :
 * It is an array of functions executed in ascending order.
 * When used with input type="number" :
 * This array has 2 default functions, one of them transforms the datatype of the value from String to Number.
 * To be able to change the value easier (substring), it is better to have access to a String rather than a Number.
 * To access a String, the custom function added to the $parsers pipeline should be unshifted rather than pushed.
 * Unshift gives the closest access to the view.
 *
 * About the $formatters pipeline :
 * It is executed in descending order
 * When used with input type="number"
 * Default function transforms the value datatype from Number to String.
 * To access a String, push to this pipeline. (push brings the function closest to the view value)
 *
 * The flow :
 * When changing ngModel where the directive stands : (In this case only the view has to be changed. $parsers returns the changed model)
 *     -When the value do not has to be modified :
 *     $parsers -> $render();
 *     -When the value has to be modified :
 *     $parsers(view value) --(does view needs to be changed?) -> $render();
 *       |                                  |
 *       |                     $setViewValue(changedViewValue)
 *       |                                  |
 *       --<-------<---------<--------<------
 *
 * When changing ngModel where the directive does not stand :
 *     - When the value does not has to be modified :
 *       -$formatters(model value)-->-- view value
 *     -When the value has to be changed
 *       -$formatters(model vale)-->--(does the value has to be modified) -- (when loop $parsers loop is finished, return modified value)-->view value
 *                                              |
 *                                  $setViewValue(notChangedValue) giving back the non changed value allows the $parsers handle the 'bad' value
 *                                               |                  and avoids it to think the value did not changed
 *                Changed the model <----(the above $parsers loop occurs)
 *
 */
于 2016-02-05T10:59:54.243 に答える
1
   <input type="text" name="profileChildCount" id="profileChildCount" ng-model="profile.ChildCount" numeric-only maxlength="1" />

数値のみの属性を使用できます。

于 2016-09-27T14:07:33.857 に答える
0

これが古いことは知っていますが、誰かが簡単な解決策を探している場合に備えて、この目的のためにディレクティブを作成しました。使い方はとても簡単です。

ここで確認できます。

于 2015-06-24T01:10:43.363 に答える
0

入力の先頭にある 0 を削除することもできます...まだコメントを作成できないため、上記の Mordred の回答に if ブロックを追加するだけです...

  app.directive('numericOnly', function() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, modelCtrl) {

          modelCtrl.$parsers.push(function (inputValue) {
              var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'') : null;

              if (transformedInput!=inputValue) {
                  modelCtrl.$setViewValue(transformedInput);
                  modelCtrl.$render();
              }
              //clear beginning 0
              if(transformedInput == 0){
                modelCtrl.$setViewValue(null);
                modelCtrl.$render();
              }
              return transformedInput;
          });
      }
    };
  })
于 2016-04-30T21:03:58.363 に答える
0

基本的な HTML

<input type="number" />

基本的なブートストラップ

<input class="form-control" type="number" value="42" id="my-id">
于 2016-09-19T11:08:35.477 に答える