숫자 만 허용하도록 입력을 제한하려면 어떻게합니까?


92

AngularJS에서 ngChange를 사용하여 사용자가 입력에 추가하는 모든 문자를 제거하는 사용자 지정 함수를 트리거합니다.

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

문제는 입력 numbersOnly()된 문자를 제거 할 수 있도록 트리거 된 입력을 대상으로해야 한다는 것입니다. 나는 Google에서 길고 열심히 보았고 이것에 대해 아무것도 찾을 수 없었습니다.

어떡해?


이것은 또한 문자를 입력 할 수없는 좋은 솔루션입니다.
Himanshu Bhandari

답변:


104

쉬운 방법 , 사용 유형 = "숫자" 가 사용 사례에 대해 작동하는 경우 :

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

또 다른 쉬운 방법 : ng-pattern 을 사용하여 필드에서 허용되는 항목을 제한하는 정규식을 정의 할 수도 있습니다. 또한 참조 양식에 대한 "요리 책"페이지를 .

해 키시? 방법 , $ watch the ng-model in your controller :

<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 재설정은 템플릿의 값을 변경하지 않습니다 (무작위 동작).


지시문을 작성했습니다! 최선의 방법을 포함 해 주셔서 감사합니다. 약간의 조사를했지만 많은 것을 배웠습니다!
Chris Bier

1
특히 권장되는 "가장 좋은"방법 (지시문의 $ parser)과 비교하여 먼저 나열된 "쉬운"방법 (type = "number")으로 단점을 확장 할 수있는 사람이 있습니까?
Matt Welch 2014 년

2
@MattWelch, 늦은 답변이지만 단점은 브라우저 지원입니다. 또한 적어도 Chrome에서는 type=number바람직하지 않을 수있는 스피너가 자동으로 표시됩니다. css를 통해 스피너를 숨길 수 있지만 모든 브라우저에서 작동하지 않을 수도 있습니다.
Rosdi Kasim

4
"쉬운"(type = "number") 접근 방식에서 문제가 될 수있는 두 가지 사항은 1입니다. 2. 삼성 모바일 장치에서는 type = "number"필드에 음수를 입력 할 수 없습니다 (키보드에는 마이너스 키만 있음)
Aides

쉬운 방법 ... firefox는 문자를 숫자 전용 필드에 입력 할 수 있도록합니다. 모델을 업데이트하지는 않지만 문자를 표시합니다
DRaehal

66

사용하여 ng-pattern텍스트 필드에 :

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

그런 다음 컨트롤러에 포함

$scope.onlyNumbers = /^\d+$/;

이것은 내가 Marks 답변을 기반으로 한 결과입니다.하지만 예제에 감사드립니다! 나는 그것이 누군가를 도울 것이라고 확신합니다!
Chris Bier 2014

2
이것은 거의 완벽하게 작동하지만 여전히 'e'를 입력 할 수 있습니다.
쿠키

type = "number"와 길이를 제한하는 데 어려움을 겪고 있다면 정말 도움이됩니다. 해결책은이 ng-pattern을 사용하고 type = "text"로 되 돌리는 것입니다. 매우 깔끔한 솔루션이며 ng-change 또는 ng-keypress에 대한 코드 검사 부하를 제거합니다. 이 솔루션은 'e'입력을 허용하지 않았으므로 다른 문제라고 가정합니다.
PeterS

1
숫자 입력이 허용되지 않는지 여부에 대해 브라우저에 따라 다릅니다. Chrome에서는 단순히 <input type = 'number'/>를 사용하는 것으로 충분하며 숫자 입력을 허용하지 않습니다. 반면에 동일한 Html을 사용하는 Firefox는 입력을 허용하지만 값이 숫자가 아닌 경우 잘못된 입력 플래그를 트리거합니다. 모든 브라우저에서 Chrome 동작을 얻을 수있는 간단한 방법을 찾고 있습니다.
steve

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"값을 변경하는 것을 방지하기 때문에 입력과 완벽하게 작동 하므로 키가 표시되지 않고 모델이 엉망이되지 않습니다.


