There are several tricks for displaying different keyboards on mobile devices for HTML 5 inputs (i.e. <input> tags).
For example, some are documented on Apple's website, Configuring the Keyboard for Web Views.
These are great for usability, but when it comes to an input for for international postal codes (mostly numeric, but letters allowed), we're left with some poor options. Most people recommend using the pattern="\d*" trick to show the numeric keyboard, but that doesn't allow for letter input.
The type="number" input type shows the regular keyboard but shifted to the numeric layout:
This works well for iOS devices, but it makes Chrome think the input must be a number and even changes the input's behavior (up/down increment and decrement the value).
Is there any way to get iOS to default to the numeric layout, but still allow for alphanumeric input?
Basically, I want the iOS behavior for type="number" but I want the field to behave like a regular text field on desktop browsers. Is this possible?
UPDATE:
Sniffing the user-agent for iOS and using the type="number" input type is not an option. type="number" is not meant for string values (like postal codes), and it has other side effects (like stripping leading zeros, comma delimiters, etc) that make it less than ideal for postal codes.
Will this work?
HTML:
<input type="tel" pattern="[0-9]*" novalidate>
This should give you the nice numeric keyboard on Android/iOS phone browsers, disable browser form validation on desktop browsers, not show any arrow spinners, allows leading zeros, and allows commas and letters on desktop browsers, as well as on iPad.
Android / iOS phones:
Desktop:
iPad:
Browsers currently have no proper way of representing numeric codes like postcodes and credit card numbers. The best solution is to use type='tel' which will give you a number keypad and ability to add any character on desktop.
Type text and pattern='\d*' will give you a number keypad but only on iOS.
There is an HTML5.1 proposal for an attribute called inputmode which would allow you to specify keypad regardless of type. However not is not currently supported by any browser.
I would also recommend having a look at the Webshim polyfill library which has a polyfill method for these types of inputs.
A quick google search found this Stackoverflow question.
HTML
<input type="text">
Javascript
$('input[type="text"]').on('touchstart', function() {
$(this).attr('type', 'number');
});
$('input[type="text"]').on('keydown blur', function() {
$(this).attr('type', 'text');
});
The input type is switched before the form can be validated, showing the correct keyboard without messing up the value. If you only want it to run on iOS, you will probably have to use the user agent.
Stackoverflow on detecting iOS
An update to this question in iOS 11. You can get the number keypad by simply adding the pattern attribute (pattern="[0-9]*") to any input with a number type.
The following works as expected.
<input type="number" pattern="[0-9]*">
This also works.
<input type="number" pattern="\d*">
#davidelrizzo posted part of the answer, but the comments from #Miguel Guardo and #turibe give a fuller picture but are easy to miss.
This will make the numerical side of the ios keyboard display by default and maintains the ability to switch to the alphabetical side. When the html input type changes, the device changes the keyboard to match the appropriate type.
(function ($) {
var control = $('#test2');
var field = $('#test1');
control.bind('click', function () {
if (control.is(':checked')) {
field.attr('type', 'text');
} else {
field.attr('type', 'number');
}
})
}(jQuery));
<input type="number" id="test1" value="123" />
<input id="test2" type="checkbox" />Change
alternate demo: http://jsfiddle.net/davidcondrey/dbg1L0c0/3/embedded/result/
If you want the large numerical format keyboard (the telephone style) you can adjust the code accordingly and it still works:
(function ($) {
var control = $('#test2');
var field = $('#test1');
control.bind('click', function () {
if (control.is(':checked')) {
field.attr('type', 'text');
} else {
field.attr('type', 'tel');
}
})
}(jQuery));
<input type="tel" id="test1" value="a" />
<input id="test2" type="checkbox" />Change
You can use the native HTML API attribute called inputmode="numeric", inputmode="decimal". (This is the preferred way to implement it)
You can read further about input mode at the MDN here
<input type="number" inputmode="numeric" />
Try this:
<input type="text" name="postalcode" class="js-postal">
<script src="https://code.jquery.com/jquery-2.1.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
if('ontouchstart' in window) { // ensure we are in touch device.
$('input.js-postal').on('focus', function() {
var $this = $(this);
// memorize current value because...
var val = $this.val();
// this may cause reset value.
$this.attr('type', 'number');
setTimeout(function() {
// Asynchronously restore 'type' and value
$this.attr('type', 'text');
$this.val(val);
}, 0);
});
}
});
</script>
I know this is very hackish way, but this apparently works.
I haven't tested on Android devices though.
Note this may causes a little noticeable glitches when $this.attr('type', 'number') because this reset the value when input has non numerical characters.
Basic ideas are stolen from this answer :)
<input type="tel" inputmode="decimal">
Above has been working for me for several years. By working, I mean that on mobile devices, a numeric virtual keyboard is displayed when the input receives focus. On iOS devices, the keyboard allows users to enter numbers, decimals, and characters. My keyboard event handler inserts thousand separators, and there is no issue with passing validation, so I assume that users could also type in commas. Negative values can be entered, so hyphens are allowed, though I don't see a hyphen on the iOS keyboard.
If you would like to try this, you may try any calculator at my site.
Why not check the header of the HTTP request (user agent), and serve up the numeric layout to the iOS devices, while serving up the alphanumeric layout to the rest?
Related
I am making an app using ionic framework -v1, now i found out when deploying my app to IOS the app seems to works perfectly fine at first.
But when i enter a space (using the mobile number keypad) in my input=[number] field the app starts flickering and loses the scopes with the space in them. Later when i want to push my data to angularfire it also completely stops working and wont let me push my data.
My input is as simple as this:
<input type="number" name="" ng-model="info.DriversLicensenr">
My customer would like the field to have spaces in them, but also the numbers keypad should show up when pressed in the app.
Is there any way to allow spaces? or to modify another input type to reach the desired effect?
This kind of input will open a number pad on mobile device. However, you will have to check that the user doesn't type other caracters than numbers.
<input type="text" inputmode="numeric" ng-model="ctrl.dLicence"/>
EDIT
<input type="text" pattern="[0-9\s]*"/>
This opens a number pad, but doesn't limit to numbers only.
No that's not possible i will suggest you to use input type text and then use ng-pattern to validate it is number or not. This won't stop you from inserting characters but will show error it there's a character or any other special characters.
To restrict input to only numbers or space , use below code
<input type="text" inputmode="numeric" oninput="formatNumber(event)"/>
function formatNumber(event){
let value = event.target.value || '';
value = value.replace(/[^0-9 ]/,'');
event.target.value = value;
}
I'm getting an error on the newer versions of iOS' Mobile Safari. This error didn't happen prior to version 10.3 of iOS. Can someone point me in the right direction on this?
Here's the raw HTML and attached are the inspected view and the view of the mobile device (iPhone 7).
Simple solution!
IOS requires a value to be set on an input field with a type of "datetime-local".
Example: <input type="datetime-local" value="2000-07-01T12:00" />
That's it :)
I personally find it nice to set the default value to the users current local time. This has to be formatted in ISOTime without seconds, so the code for this might be something like:
// get the iso time string formatted for usage in an input['type="datetime-local"']
var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0,-1);
var localISOTimeWithoutSeconds = localISOTime.slice(0,16);
// select the "datetime-local" input to set the default value on
var dtlInput = document.querySelector('input[type="datetime-local"]');
// set it and forget it ;)
dtlInput.value = localISOTime.slice(0,16);
This message is triggered by client-side validation. If you are not using client-side validation then I found you can fix this issue by turning it off using the novalidate attribute as follows:
<form action="/myaction" method="POST" novalidate>
For the whom still struggle with IOS datetime-local same as me.
This caused by IOS set datetime-local value in invalid format when value attribute/property not set or set with invalid one.
<input type='datetime-local' onChange='alert(event.target.value)'>
This will alert with 'yyyy-MM-ddThh:mm:ss' format such as 2018-12-25T12:00:00 which has unallowed string of seconds.
To bypass it, simply set the value with valid form.
const onChange = (event) => {
event.target.value = event.target.value.substr(0, 16);
}
That`s it.
Seems it's a bug in Safari, but you can skip it by using javascript to submit the form.
$("#new_apply_form").submit();
It is a bug in Safari. You should use JS to submit the form instead.
JS: form.submit();
format('Y-m-d\TH:i') worked for me.
This is fixed in iOS 15.4. On iOS 15.3.1, as soon as the user taps on the input, it automatically gets populated with the current date/time and the value will be something like this:
2022-03-18T13:30:45.123
So, unless the user changes the date and/or time to something else, submitting the form will cause a client-side validation error.
But on iOS 15.4, as soon as the user taps on the input, it still automatically gets populated with the current date/time, but now the value will be something like this:
2022-03-18T13:30
I was tring to use material component in angular 2 dart as a number input:
<material-input type="number"></material-input>
but it behaves like a normal input. In docs it sais it supports type "number". Am i doing anything wrong? Or isn't number type implemented yet?
Thank you for any suggestions.
I can share my personal experiment trying to have a number (integer) input. It does not work perfectly on all browsers but I wanted to have the proper keyboard shown on Android and iOS. What I did was forcing the type on the inner input element programmatically. It seems that on Firefox it does not prevent entering text but does display a message ("Please enter a number"). It does not handle decimal neither (i.e. it does expect an integer)
initInputNumber(MaterialInputComponent inputComponent) {
inputComponent.type = "number";
InputElement inputElement = inputComponent.inputEl.nativeElement;
inputElement.type = "number";
// http://stackoverflow.com/questions/6178556/phone-numeric-keyboard-for-text-input
// As of mid-2015, I believe this is the best solution:
// <input type="number" pattern="[0-9]*" inputmode="numeric">
inputElement.attributes["inputmode"] = "numeric";
inputElement.pattern = "[0-9]*"; // this and only this works 0-9
}
I don't know if that's the best solution but I find it hard to have a complete cross-browser solution
I think you need to set an errorMsg
<material-input type="number" errorMsg="That's not a number"></material-input>
This line https://github.com/dart-lang/angular2_components/blob/a0eff879a6cb347b8beb95ed758c02c6dd9dfaa0/lib/src/components/material_input/material_input.dart#L232 seems to indicate that type="tel" and type="number" are set to text for the internal input element, while this line https://github.com/dart-lang/angular2_components/blob/a0eff879a6cb347b8beb95ed758c02c6dd9dfaa0/lib/src/components/material_input/material_input.dart#L61 says that errorMsg is used when and invalid number is entered when type="number".
I'm trying to get regex pattern in input type number to show only numbers and dots.
I tried something like this.
<input type="number" pattern="[0-9.]*">
<input type="tel">
Both are showing only numbers (0-9), but not displaying . (dot). I need to use dot in input field.
Is it possible thru html5? Or Shall I go with javascript?
Note: This is working fine in Android, but . (dot) not displaying in iphones
I need to display mobile keypad like this..
Any help regarding this?
If you only specify "type=number" it will display keypad on iPhone like:
And if you specify pattern like <input type="number" pattern="\d*"/> or <input type="number" pattern="[0-9]*" />, then keypad on iPhone will be like :
Still it cannot display dot(.), currently there is no pattern to handle such case.
So you may opt for <input type="tel" /> which will provide keypad like:
Please refer to below links for more details on inputs for iOS:
http://bradfrost.com/blog/mobile/better-numerical-inputs-for-mobile-forms/
http://blog.pamelafox.org/2012/05/triggering-numeric-keyboards-with-html5.html
https://about.zoosk.com/nb/engineering-blog/mobile-web-design-use-html5-to-trigger-the-appropriate-keyboard-for-form-inputs/
http://mobiforge.com/design-development/html5-mobile-web-forms-and-input-types
http://www.petefreitag.com/item/768.cfm
http://html5tutorial.info/html5-contact.php
Hope this will help you. :)
Updates for customization (reference: https://stackoverflow.com/a/20021657/1771795)
You can do some customization using javascript.
Lets take example of currency input with decimals pattern in which e.which to read CharCode entered and then push it into an array (before) which represents digits before decimal mark and another array (after) to move values from (before) array past the decimal mark.
complete fiddle link
HTML:
<input type="tel" id="number" />
JS
Variables and functions:
// declare variables
var i = 0,
before = [],
after = [],
value = [],
number = '';
// reset all values
function resetVal() {
i = 0;
before = [];
after = [];
value = [];
number = '';
$("#number").val("");
$(".amount").html("");
}
// add thousand separater
function addComma(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
Main code:
// listen to keyup event
$("#number").on("keyup", function (e, v) {
// accept numbers only (0-9)
if ((e.which >= 48) && (e.which <= 57)) {
// convert CharCode into a number
number = String.fromCharCode(e.which);
// hide value in input
$(this).val("");
// main array which holds all numbers
value.push(number);
// array of numbers before decimal mark
before.push(value[i]);
// move numbers past decimal mark
if (i > 1) {
after.push(value[i - 2]);
before.splice(0, 1);
}
// final value
var val_final = after.join("") + "." + before.join("");
// show value separated by comma(s)
$(this).val(addComma(val_final));
// update counter
i++;
// for demo
$(".amount").html(" " + $(this).val());
} else {
// reset values
resetVal();
}
});
Reset:
// clear arrays once clear btn is pressed
$(".ui-input-text .ui-input-clear").on("click", function () {
resetVal();
});
Result:
Not every input type and attribute is supported in all browsers. In general, most modern browsers from IE10+ include basics such as email and number.
The browser will revert to a standard text input when a specific type and ignore attributes when those values are not supported.
So you should use a good regular expression pattern.
for example
<input type="tel" name="tel" pattern="^(?:\(\d{3}\)|\d{3})[- . ]?\d{3}[- . ]?\d{4}$" />
1234567899
123 456 7899
123-456-7899
123.456.7899
supported
Browser support for 'tel' type
Android (yes)
iOS (yes)
IE (yes)
Mobile (yes)
Opera (yes)
Mobile (yes)
Opera (yes)
Classic (yes)
Opera Mini (no)
Firefox (yes)
Mobile (yes)
Chrome for Android (yes)
(Sources: caniuse.com, DeviceAtlas, mobilehtml5.org)
Browser support for pattern attribute
But the pattern attribute is supported in Internet Explorer 10, Firefox, Opera, and Chrome.
And is not supported in Internet Explorer 9 and earlier versions, or in Safari.
For iOS use the input attribute type="number", inputmode="decimal".
This will show the number pad with the “dots” on iOS 12.3+.
I had a similar scenario whereby I needed to support both comma and point as both the decimal mark and digit grouping [see here]
E.g.
1.00 / 1,00
1,000,000.00 / 1.000.000,00
At the same time the scenario required that the number keypad was displayed on mobile devices.
The initial implementation combined the 'number' type with the pattern attribute.
<input type="number" pattern="^(0*[,.]*[0-9][0-9]*([,.][0-9]+)*|[0-9]?[,.][0-9]*[1-9][0-9]*)$" required />
However the number validation failed inputs that the pattern would allow. This meant the field and thus form were marked as invalid.
The solution was to change the type to 'tel'.
<input type="tel" pattern="^(0*[,.]*[0-9][0-9]*([,.][0-9]+)*|[0-9]?[,.][0-9]*[1-9][0-9]*)$" required />
Mobile users would now see a number keypad by default, and the pattern validation would be used to validate the input.
Unfortunately it's not possible to achieve the exact functionality that you're looking for is not possible. However there is a kind of "hack" available which will give similar functionality:
http://www.brownphp.com/2011/05/iphone-currency-input-web-apps/ (Link broken)
It's a bit of JS which fills in the decimal automatically when the user starts typing, like this: 0.01 -> 0.12 -> 1.23 -> 12.34 . So this can be used for similar effect.
How does Stack Overflow show interactive character limits? Like when editing comments, it shows you how many characters you have left, as well as warning if it is too few.
I'd like that exact functionality in my Ruby on Rails... But not sure how to do it?
Stackoverflow uses the jQuery JavaScript Framework and it has a lot of existing scripts and plugins for this sort of thing.
One example is this Interactive Character Limit for TextArea in jQuery demonstrated here.
I'm sure there are others as well.
I use the following JavaScript function to restrict max length in textareas
function checkLength(edit, maxlen)
{
if (edit.value.length > maxlen)
edit.value = edit.value.substring(0, maxlen);
document.getElementById('remaining').innerHTML = edit.value.length;
}
Link this to your textarea's onKeyDown and onKeyUp attributes:
onKeyDown = "checkLength(this, 100);"
by using the onkeydown event on the input. There are millions of examples out there and frankly I'd be surprised if this isn't a duplicate question.
It is: How to show interactive character limits?
I think you are looking for some javascript, basically you add a handler to the textbox onkeypress event then to get the current length:
mytextbox.value.length
and to limit it you could do something like:
if (mytextbox.value.length > maxlimit)
mytextbox.value = mytextbox.value.substring(0, maxlimit);
You can also use simple javascript event handling to show character counts
for input elements. No server side processing required.
This javascript catches the key-press event for a text area "txt"
and shows the character count in a span "count".
See it running at
http://aaron.oirt.rutgers.edu/myapp/root/charCount.html
<html>
<head>
<script>
function go() {
var txt=document.getElementById("txt");
txt.onkeydown = countTxt;
}
function countTxt() {
var txt=document.getElementById("txt");
var count=document.getElementById("count");
count.innerHTML = txt.value.length+1; // count the character not shown yet ;)
}
</script>
</head>
<body onload="go()">
<h3>type in the text area and see the count change</h3>
<textarea id="txt" rows="8" cols="30"></textarea>
<br>
count: <span id="count"> 0</span>
</body>
The count can be off my +-1 -- fixing that (if you really want to) is left to the reader.