2

I have a jsbin --> https://jsbin.com/yipigicuve/edit?html,console,output

As per the link, i have the following code

<input ng-keypress="Num($event)" type="number" step=".1" ng-pattern="/^[+-]?(?:\d+\.?\d*|\d*\.?\d+)[\r\n]*$|^$/" ng-model="dataip"></>

$scope.Num = 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, 'dash':189, 'subtract':109
};
for (var index in keys) {
    if (!keys.hasOwnProperty(index)) continue;
    if (event.charCode == keys[index] || event.keyCode == keys[index]) {
        return; //default event
    }
}
event.preventDefault();
};

User enters alphabets and those are not accepted. There are certain alphanumeric keys which is accepted as shown in variable 'keys'

Certain patterns are presented so that null values, decimal point can be accepted.

My problem is....the current input type in the jsbin accepts values such as '-2.34---45' or '3.4...345"

It should accept decimal point and negative sign only once. i.e. '3.5566' or '-23.33'

Can someone let me know how to use ng-pattern to achieve my conditions.

2 Answers 2

1

You can just simplify your life and use what is already done.

Use this directive: nksOnlyNumber.

You can set the input accordingly your requirements.

Here's a snippet working:

angular.module('app', [])
  .controller('mainCtrl', function($scope) {

  })
  .directive('nksOnlyNumber', function() {
    return {
      restrict: 'EA',
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        scope.$watch(attrs.ngModel, function(newValue, oldValue) {
          var spiltArray = String(newValue).split("");

          if (attrs.allowNegative == "false") {
            if (spiltArray[0] == '-') {
              newValue = newValue.replace("-", "");
              ngModel.$setViewValue(newValue);
              ngModel.$render();
            }
          }

          if (attrs.allowDecimal == "false") {
            newValue = parseInt(newValue);
            ngModel.$setViewValue(newValue);
            ngModel.$render();
          }

          if (attrs.allowDecimal != "false") {
            if (attrs.decimalUpto) {
              var n = String(newValue).split(".");
              if (n[1]) {
                var n2 = n[1].slice(0, attrs.decimalUpto);
                newValue = [n[0], n2].join(".");
                ngModel.$setViewValue(newValue);
                ngModel.$render();
              }
            }
          }


          if (spiltArray.length === 0) return;
          if (spiltArray.length === 1 && (spiltArray[0] == '-' || spiltArray[0] === '.')) return;
          if (spiltArray.length === 2 && newValue === '-.') return;

          /*Check it is number or not.*/
          if (isNaN(newValue)) {
            ngModel.$setViewValue(oldValue || '');
            ngModel.$render();
          }
        });
      }
    };
  });
<!DOCTYPE html>
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>

<body ng-controller="mainCtrl">
  <form name="form">
    <input type="text" nks-only-number ng-model="dataip" decimal-upto="6" />
  </form>
</body>

</html>

Sign up to request clarification or add additional context in comments.

2 Comments

if i run the code snippet, it allows me to enter strings. i donot want user to enter strings...
@Patrick it was just because his code in (Readme) is different from the original code, I corrected it, check it now. It's perfect!
1

Actually your ng -pattern is working correctly , ng -pattern just going to put the value of your model as undefined but visually you will not see anything, to do that you could use a filter and not allow a character that does not correspond with your pattern , or simply change some visual aspect of your input to notify that the value entered is incorrect

css (example):

  <style>
    .match{
      border-color:green;
    }

    .no-match{
      border-color:red;
    }

    input{
      outline:none;
    }
  </style>

html:

    <input ng-class="{'match':dataip, 'no-match':!dataip}" 
           ng-keypress="Num($event)"
           type="number" 
           step=".1" 
           ng-pattern="/^[+-]?(?:\d+\.?\d*|\d*\.?\d+)[\r\n]*$|^$/" 
           ng-model="dataip" />

  {{dataip}} <!--Print your model-->

With this approach you could code your filter or handle it with css

Note: this value is allowed 1.11. (dot at the end), check your pattern to avoid this behavior

I hope this answers your question

To know more about ngPattern, check the angular docs https://docs.angularjs.org/api/ng/directive/ngPattern

3 Comments

thanks for your suggestion. You mentioned it will allow '1.11.'. Is it possible to have a variation in ng-pattern so that it only allows decimal point once and negative sign at the start only.
this is a very useful answer. thanks. before i accept it as a answer, can you tell me how to avoid 1.11. if we type 1.11. as per your answer, it shows a green border. instead it should show a red border
@Patrick Actually your pattern is correct, you can check it here regex101.com; visually the input is green but internally the model is displayed without the dot --> .111. is .111 to the model, but if you add something more after this dot the value becomes undefined .111.1 is undefined, so your pattern is correct.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.