{"id":367,"date":"2017-03-07T19:11:39","date_gmt":"2017-03-07T11:11:39","guid":{"rendered":"https:\/\/www.zhuyanbin.com\/?p=367"},"modified":"2017-03-07T19:12:56","modified_gmt":"2017-03-07T11:12:56","slug":"and-ios-numeric-keypad","status":"publish","type":"post","link":"https:\/\/www.yanbin888.com\/?p=367","title":{"rendered":"<input type=\"number\"> and iOS&#8217; numeric keypad"},"content":{"rendered":"<p>You probably already know about HTML<i>5<\/i>&#8216;s <code class=\"language-html highlight\"><span class=\"nt\">&lt;input<\/span> <span class=\"na\">type=<\/span><span class=\"s\">\"number\"<\/span><span class=\"nt\">&gt;<\/span><\/code>. Which if supported by a browser displays a form input optimized for inputting numbers. Whether that means an up\/down spinner or an optimized keyboard.<\/p>\n<p>However iOS&#8217; standard behavior for the number input isn&#8217;t that ideal. By default iOS will display a standard keyboard slightly modified with a row of numbers at the \u00a0top. This isn&#8217;t ideal as you don&#8217;t need the alphabetic keys and iOS already has a full numeric keypad it could use for the input instead. <i>For reference, other mobile OS such as Android already display their numeric keypad when focusing a number input.<\/i><\/p>\n<p><a href=\"http:\/\/html5doctor.com\/html5-forms-input-types\/#input-number\">A html5doctor article<\/a> article went over this, pointed out a trick by Chris Coyier using <code class=\"language-html highlight\"><span class=\"nt\">&lt;input<\/span> <span class=\"na\">type=<\/span><span class=\"s\">\"text\"<\/span> <span class=\"na\">pattern=<\/span><span class=\"s\">\"[0-9]*\"<\/span><span class=\"nt\">&gt;<\/span><\/code> in which the pattern forces iOS to use it&#8217;s numeric keypad, and also mentioned HTML5&#8217;s <a href=\"http:\/\/www.whatwg.org\/specs\/web-apps\/current-work\/multipage\/association-of-controls-and-forms.html#attr-fe-inputmode\">inputmode<\/a>.<\/p>\n<p>The unfortunate issue with Chris&#8217; technique as-is is the number input is no longer a number input. And the practice of depending on raw string matches to specific regexps in <code class=\"language-html highlight\">pattern=\"\"<\/code> to trigger UI changes is non-standard. So while the trick nicely displays a numeric keypad on iOS the input no longer has the spinner interface on desktop browsers and other mobile devices such as Android no longer use their numeric keyboards.<\/p>\n<p>Wondering if this technique could be applied in a meaningful way to a number input without ruining the experience for users with other devices I started experimenting and came up with another technique.<\/p>\n<div class=\"codelicense-wrapper codelicense-cc0\">\n<pre><code class=\"language-html highlight\"><span class=\"nt\">&lt;input<\/span> <span class=\"na\">type=<\/span><span class=\"s\">\"number\"<\/span> <span class=\"na\">min=<\/span><span class=\"s\">\"0\"<\/span> <span class=\"na\">inputmode=<\/span><span class=\"s\">\"numeric\"<\/span> <span class=\"na\">pattern=<\/span><span class=\"s\">\"[0-9]*\"<\/span> \r\n<span class=\"na\">title=<\/span><span class=\"s\">\"Non-negative integral number\"<\/span><span class=\"nt\">&gt;<\/span><\/code><\/pre>\n<div class=\"codelicense-footer\">This code is <a href=\"https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/\">CC-0<\/a>. You may use it without restriction. (<a href=\"http:\/\/danielfriesen.name\/blog\/2013\/09\/14\/cc0-code-snippets\/\" rel=\"help\">what?<\/a>)<\/div>\n<\/div>\n<p>I found out that the technique of adding <code class=\"language-html highlight\">pattern=\"[0-9]*\"<\/code> to an input to trigger the keypad in iOS works even when the input is <code class=\"language-html highlight\">type=\"number\"<\/code> so both <code class=\"language-html highlight\">type=\"number\"<\/code> and <code class=\"language-html highlight\">pattern<\/code> are used. <code class=\"language-html highlight\">inputmode=\"numeric\"<\/code> was added for forward compatibility as unlike <code class=\"language-html highlight\">pattern=\"[0-9]*\"<\/code> is <em>is<\/em> the standard way to declare that a numeric mode of user input should be used for a form field.<\/p>\n<p>I also realized that the use of pattern triggers the browser&#8217;s native form validation. Which in the case of browsers \u2013 like Firefox \u2013 which have implemented form validation but not <code class=\"language-html highlight\">type=\"number\"<\/code> results in the browser displaying a cryptic &#8220;Please match the requested format.&#8221; message when the user attempts to submit the form and the number input contains some non-numeric characters. So a <code class=\"language-html highlight\">title<\/code> was added which is the standard way to note what type of input is expected within the form field and causes that text to be used inside the error message to describe what the format is.<\/p>\n<p><code class=\"language-html highlight\">pattern<\/code> is ignored by most browsers that implement <code class=\"language-html highlight\">type=\"number\"<\/code> but is used by browsers that implement form validation but not the number input type <i>such as Firefox<\/i>. The pattern <code class=\"language-html highlight\">[0-9]*<\/code> which is the only one that iOS will accept to trigger the keypad only permits the input of non-negative integral numbers. So I added <code class=\"language-html highlight\">min=\"0\"<\/code> to force browsers implementing <code class=\"language-html highlight\">type=\"number\"<\/code> from accepting negative numbers which other browsers would reject.<\/p>\n<p>This technique works in all browsers; Displaying numeric keypads on iOS as well as Android and any other mobile device that&#8217;s implemented <code class=\"language-html highlight\">type=\"number\"<\/code> or <code class=\"language-html highlight\">inputmode=\"numeric\"<\/code> handling. Displaying the numeric spinner on browsers where it&#8217;s implemented such as Chrome and Opera. And displaying user friendly form validation on browsers like Firefox that have validation but no number input.<\/p>\n<p>If you have an iOS device you can try out <a href=\"http:\/\/demos.danf.ca\/iosnumpad\/\">the demo<\/a> which is depicted by <a href=\"http:\/\/danielfriesen.name\/blog\/2013\/09\/19\/input-type-number-and-ios-numeric-keypad\/#fig1\">figure 1<\/a> and <a href=\"http:\/\/danielfriesen.name\/blog\/2013\/09\/19\/input-type-number-and-ios-numeric-keypad\/#fig2\">figure 2<\/a>.<\/p>\n<p>This technique <em>technically<\/em> does not validate. As the spec defines <code class=\"language-html highlight\">inputmode<\/code> and <code class=\"language-html highlight\">pattern<\/code> as attributes on textual inputs but not on <code class=\"language-html highlight\">type=\"number\"<\/code>. However the semantic meaning of these attributes is known and matches the semantic meaning of <code class=\"language-html highlight\">type=\"number\"<\/code>. So while it is <em>technically<\/em> invalid the technique is safe to use and the better user experience is worth any error messages in a validator.<\/p>\n<p><a href=\"https:\/\/www.zhuyanbin.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad-kbd.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-369\" src=\"https:\/\/www.zhuyanbin.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad-kbd.png\" alt=\"\" width=\"320\" height=\"480\" srcset=\"https:\/\/www.yanbin888.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad-kbd.png 320w, https:\/\/www.yanbin888.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad-kbd-200x300.png 200w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0<a href=\"https:\/\/www.zhuyanbin.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-368\" src=\"https:\/\/www.zhuyanbin.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad2.png\" alt=\"\" width=\"320\" height=\"480\" srcset=\"https:\/\/www.yanbin888.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad2.png 320w, https:\/\/www.yanbin888.com\/wp-content\/uploads\/2017\/03\/demoscreenshot-iosnumpad2-200x300.png 200w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>link:\u00a0http:\/\/danielfriesen.name\/blog\/2013\/09\/19\/input-type-number-and-ios-numeric-keypad\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You probably already know about HTML5&#8216;s &lt;input <span class=\"ellipsis\">&hellip;<\/span> <span class=\"more-link-wrap\"><a href=\"https:\/\/www.yanbin888.com\/?p=367\" class=\"more-link\"><span>Read More &rarr;<\/span><\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[37,29],"tags":[38,30],"class_list":["post-367","post","type-post","status-publish","format-standard","hentry","category-cordova","category-ios","tag-cordova","tag-ios"],"_links":{"self":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts\/367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=367"}],"version-history":[{"count":3,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts\/367\/revisions"}],"predecessor-version":[{"id":372,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=\/wp\/v2\/posts\/367\/revisions\/372"}],"wp:attachment":[{"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yanbin888.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}