Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

autocapitalize="words" broken on mobile Safari in iOS 8,9 - Is there a workaround?

Tags:

The <input> attribute autocapitalize="words" is broken in mobile Safari under iOS 8,9 with the default iOS keyboard. It uppercases the first 2 letters of the field, not the first letter of each word.

Official documentation says is supported: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/Attributes.html

To test, open the following field on iOS emulator or real device:

First name: <input type="text" autocorrect="off" autocapitalize="words" value="First Name"> 

You can use https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_form_submit to test, or this snippet on iOS 8 or 9:

<!DOCTYPE html>  <html lang="en">    <head>      <meta charset="utf-8">      <title>Test autocapitalize</title>     </head>    <body>      <form>        <label for="words">autocapitalize="words"</label>        <input type="text" autocapitalize="words" name="text1" id="words" /><br />        <label for="sentences">autocapitalize="sentences"</label>        <input type="text" autocapitalize="sentences" name="text2" id="sentences" /><br />        <label for="none">autocapitalize="none"</label>        <input type="text" autocapitalize="none" name="text3" id="none" />      </form>    </body>  </html>

I'm amazed this has been present since 8.x and has passed under the radar.

Is there a known workaround?

Update 10/13: iPhone 6s+ Safari completely ignores any HTML attribute set on the input field.

like image 255
juanca Avatar asked Sep 18 '15 15:09

juanca


1 Answers

There seems to be a workaround for this issue if you are willing to (temporarily) include this library: https://github.com/agrublev/autocapitalize. It does however require jQuery, so might not be ideal on a mobile device. I've created this small piece of code which does the same thing just for words without the use of jQuery. It can ofcourse be extented to also include other cases.

The example below also capitalizes the words initially on page ready, instead of just on the 'keyup' event. I've tested the code on several devices and haven't gotten an error. But feel free to comment if something doesn't work or you feel something can be done better.

Note that the 'domReady' function I added works for IE9 and up. Please see this if you require support for an older version.

// Create one global variable var lib = {};  (function ( lib ) {    lib.autocapitalize_element = function (element) {     var val = element.value.toLowerCase();     var split_identifier = " ";     var split = val.split(split_identifier);     for (var i = 0; i < split.length; i ++) {       var v = split[i];       if ( v.length ) {           split[i] = v.charAt(0).toUpperCase() + v.substring(1);       }     };     val = split.join(split_identifier);     element.value = val;   }    lib.autocapitalize_helper = function(element) {     element.onkeyup = function(e) {       var inp = String.fromCharCode(e.keyCode);       if (/[a-zA-Z0-9-_ ]/.test(inp)) {         lib.autocapitalize_element(element);       }     };   }    lib.autocapitalize = function() {     var elements = document.querySelectorAll("input[autocapitalize], textarea[autocapitalize]");     for(var i = 0; i < elements.length; i++) {       lib.autocapitalize_helper(elements[i]);       lib.autocapitalize_element(elements[i]);     }   }    lib.domReady = function(callback) {     document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback);   }; }( lib ));   // This function gets called when the dom is ready. I've added it to the lib variable now because I dislike adding global variables, but you can put it anywhere you like. lib.domReady(function() {   lib.autocapitalize(); }); 
like image 183
Daan van Hulst Avatar answered Oct 04 '22 11:10

Daan van Hulst