web-dev-qa-db-fra.com

angularjs: autorise uniquement la saisie de numéros dans une zone de texte

Dans angularjs, existe-t-il une fonctionnalité disponible permettant uniquement de saisir des nombres dans une zone de texte comme

64
Ali Hasan

Cette fonctionnalité est exactement ce dont vous avez besoin. http://docs.angularjs.org/api/ng.directive:input.number

MODIFIER:

Vous pouvez envelopper le plugin jquery dans une directive. J'ai créé un exemple ici: http://jsfiddle.net/anazimok/jTJCF/

HTML:

<div ng-app="myApp">
    <div>
        <input type="text" min="0" max="99" number-mask="" ng-model="message">
            <button ng-click="handleClick()">Broadcast</button>
    </div>

</div>

CSS:

.ng-invalid {
    border: 1px solid red;
}

JS:

// declare a module
var app = angular.module('myApp', []);

app.directive('numberMask', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            $(element).numeric();
        }
    }
});
23
anazimok

Ce code montre l'exemple pour empêcher la saisie de symboles non numériques.

angular.module('app').
  directive('onlyDigits', function () {

    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, modelCtrl) {
            modelCtrl.$parsers.Push(function (inputValue) {
                if (inputValue == undefined) return '';
                var transformedInput = inputValue.replace(/[^0-9]/g, '');
                if (transformedInput !== inputValue) {
                    modelCtrl.$setViewValue(transformedInput);
                    modelCtrl.$render();
                }
                return transformedInput;
            });
        }
    };
});
62
Anton

HTML

 <input type="text" name="number" only-digits>

// suffit de taper 123

  .directive('onlyDigits', 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 !== val) {
              ctrl.$setViewValue(digits);
              ctrl.$render();
            }
            return parseInt(digits,10);
          }
          return undefined;
        }            
        ctrl.$parsers.Push(inputValue);
      }
    };
});

// type: 123 ou 123.45

 .directive('onlyDigits', 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 undefined;
        }            
        ctrl.$parsers.Push(inputValue);
      }
    };
 });
41
My Mai

Je viens d'utiliser ng-keypress dans la directive pour mon entrée.

HTML:

<input type="text" ng-keypress="filterValue($event)"/>

JS:

$scope.filterValue = function($event){
        if(isNaN(String.fromCharCode($event.keyCode))){
            $event.preventDefault();
        }
};
36
samnau

C'est le moyen le plus simple et le plus rapide, permettant uniquement la saisie de numéro.

<input type="text" id="cardno" placeholder="Enter a Number" onkeypress='return event.charCode >= 48 && event.charCode <= 57' required>

Merci

17
Sijan Gurung

Ma solution accepte Copier/Coller et enregistre la position du curseur. Utilisé pour le coût des produits, n'autorise que les valeurs décimales positives. Peut être refactor très facile à autoriser les chiffres négatifs ou entiers. 

angular
        .module("client")
        .directive("onlyNumber", function () {
            return {
                restrict: "A",
                link: function (scope, element, attr) {
                    element.bind('input', function () {
                        var position = this.selectionStart - 1;

                        //remove all but number and .
                        var fixed = this.value.replace(/[^0-9\.]/g, '');  
                        if (fixed.charAt(0) === '.')                  //can't start with .
                            fixed = fixed.slice(1);

                        var pos = fixed.indexOf(".") + 1;
                        if (pos >= 0)               //avoid more than one .
                            fixed = fixed.substr(0, pos) + fixed.slice(pos).replace('.', '');  

                        if (this.value !== fixed) {
                            this.value = fixed;
                            this.selectionStart = position;
                            this.selectionEnd = position;
                        }
                    });
                }
            };
        });

Mettez sur la page html:

<input type="text" class="form-control" only-number ng-model="vm.cost" />
7
Carlos Toledo

Pour compléter un peu la réponse d'Anton -

angular.module("app").directive("onlyDigits", function ()
{
    return {
        restrict: 'EA',
        require: '?ngModel',
        scope:{
            allowDecimal: '@',
            allowNegative: '@',
            minNum: '@',
            maxNum: '@'
        },

        link: function (scope, element, attrs, ngModel)
        {
            if (!ngModel) return;
            ngModel.$parsers.unshift(function (inputValue)
            {
                var decimalFound = false;
                var digits = inputValue.split('').filter(function (s,i)
                {
                    var b = (!isNaN(s) && s != ' ');
                    if (!b && attrs.allowDecimal && attrs.allowDecimal == "true")
                    {
                        if (s == "." && decimalFound == false)
                        {
                            decimalFound = true;
                            b = true;
                        }
                    }
                    if (!b && attrs.allowNegative && attrs.allowNegative == "true")
                    {
                        b = (s == '-' && i == 0);
                    }

                    return b;
                }).join('');
                if (attrs.maxNum && !isNaN(attrs.maxNum) && parseFloat(digits) > parseFloat(attrs.maxNum))
                {
                    digits = attrs.maxNum;
                }
                if (attrs.minNum && !isNaN(attrs.minNum) && parseFloat(digits) < parseFloat(attrs.minNum))
                {
                    digits = attrs.minNum;
                }
                ngModel.$viewValue = digits;
                ngModel.$render();

                return digits;
            });
        }
    };
});
7
Craig