네거티브를 허용하려면restrict-to="[0-9\-]"
Noumenon

18

다음은 $parser@Mark Rajcok이 최상의 방법으로 권장 하는 솔루션의 구현입니다 . 본질적으로 @ pkozlowski.opensource의 텍스트 답변에 대한 훌륭한 $ 파서 이지만 숫자 만 허용하도록 다시 작성되었습니다. 모든 신용은 그에게 돌아갑니다. 이것은 그 답을 읽고 자신의 답을 다시 쓰는 데 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"> . 어떤 이유로, 숫자가 아닌 사람 제거 될 파서에 도달하지 않지만 입력 컨트롤 자체로 만듭니다.


이것을 구현할 때 입력 모델이 값없이 초기화되면 JS 오류가 발생했습니다. 이 변경을 통해 다음과 같은 문제가 해결되었습니다. var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'') : null;
Alkie

감사합니다 @Alkie. 나는 그 변경 사항을 지시문에 추가했습니다.
Mordred 2015 년

1
당신은 설정해야 ng-trim할 수 false있는지 공간 파서에 도달 할 수 있습니다.
Ilya

완벽하게 만들려면 modelCtrl.$commitViewValue();$ setViewValue (clean); 사이 에 추가해야합니다 . 그리고 $ render ();
ingaham

1
감사합니다! 이것은 굉장합니다! 그것은 많은 도움이
iulial

4

이를 수행하는 몇 가지 방법이 있습니다.

다음을 사용할 수 있습니다 type="number".

<input type="number" />

또는 정규식을 사용하는 재사용 가능한 지시문 을 만들었습니다 .

HTML

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

자바 스크립트

;(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;
                    }
                });
            }
        };
    }]);    
}());

use, $ (element) .on ( 'input', function () {// 논리}); 이렇게하면 원하지 않는 값을 입력하는 것도 방지됩니다
Vishal

4

다음은 숫자 입력 만 허용하는 꽤 좋은 솔루션입니다 input.

<input type="text" ng-model="myText" name="inputName" onkeypress='return event.charCode >= 48 && event.charCode <= 57'/>

이 날 삭제 또는 백 스페이스 키를 누릅니다 수 없습니다
Ravistm

삭제 및 백 스페이스는 작동합니다. Firefox 76.0.1에서 테스트
iamjoshua

3

위의 모든 솔루션은 상당히 큽니다. 저는 이것에 대해 2 센트를주고 싶었습니다.

입력 한 값이 숫자인지 아닌지 확인하고 비어 있지 않은지 확인하는 것뿐입니다.

다음은 html입니다.

<input type="text" ng-keypress="CheckNumber()"/>

다음은 JS입니다.

$scope.CheckKey = function () {
    if (isNaN(event.key) || event.key === ' ' || event.key === '') {
        event.returnValue = '';
    }
};

아주 간단합니다.

나는 이것이 Paste tho에서 작동하지 않을 것이라고 믿습니다.

붙여 넣기의 경우 onChange 이벤트를 사용하고 전체 문자열을 구문 분석해야한다고 생각합니다. 이것은 타이핑에만 해당됩니다.

붙여 넣기 업데이트 :이 JS 함수를 추가하십시오.

$scope.CheckPaste = function () {
    var paste = event.clipboardData.getData('text');

    if (isNaN(paste)) {
        event.preventDefault();
        return false;
    }
};

그리고 html 입력은 트리거를 추가합니다.

<input type="text" ng-paste="CheckPaste()"/>

이 정보가 도움이되기를 바랍니다.


2

다음은 처리하지 않는 제안 위의 상황을 처리 하는 Plunker 입니다.
$ formatters 및 $ parsers 파이프 라인을 사용하고 type = "number"를 피함으로써

다음은 문제 / 해결 방법에 대한 설명입니다 (Punker에서도 사용 가능).

/*
 *
 * 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)
 *
 */

1
   <input type="text" name="profileChildCount" id="profileChildCount" ng-model="profile.ChildCount" numeric-only maxlength="1" />

숫자 전용 속성을 사용할 수 있습니다.


1

소수

directive('decimal', function() {
                return {
                    require: 'ngModel',
                    restrict: 'A',
                    link: function(scope, element, attr, ctrl) {
                        function inputValue(val) {
                            if (val) {
                                var digits = val.replace(/[^0-9.]/g, '');

                                if (digits.split('.').length > 2) {
                                    digits = digits.substring(0, digits.length - 1);
                                }

                                if (digits !== val) {
                                    ctrl.$setViewValue(digits);
                                    ctrl.$render();
                                }
                                return parseFloat(digits);
                            }
                            return "";
                        }
                        ctrl.$parsers.push(inputValue);
                    }
                };
            });

숫자

directive('entero', function() {
            return {
                require: 'ngModel',
                restrict: 'A',
                link: function(scope, element, attr, ctrl) {
                    function inputValue(val) {
                        if (val) {
                            var value = val + ''; //convert to string
                            var digits = value.replace(/[^0-9]/g, '');

                            if (digits !== value) {
                                ctrl.$setViewValue(digits);
                                ctrl.$render();
                            }
                            return parseInt(digits);
                        }
                        return "";
                    }
                    ctrl.$parsers.push(inputValue);
                }
            };
        });

숫자 확인을위한 각도 지시문


0

나는 이것이 오래되었다는 것을 알고 있지만 누구나 쉬운 해결책을 찾고있는 경우를 대비하여이 목적을위한 지시문을 만들었습니다. 사용하기 매우 간단합니다.

여기에서 확인할 수 있습니다 .


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;
          });
      }
    };
  })

