When using the input
tag as type="tel"
the keyboard on touch devices correspond with the type of input box. However, I wish to keep the value in the input
tag hidden (as with the password
type).
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?
<input> elements of type password provide a way for the user to securely enter a password. The element is presented as a one-line plain text editor control in which the text is obscured so that it cannot be read, usually by replacing each character with a symbol such as the asterisk ("*") or a dot ("•").
The <input type="tel"> defines a field for entering a telephone number. Note: Browsers that do not support "tel" fall back to being a standard "text" input. Tip: Always add the <label> tag for best accessibility practices!
You can't change the password masking character in the standard password field. You can fake it with a textbox, but it makes for a weak security model because you don't get the protection you do from the password textbox.
If all you're after is better usability for "pin" inputs, I'd now suggest sticking with the inputmode attribute that didn't work for OP in 2016. The browser support is still quite limited, but it's finally working at least on iOS Safari and as a solution it's much simpler and possibly more secure than avoiding input type="password"
altoghether.
<input type="password" inputmode="tel" />
So for OP's specific use-case I'd now recommend the above even though browser support is not 100%.
I know some people coming to this post are actually looking for type="password"
alternatives for other reasons, like to circumvent password autocomplete, and my original answer below may still help them.
Also note that my password font project that I recommend below has had a few updates since I gave this answer and has a bit different installation instructions now.
I know this already has a nice, working and accepted solution from jdgregson, but I really liked rybo111's idea of a custom font based solution and wanted to give it a try.
The idea is to create a font that only contains circles so that when the font family is applied to the input element, seemingly no characters are displayed.
So in case anyone's still interested in a non-JS solution with decent browser support and without the known issues with jdgregson's answer, I created a simple font for this.
GitHub repo: https://github.com/noppa/text-security
JSFiddle demo: https://jsfiddle.net/449Lamue/6/
The font can be used by including the dist/text-security.css either from cloned repo or from RawGit or something similar. After including the css you can use the font by setting the element's font-family
to 'text-security-disc'
.
<link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/noppa/text-security/master/dist/text-security.css">
<style>
input [type="tel"] {
font-family: "text-security-disc";
-webkit-text-security: disc;
}
</style>
In the spirit of "polyfilling" the -webkit-text-security, I also added the "circle" and "square" options to use as the hiding symbol.
I've tested this with Chrome v49, IE11, Microsoft Edge 25 and Chrome v50 on Android 5.0, in which the input of type "tel" opens the number keypad.
There are several ways you can accomplish this:
The most elegant solution is to use the builtin -webkit-text-security: circle;
CSS style which is intended for this very thing. Unfortunately that is not portable, and isn't supported on IE or Edge. You can find a workaround to get support on other browsers here if you choose to use this approach.
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 suggested by rybo111 in the comments which has been implemented by noppa below is to use a font that has only a password dot character. This is likely the most portable and least hackish solution. One drawback is that the user cannot see the character they just typed as is the usual behaviour for modern mobile password fields. A comprehensive fiddle of this is posted here.
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:
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) {
--len;
}
}
for(var i=0; i<len; i++) { // no String.repeat() in IE :(
fakeInput.value += hideChar;
}
updateDisplay();
}
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);
}
updateDisplay();
}
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:
Using noppa's answer and his GitHub font and jdgregson's answer, here's a turnkey CSS solution (fiddle):
@font-face {
font-family: "password-mask";
src: url(data:font/woff;charset:utf-8;base64,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) format("woff");
}
.numeric-password {
font-family: password-mask;
}
.numeric-password::placeholder {
font-family: initial;
}
<input type="tel" class="numeric-password" placeholder="test" />
To support older iOS and Android devices, you would just need to add another data URI font-face definition with the ttf file for the password mask font. Same for IE with the eot font file but most modern browsers support woff and should work with this CSS.
I created a fiddle that replaces the initial tel
with an password
input as soon as you focus it (jQuery needed):
var value = "",
isPWD = false;
$('#wrap')
.on("focus", "#input", function() {
if (!isPWD) {
var pass = $('<input id="input" type="password">');
$(this).replaceWith(pass);
isPWD = true;
pass.focus();
}
})
.on("change", "#input", function() {
value = $(this).val();
$("#span").text(" = " + value);
})
.on("blur", "#input", function() {
var tel = $('<input id="input" type="tel">');
$(this).replaceWith(tel);
isPWD = false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="wrap">
<input id="input" type="tel"/>
<span id="span"></span>
</div>
I did not test this on a mobile device so far so I'm not sure if bringing the numeric pad up to the user works in every case.
EDIT: At least my mobile IE did not show a numeric pad but only the standard text field.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With