Basé sur djsiz solution, enveloppé dans la directive .

angular
        .module("app")
        .directive("mwInputRestrict", [
            function () {
                return {
                    restrict: "A",
                    link: function (scope, element, attrs) {
                        element.on("keypress", function (event) {
                            if (attrs.mwInputRestrict === "onlynumbers") {
                                // allow only digits to be entered, or backspace and delete keys to be pressed
                                return (event.charCode >= 48 && event.charCode <= 57) ||
                                       (event.keyCode === 8 || event.keyCode === 46);
                            }
                            return true;
                        });
                    }
                }
            }
        ]);

HTML

 <input type="text"
        class="form-control"
        id="inputHeight"
        name="inputHeight"
        placeholder="Height"
        mw-input-restrict="onlynumbers"
        ng-model="ctbtVm.dto.height">
3
igorGIS

C'est la méthode qui fonctionne pour moi. Il est basé dans samnau anwser mais permet de soumettre le formulaire avec ENTER, d’augmenter et de diminuer le nombre avec les flèches UP et DOWN, d’éditer avec DEL, BACKSPACE, LEFT et RIGHT et de naviguer dans les champs avec TAB. Notez que cela fonctionne pour les entiers positifs tels qu'un montant.

HTML:

<input ng-keypress="onlyNumbers($event)" min="0" type="number" step="1" ng-pattern="/^[0-9]{1,8}$/" ng-model="... >

ANGULARJS: 

$scope.onlyNumbers = function(event){   
    var keys={
        'up': 38,'right':39,'down':40,'left':37,
        'escape':27,'backspace':8,'tab':9,'enter':13,'del':46,
        '0':48,'1':49,'2':50,'3':51,'4':52,'5':53,'6':54,'7':55,'8':56,'9':57
    };
    for(var index in keys) {
        if (!keys.hasOwnProperty(index)) continue;
        if (event.charCode==keys[index]||event.keyCode==keys[index]) {
            return; //default event
        }
    }   
    event.preventDefault();
};
2
Leopoldo Sanczyk

Utilisez simplement HTML5 

<input type="number" min="0"/>
2
Rohidas Kadam

C’est simple et compréhensible… .. Il suffit de copier/coller ce code pour résoudre le problème.

<input type="text"  pattern="[0-9]{0,}" oninvalid="this.setCustomValidity('Please enter only numeric value. Special character are not allowed.')" oninput="setCustomValidity('')">
1
user6782881

Vous pouvez vérifier https://github.com/rajesh38/ng-only-number

  1. La saisie est limitée aux chiffres et au point décimal dans une zone de texte lors de la frappe.
  2. Vous pouvez limiter le nombre de chiffres à autoriser avant et après le point décimal.
  3. Il supprime également les chiffres après le point décimal si le point décimal est supprimé de la zone de texte, par exemple. si vous avez mis 123.45 et ensuite supprimé le point décimal, il supprimera également les derniers chiffres après le point décimal et le rendra 123.
1
Rajesh Paul

Cette solution n'acceptera que des chiffres, '.' et '-' 

De plus, cela limite l'entrée d'espace dans la zone de texte. J'avais utilisé la directive pour atteindre le même objectif.

S'il vous plaît avoir la solution sur l'exemple de travail ci-dessous.

http://jsfiddle.net/vfsHX/2697/

HTML:

<form ng-app="myapp" name="myform" novalidate> 
<div ng-controller="Ctrl">
<input name="number" is-number ng-model="wks.number">
<span ng-show="!wks.validity">Value is invalid</span>
</div>

JS:

var $scope;
var app = angular.module('myapp', []);

app.controller('Ctrl', function($scope) {
    $scope.wks =  {number: 1, validity: true}
});

app.directive('isNumber', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {   
        element.bind("keydown keypress", function (event) {
          if(event.which === 32) {
            event.returnValue = false;
            return false;
          }
       }); 
            scope.$watch(attrs.ngModel, function(newValue,oldValue) {
                var arr = String(newValue).split("");
                if (arr.length === 0) return;
                if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;
                if (arr.length === 2 && newValue === '-.') return;
                if (isNaN(newValue)) {
                    //scope.wks.number = oldValue;
                    ngModel.$setViewValue(oldValue);
                                    ngModel.$render();
                }
            });

        }
    };
});
1
Suve

