CodeMan CodeMan - 5 months ago 13
Javascript Question

How to make input type="tel" work as type="password"

When using the

tag as
the keyboard on touch devices correspond with the type of input box. However, I wish to keep the value in the
tag hidden (as with the
The normal behaviour would be to have each character hidden as the user is typing.

<input type="tel">

input [type="tel"] {
-webkit-text-security: disc;

This solution works in most browsers, but not in IE.

<input type="password" pattern="[0-9]*" inputmode="numeric">

This solution doesn't work as expected.

Is there any way to accomplish what i'm trying to do?


As @Fidel90 and others have pointed out, you could try switching the type="tel" to type="password" after the user has selected it. I made a fiddle of that idea here. It works perfectly in iOS, but in Android it fails to launch the first tap, and then launches as the default keyboard on the second tap.

Another idea in the comments is to use a font that has only a password dot character, though you would have to ensure the user has the font or their device or their device can render web fonts.

My idea (below) is to use a second input to store the real number and then hide the number as the user types it. Note that this will filter all non-phone number characters from the final number, though you can modify the variable to accept whatever you want.

Tested and works on:

  • iOS 9 Safari
  • Android 6.0 Chrome
  • Internet Explorer 11
  • FireFox 45
  • Chrome 50
  • Opera 36
  • Microsoft Edge 25

var BACKSPACE_CHARS = [8, 46, 229];

function hideNumber(fakeInput, event) {
    var hideChar = '*';
    // add characters that you want to appear in the final number to this
    // string -- leave the string empty to allow all characters
    var phoneChars = '0123456789()-+';
    var keyCode = event.keyCode || event.charCode;
    var key = String.fromCharCode(keyCode)+'';
    var realInput = document.getElementById("hidden-number");
    var len = fakeInput.value.length;
    fakeInput.value = '';
    if(phoneChars.indexOf(key) > -1 || !phoneChars.length) {
        realInput.value += key;
    } else {
        if(BACKSPACE_CHARS.indexOf(keyCode) < 0) {
    for(var i=0; i<len; i++) { // no String.repeat() in IE :(
        fakeInput.value += hideChar;

function backspace(event) {
    var keyCode = event.keyCode || event.charCode;
    var realInput = document.getElementById("hidden-number");
    if(BACKSPACE_CHARS.indexOf(keyCode) > -1) { // backspace or delete
        var len = realInput.value.length;
        realInput.value = realInput.value.slice(0, len-1);

function updateDisplay() {
    var realInput = document.getElementById("hidden-number");
    var display = document.getElementById("display");
    display.innerHTML = realInput.value || '';
<input type="tel" name="number" id="number-hider" onkeypress="hideNumber(this, event)" onkeydown="backspace(event)" onblur="hideNumber(this)">
<input type="hidden" name="realnumber" id="hidden-number">
<div id="display"></div>

Known bugs:

  • If a user taps or clicks in the middle of the text box and types or backspaces, the characters will be added or deleted from the end of the real number.