0

이 시도,

<input ng-keypress="validation($event)">

 function validation(event) {
    var theEvent = event || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode(key);
    var regex = /[0-9]|\./;
    if (!regex.test(key)) {
        theEvent.returnValue = false;
        if (theEvent.preventDefault) theEvent.preventDefault();
    }

}

0

솔루션 : 앱의 모든 입력, 숫자, 텍스트 또는 기타 항목에 대한 지시문을 작성하여 값을 입력하고 이벤트를 변경할 수 있습니다. 각도 6 만들기

 import { Directive, ElementRef, HostListener, Input } from '@angular/core';

 @Directive({
// tslint:disable-next-line:directive-selector
selector: 'input[inputType]'
})
  export class InputTypeDirective {
 constructor(private _el: ElementRef) {}

 @Input() inputType: string;
 // tipos: number, letter, cuit, tel

@HostListener('input', ['$event']) onInputChange(event) {
if (!event.data) {
  return;
}

switch (this.inputType) {
  case 'number': {
    const initalValue = this._el.nativeElement.value;
    this._el.nativeElement.value = initalValue.replace(/[^0-9]*/g, '');
    if (initalValue !== this._el.nativeElement.value) {
      event.stopPropagation();
    }
     break;
          }
       case 'text': {
        const result = event.data.match(/[^a-zA-Z Ññ]*/g);
        if (result[0] !== '') {
           const initalValue = this._el.nativeElement.value;
           this._el.nativeElement.value = initalValue.replace(
          /[^a-zA-Z Ññ]*/g,
           ''
         );
           event.stopPropagation();
        }
        break;
    }
        case 'tel':
          case 'cuit': {
         const initalValue = this._el.nativeElement.value;
      this._el.nativeElement.value = initalValue.replace(/[^0-9-]*/g, '');
       if (initalValue !== this._el.nativeElement.value) {
         event.stopPropagation();
       }
     }
   }
  }
   }

HTML

     <input matInput inputType="number" [formControlName]="field.name" [maxlength]="field.length" [placeholder]="field.label | translate"  type="text" class="filter-input">

