How to overcome WhatWG/W3C/Chrome version 33.0.1750.146 "regression bug" with <input type="number"/> fields How to overcome WhatWG/W3C/Chrome version 33.0.1750.146 "regression bug" with <input type="number"/> fields google-chrome google-chrome

How to overcome WhatWG/W3C/Chrome version 33.0.1750.146 "regression bug" with <input type="number"/> fields


I've solved this with the following code:

function checkForInputTypeNumberBug(){  var dummy = document.createElement('input');  try {    dummy.type = 'number';  } catch(ex){    //Older IE versions will fail to set the type  }  if(typeof(dummy.setSelectionRange) != 'undefined' && typeof(dummy.createTextRange) == 'undefined'){    //Chrome, Firefox, Safari, Opera only!    try {      var sel = dummy.setSelectionRange(0,0);    } catch(ex){      //This exception is currently thrown in Chrome v33.0.1750.146 as they have removed support      //for this method on number fields. Thus we need to revert all number fields to text fields.      $('input[type=number]').each(function(){        this.type = 'text';      });    }  }}$(document).ready(function(){  checkForInputTypeNumberBug();});

I've made it a standalone function as I have cases where the fields are loaded via AJAX and I need to be able to call the function on the fly.

This code handles older IE versions where attempting to set the type will fail as well as handle the exception in Chrome (on a dummy element) so that pages can overcome this behavior change.

Update: As per @Andy E's suggestion around using the inputmode attribute (currently unsupported) I've created a bug to try and prioritize the implementation of inputmode before user agents remove the selection APIs: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26695


Depending on the use case, there may be a more appropriate (albeit elaborate) workaround. For instance, in order to add text at the current position of the cursor, you can do the following (tested in Chrome):

var len, pre, post,    // Currently focused element    a = document.activeElement,    // Get current selection    s = window.getSelection();// Delete any existing contentss.deleteFromDocument();// Keep moving selection backward until the length stops increasingdo {    len = String(s).length;    s.modify('extend', 'backward', 'line');}while (String(s).length !== len);// Store the selection, then delete itpre = String(s);s.deleteFromDocument();// Keep moving selection forward until the length stops increasingdo {    len = String(s).length;    s.modify('extend', 'forward', 'line');}while (String(s).length !== len);// Store the selection, then delete itpost = String(s);s.deleteFromDocument();// Recreate the contents with the new text addeda.setAttribute('value', a.defaultValue);a.value = pre + txt + post;// Move the selection to after the new texta.select();s = window.getSelection();s.collapseToEnd();while (len-- > 0)    s.modify('move', 'backward', 'character');

There are limitations to this approach that might need even more elaborate solutions, too, such as when a different value is returned than text is selected (which may be the case for arabic domain names in a type="email" input, for example).

Sadly, there's a bug that prevents this workaround from working in Firefox/Gecko, but at least Firefox still allows Selection API on <input type="email">.