2

I have written the below directive which allow only numeric value to be entered in the input field.The same is working fine except allowing alphanumeric also to be entered for example if i have copied "abc123" and pasting the same in input field then it is accepting numeric and ignoring alphabet which should not be the case .In this case it should not allow anything to be paste in the input field. Please help.

function link(scope, element, attrs, modelCtrl){
        modelCtrl.$parsers.push(function(inputValue) {
            if (inputValue === undefined) return '';

            var cleanInputValue = inputValue.replace('.', '')
                .replace(/[^0-9.]/g, '')
                .replace(/\./, "x")
                .replace(/\./g, "")
                .replace(/x/, ".");
            if (cleanInputValue != inputValue) {
                modelCtrl.$setViewValue(cleanInputValue);
                modelCtrl.$render();
            }
            return cleanInputValue;
        })
    }
Raj
  • 107
  • 2
  • 10
  • Check [angularjs: allows only numbers to be typed into a text box](https://stackoverflow.com/questions/16091218/angularjs-allows-only-numbers-to-be-typed-into-a-text-box). – Wiktor Stribiżew Sep 25 '17 at 11:54
  • If you want to cancel the `paste` completely then you'd have to monitor the clipboard. Ref: https://stackoverflow.com/questions/2176861/javascript-get-clipboard-data-on-paste-event-cross-browser – Brahma Dev Sep 25 '17 at 11:56

4 Answers4

1

$parsers:

<input type="text" ng-model="test" format="number" />

JS

app.directive('format', ['$filter', '$window', function($filter, $window) {
  return {
    require: '?ngModel',
    link: function(scope, elem, attrs, ctrl) {
      if (!ctrl) return;

      scope.vKey = 86;
      scope.ctrlVDown = false;
      angular.element($window).bind("keydown", function($event) {
        console.log($event.keyCode);
        if ($event.keyCode == scope.vKey) {
          scope.ctrlVDown = true;
        } else {
          scope.ctrlVDown = false;
        }
      });


      ctrl.$parsers.unshift(function(viewValue) {
        var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');

        console.log(scope.ctrlVDown);

        if (scope.ctrlVDown && plainNumber.length !== viewValue.length) {
          elem.val('');
          return '';
        } else {
          elem.val(plainNumber);
          return plainNumber;
        }
      });
    }
  };
}]);

Demo Fiddle

Maxim Shoustin
  • 76,444
  • 28
  • 192
  • 219
  • Still i am facing the same problem.If you will copy a alphanumeric value and paste it then it will paste the number and ignore alphabet. – Raj Sep 25 '17 at 12:13
  • @Raj I tried demo 1, I copied `aaaa232323sds` and got `232323`. – Maxim Shoustin Sep 25 '17 at 12:15
  • That is what not required.I want to ignore all the value if it is alphanumeric(e.g if aaaa232323sds is pasted then nothing should be pasted).Allow to paste value in input field if it is only number – Raj Sep 25 '17 at 12:21
  • @Raj well, you cannot achieve that. Check this one: http://jsfiddle.net/2s9bdk67/ it will work for u but if user types inside input field numeric + alpha chars it will also clear the form – Maxim Shoustin Sep 25 '17 at 12:28
  • Thanks Maxim !! But i am able to type alphabet if typed two times and if you will copy "avcds565456" and paste the same two times then in second time it is accepting the entire value. – Raj Sep 25 '17 at 12:52
  • @Raj I think you can do your homework :). Play with flags – Maxim Shoustin Sep 25 '17 at 12:52
  • Thanks for the help Maxim !! – Raj Sep 25 '17 at 12:53
1

Below is a simple directive, which allows you only to enter numbers inside a input field.

When linked to an input field:

<input type="text" ng-model="test" valid-number>

It bind a keydown event on the input field, which checks what key has been pressed. Each key on your keyboard has an global number. For example: enter has the numer 13 assigned.

A complete list of key codes

When you press a key on your keyboard, and its matches the key code listed inside var keyCode

var keyCode = [8, 9, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110];

then we prevent the action from executing.

