Search code examples
regexangularjsangularjs-ng-pattern

ng-pattern issue with input type number


I am facing one weird issue when trying to use ng-pattern with input type number.

<input type="number" name="input" min="0" max="1000" data-ng-model="input" ng-pattern="/^[0-9]*$/">
    <div data-ng-if="Form.input.$error.pattern">Please enter an Integer number between 0 and 1000.</div>
</div>

As per my regular expression defined, error should be shown when user input 1.. Right?

However, it does not show error when type 1. but shows error for input 1.1 Why not for 1.?

Anything im missing here?


Solution

  • To allow numbers from 0 to 190 (including 190.0000) you can use type="text" and then use the following regex:

    ^(?:(?:\d{1,2}|1[0-8]\d)(?:\.\d+)?|190(?:\.0+)?)$
    

    See demo

    • ^ - The beginning of string anchor (only match the rest if it appears right at the beginning of string, else fail the match)
    • (?:(?:\d{1,2}|1[0-8]\d)(?:\.\d+)?|190(?:\.0+)?) - a non-capturing group that is just used for grouping and not remembering the captured text. It contains 2 alternatives:
      • (?:\d{1,2}|1[0-8]\d)(?:\.\d+)?:
        • (?:\d{1,2}|1[0-8]\d) - Either 1 or 2 any digits (\d{1,2}) or 1 followed by 0, 1...8, and then followed by any 1 digit.
        • (?:\.\d+)? - optionally (as ? means match 1 or 0 times) match a dot and 1 or more digits.
      • 190(?:\.0+)? - matches 190 and then optionally . and 1 or more 0 characters.
    • $ - assert the end of string (if there are more characters after the preceding pattern, no match is found).

    The non-capturing group can be replaced with a capturing group in your case without any visible change in the efficiency and behavior. However, capturing groups keep the text they capture in some buffer, thus are supposed to be slower (though it is really insignificant). Also, capturing groups are necessary when back-references are used in the pattern (when you want to match already matched substrings), but it is not the case here.