-1

입력을 수락하고 즉시 형식을 변경하기 위해 위 코드의 수정 된 지시문을 작성했습니다.

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

           element.bind('keyup', function (inputValue, e) {
             var strinput = modelCtrl.$$rawModelValue;
             //filter user input
             var transformedInput = strinput ? strinput.replace(/[^,\d.-]/g,'') : null;
             //remove trailing 0
             if(transformedInput.charAt(0) <= '0'){
               transformedInput = null;
               modelCtrl.$setViewValue(transformedInput);
               modelCtrl.$render();
             }else{
               var decimalSplit = transformedInput.split(".")
               var intPart = decimalSplit[0];
               var decPart = decimalSplit[1];
               //remove previously formated number
               intPart = intPart.replace(/,/g, "");
               //split whole number into array of 3 digits
               if(intPart.length > 3){
                 var intDiv = Math.floor(intPart.length / 3);
                 var strfraction = [];
                 var i = intDiv,
                     j = 3;

                 while(intDiv > 0){
                   strfraction[intDiv] = intPart.slice(intPart.length-j,intPart.length - (j - 3));
                   j=j+3;
                   intDiv--;
                 }
                 var k = j-3;
                 if((intPart.length-k) > 0){
                   strfraction[0] = intPart.slice(0,intPart.length-k);
                 }
               }
               //join arrays
               if(strfraction == undefined){ return;}
                 var currencyformat = strfraction.join(',');
                 //check for leading comma
                 if(currencyformat.charAt(0)==','){
                   currencyformat = currencyformat.slice(1);
                 }

                 if(decPart ==  undefined){
                   modelCtrl.$setViewValue(currencyformat);
                   modelCtrl.$render();
                   return;
                 }else{
                   currencyformat = currencyformat + "." + decPart.slice(0,2);
                   modelCtrl.$setViewValue(currencyformat);
                   modelCtrl.$render();
                 }
             }
            });
      }
  };

})


-1
<input type="text" ng-model="employee.age" valid-input input-pattern="[^0-9]+" placeholder="Enter an age" />

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

app.controller('dataCtrl', function($scope) {
});

app.directive('validInput', function() {
  return {
    require: '?ngModel',
    scope: {
      "inputPattern": '@'
    },
    link: function(scope, element, attrs, ngModelCtrl) {

      var regexp = null;

      if (scope.inputPattern !== undefined) {
        regexp = new RegExp(scope.inputPattern, "g");
      }

      if(!ngModelCtrl) {
        return;
      }

      ngModelCtrl.$parsers.push(function(val) {
        if (regexp) {
          var clean = val.replace(regexp, '');
          if (val !== clean) {
            ngModelCtrl.$setViewValue(clean);
            ngModelCtrl.$render();
          }
          return clean;
        }
        else {
          return val;
        }

      });

      element.bind('keypress', function(event) {
        if(event.keyCode === 32) {
          event.preventDefault();
        }
      });
    }
}}); </script>

1
코드 덤핑은 일반적으로 눈살을 찌푸립니다. 설명을 추가 해주세요.
rayryeng

1
키를 제한하려면 이것을 시도하십시오---function Number (evt) {var charCode = (evt.which)? evt.which : event.keyCode if (charCode> 31 && (charCode <48 || charCode> 57)) return false; true를 반환하십시오. <input type = "number"min = "0"onkeypress = "return Number (event)">
Rahul Sharma

-1

기본 HTML

<input type="number" />

기본 부트 스트랩

<input class="form-control" type="number" value="42" id="my-id">

@Praveen 나는 당신과 동의하지 않습니다. 질문은 어떤 부트 스트랩도 언급하지 않습니다. 질문에 존재하지 않는 것을 언급해야하는 이유는 무엇입니까?
Amr Ibrahim

부트 스트랩을 사용하려는 경우 <input class="form-control" type="number" >
Amr Ibrahim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.