2

I am currently developing a part of a web app that takes a 4-digit pin input.

I use a piece of logic to check both the PIN input and PIN conformation input are at least 4 digits and they are the same.

Here is my code:

<md-input-containe>
    <label>New 4-digit PIN</label>
    <input ng-model="selectedDriver.password" type="number"
           ng-pattern="/^\d{4}$/" required>
</md-input-container>
<md-input-containe>
    <label>Confirm the PIN</label>
    <input ng-model="selectedDriver.passwordConfirm" type="number"
           ng-pattern="/^\d{4}$/" required>
</md-input-container>
<md-button class="md-raised" ng-click="saveDriver()"
           ng-disabled="selectedDriver.password != selectedDriver.passwordConfirm 
                     || selectedDriver.password.toString().length != 4">

The main part to take note of is this:

ng-disabled="selectedDriver.password != selectedDriver.passwordConfirm || selectedDriver.password.toString().length != 4"

The problem is, say a pin such as 0123 is entered, .toString() turns it into "123" because it removes the needless leading zeroes so it then fails the length check.

What are some possible solutions? I looked at padding but it doesn't seem to be dynamic enough for what I need, I need a simple function that will take any input like 0012 and turn it into "0012".

A possible solution would be to use text inputs and have some ng-change logic that would block any non-numeric characters being typed but I don't believe that this is the right solution.

Thanks for your help.

EDIT: Apparently I need to explain why this is different to a "padding" issue. This is different because the user's input could be something like '38', if it was '38' I wouldn't want to mindlessly pad it to '0038', it should only be '0038' if they have typed that. I am not somebody who posts on here without scouring the web and trying every existing solution first.

The accepted answer is very useful to other SO users as there is no other one like it on here.

iJamesPHP2
  • 524
  • 4
  • 13
  • 1
    why do you have `toString`? inputs return strings. – Nina Scholz Feb 27 '20 at 15:05
  • @NinaScholz I don't understand your comment – iJamesPHP2 Feb 27 '20 at 15:06
  • @NinaScholz In angularjs, a number input will make its model an integer – iJamesPHP2 Feb 27 '20 at 15:06
  • then change the model. – Nina Scholz Feb 27 '20 at 15:07
  • @NinaScholz Change the model to what? JS as a language doesn't really have type definitions as such. If I wish to get the length in characters of a number input via an angularjs ng-model, I must convert it into a string. – iJamesPHP2 Feb 27 '20 at 15:12
  • @HereticMonkey Please read the question. I have no way to tell if their input is 0123 and not just 123, meaning and cant mindlessly pad it. Thanks though – iJamesPHP2 Feb 27 '20 at 15:18
  • Okay, then [HTML5 Input type=number removes leading zero](https://stackoverflow.com/q/8437529/215552) – Heretic Monkey Feb 27 '20 at 15:21
  • Just a comment, I think the misconception you had/have is that a pin is a number, just because it consists of digits; or a phone-"number", a zip-code, a numeric ID, and so many more. These are not numbers, numbers have a value and this value is independant of the format you represent it in. But a pin `1234` and a "pin" `0x4d2` are not the same and leading zeroes matter. – Thomas Feb 27 '20 at 15:40

1 Answers1

3

I use:

<input type="text" pattern="[0-9]*" ...>

As Chrome removes leading zeros.

With this pattern the numeric keypad is shown on smartphones.

You could also check:

<input type="tel" pattern="[0-9]*" ...>

This one seems to preserve the leading zeros as well.

jeprubio
  • 17,312
  • 5
  • 45
  • 56
  • Thanks, I initially disregarded your answer and then realised you actually changed the input to a text one and used the pattern to restrict it. – iJamesPHP2 Feb 27 '20 at 15:16
  • No problem, I read the question but in my experience it was the browser which seemed to remove the leading 0, and with `type="text"` and the pattern I didn't have that problem. You could also check with `type="tel"` and the pattern, both should work – jeprubio Feb 27 '20 at 15:17