Vous pouvez faire quelque chose comme ceci: Utilisez ng-pattern avec RegExp "/^ [0-9] + $/", cela signifie que seuls les nombres entiers sont valides.

<form novalidate name="form">
    <input type="text" data-ng-model="age" id="age" name="age" ng-pattern="/^[0-9]+$/">
    <span ng-show="form.age.$error.pattern">The value is not a valid integer</span>
</form>
1
Victor Oliveira
 <input type="text" ng-keypress="checkNumeric($event)"/>
 //inside controller
 $scope.dot = false
 $scope.checkNumeric = function($event){
 if(String.fromCharCode($event.keyCode) == "." && !$scope.dot){
    $scope.dot = true
 }
 else if( isNaN(String.fromCharCode($event.keyCode))){
   $event.preventDefault();
 }
0
Ramesh Ramasamy

Je sais que c’est un vieux post, mais cette adaptation de la réponse de Ma Mai me convient parfaitement ...

angular.module("app").directive("numbersOnly", function() {
  return {
    require: "ngModel",
    restrict: "A",
    link: function(scope, element, attr, ctrl) {
        function inputValue(val) {
            if (val) {
                //transform val to a string so replace works
                var myVal = val.toString();

                //replace any non numeric characters with nothing
                var digits = myVal.replace(/\D/g, "");

                //if anything needs replacing - do it!
                if (digits !== myVal) {
                    ctrl.$setViewValue(digits);
                    ctrl.$render();
                }
                return parseFloat(digits);
            }
            return undefined;
        }
        ctrl.$parsers.Push(inputValue);
    }
  };
});
0
Janey

J'ai eu un problème similaire et fini par accrocher et événement 

ng-change="changeCount()" 

puis:

self.changeCount = function () {
      if (!self.info.itemcount) {
        self.info.itemcount = 1;
      }
 };

Ainsi, la valeur par défaut de l'utilisateur est 1 si un nombre non valide est inséré.

0
leeroya

J'ai arrogé le jQuery dans this

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

        element.on('keydown', function(event) {                  
            // Allow: backspace, delete, tab, escape, enter and .
            var array2 = [46, 8, 9, 27, 13, 110, 190]
            if (array2.indexOf(event.which) !== -1 ||
                 // Allow: Ctrl+A
                (event.which == 65 && event.ctrlKey === true) ||
                 // Allow: Ctrl+C
                (event.which == 67 && event.ctrlKey === true) ||
                 // Allow: Ctrl+X
                (event.which == 88 && event.ctrlKey === true) ||
                 // Allow: home, end, left, right
                (event.which >= 35 && event.which <= 39)) {
                     // let it happen, don't do anything
                     return;
            }
            // Ensure that it is a number and stop the keypress
            if ((event.shiftKey || (event.which < 48 || event.which > 57)) && (event.which < 96 || event.which > 105)) {
                event.preventDefault();
            }
         });

     }
   };
})
0
plampot

Cette réponse sert de simplification et d'optimisation par rapport à La réponse de Leopoldo .

Déclenchez une fonction à partir de votre entrée à chaque touche du bas comme ceci:

<input type="text" ng-keydown="onlyNumbers($event);"/>

Vous pouvez décrire la fonction de cette manière dans votre contrôleur.

$scope.onlyNumbers = function(event){    
    // 'up': 38,'right':39,'down':40,'left':37,
    // 'escape':27,'backspace':8,'tab':9,'enter':13,'del':46,
    // '0':48,'1':49,'2':50,'3':51,'4':52,'5':53,'6':54,'7':55,'8':56,'9':57
    var keys = { 38:true,39:true,40:true,37:true,27:true,8:true,9:true,13:true,
                 46:true,48:true,49:true, 50:true,51:true,52:true,53:true,
                 54:true,55:true,56:true,57:true };

    // if the pressed key is not listed, do not perform any action
    if(!keys[event.keyCode]) { event.preventDefault(); }
}

Si vous utilisez Angular 2+, vous pouvez appeler cette même fonction de la manière suivante:

<input type="text" (keydown)="onlyNumbers($event);"/>

Votre fonction Angular 2+ devrait ressembler à ceci:

onlyNumbers(event) { // the logic here }
0
Surya
<input type="phone" numbers-only >

Vous pouvez utiliser cette méthode si vous ne voulez que des chiffres :)

voici la demo cliquez

0
Sayed Mohd Ali

J'ai fait à

.js

$scope.numberOnly="(^[0-9]+$)";

.html

<input type="text" name="rollNo" ng-model="stud.rollNo" ng-pattern="numberOnly" ng-maxlength="10" maxlength="10" md-maxlength="10" ng-required="true" >
0
Nilesh Panchal