(function () {

  angular.module("app", [])
  
  .directive("validNumber", function () {
        return {
            restrict: "EA",
            require: "?ngModel",
            link: function (scope, element, attrs, ngModel) {
                if (!ngModel) return;
                var keyCode = [8, 9, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 110];
                element.bind("keydown", function (event) {
                    if ($.inArray(event.which, keyCode) === -1) {
                        scope.$apply(function () {
                            scope.$eval(attrs.validNumber);
                            event.preventDefault();
                        });
                        event.preventDefault();
                    }
                });
            }
        };
    });

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div ng-app="app">
  <input type="text" ng-model="test" valid-number="" name="test">
</div>

UPDATE


Based on your comments on other posted awnsers. You can just use .replace() function to replace everything except numbers.

Even when you copy and paste a valid number with invalid characters, it will replace the invalid characters.

I allowed users to write an dot ., because 5.2 is a valid number. But if you dont want this, you can replace the regex with

value.replace(/[^0-9]/g, "");

DEMO

(function () {

  angular.module("app", [])
  
  .directive("validNumber", function () {
        return {
            restrict: "EA",
            require: "?ngModel",
            link: function (scope, element, attrs, ngModel) {
                if (!ngModel) return;

                element.bind("keypress keyup", function (event) {
                    var value = element.val();
                    value = value.replace(/[^0-9.]/g, "");
                    
                    element.val(value);
                });
            }
        };
    });

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div ng-app="app">
  <input type="text" ng-model="test" valid-number="" name="test">
</div>
Red
  • 5,189
  • 7
  • 32
  • 62
  • can you explain what this key code array is doing?Can you see my code and help me to change the regex to make it work. I think we can we do this by using proper regex. – Raj Sep 26 '17 at 11:47
  • Replace `inputValue.replace('.', '') .replace(/[^0-9.]/g, '') .replace(/\./, "x") .replace(/\./g, "") .replace(/x/, ".");` to `inputValue.replace(/[^0-9.]/g, "");` – Red Sep 26 '17 at 12:16
  • This will behave like it was behaving earlier.It will accept number and ignore alphabet if we will paste any alphanumeric value. – Raj Sep 27 '17 at 07:07
  • Also this will not allow to paste numeric value.This is valid only if typing with key – Raj Sep 27 '17 at 08:53
  • `Also this will not allow to paste numeric value.This is valid only if typing with key`. Tested and does work. I can paste a numeric value inside it. What browser did you test on? – Red Sep 27 '17 at 09:51
  • copy "abc213wse" and paste that in the input field.It will accept the number i.e 213 will pasted and rest will be ignored.I this case nothing should be pasted. – Raj Sep 28 '17 at 06:24
  • I am looking for a regex for alphanumeric value for example :"as12ws".So let say we pasted as "12sas1" so regex will check if the entire value consist of aything other number if so then it will replace the value with empty string – Raj Sep 28 '17 at 06:46
  • I have created a regex i.e var cleanInputValue = inputValue.replace('.', '') .replace(/^(?:[0-9]+[a-zA-Z]|[a-zA-Z]+[0-9]|[a-zA-Z]+[.,!@#$]+[0-9]|[0-9]+[.,!@#$]+[a-zA-Z])[a-z0-9#$@!]*$/g, '') .replace(/[^0-9.]/g, ''); and it worked for me – Raj Sep 28 '17 at 07:22
1

This may helpful

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button 
{   
    -webkit-appearance: none;
    margin: 0; /* some part are still there even though it is hidden */
}
<div ng-app="app">
  <input type="number" >
</div>

if you feel uncomfortable with key 'e' use the following one

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
   $scope.myFunc = function (event) {    
    if (event.keyCode < 48 || event.keyCode > 57)
    {
        event.preventDefault();
    }
};
});
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button 
{   
    -webkit-appearance: none;
    margin: 0; /* some part are still there even though it is hidden */
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
  <input type="text" ng-keypress="myFunc($event)">
</div>
Deepu Reghunath
  • 4,992
  • 1
  • 22
  • 37
  • Thanks !! I have already tried this . But in this case it is accepting "e" also which should not be the case. – Raj Sep 27 '17 at 07:01
  • @Raj. I have made changes as per your requirement – Deepu Reghunath Sep 27 '17 at 07:29
  • Thanks for your effort! But this is not working in case of copy paste.If you will copy and paste some alphanumeric value then it is accepting that which should not be the case. – Raj Sep 27 '17 at 07:31
0

Did you try to set your input type to number?

<input type="number" />

This will automatically strip all alphabetical characters even when user will use paste

Danny K
  • 34
  • 5