Detect if <input type = "file" / "> is supported
I am creating a mobile version of my site on which there is a file upload tool, accessed through the "Download" button
I would like to hide the button from iPhone users, since the control just appears in gray - is this possible?
I really don't want to detect an iPhone; I feel that it would be much better to detect this feature - make it work automatically if Apple turns it on (or a Jailbroken phone or something else ...)
Function for checking implementation of input[type=file] :
function isInputTypeFileImplemented() { var elem = document.createElement("input"); elem.type = "file"; if (elem.disabled) return false; try { elem.value = "Test"; // Throws error if type=file is implemented return elem.value != "Test"; } catch(e) { return elem.type == "file"; } } Fiddle: http://jsfiddle.net/8EqEE/9
UPDATE: now it is part of Modernizr .
There is a pull request for modernizr that seems to work. Essentially, it just checks:
var elem = document.createElement('input'); elem.type = 'file'; return !elem.disabled; Create <input type="file"> and check if it is disabled.
function isFileUploadImpossible() { var el = document.createElement("input"); el.setAttribute("type", "file"); return el.disabled; } Tested in iOS 4.2.1, Android 2.3.4, Chrome 17, Firefox 11, IE7.
Please note that I have not tested this, so I am not sure if this will work. This is basically how you test support for HTML5 input types (for example, <input type="color" /> ). But you can try:
function upload_supported() { var file_input = document.createElement("input"); file_input.setAttribute("type", "file"); return file_input.type !== "text"; } This depends on the behavior of the browser when resetting the type attribute to text when it encounters an unknown input type. However, since you say that it appears gray, it will mean that it is not unknown as such.
Value-based hybrid error checking (try / catch) plus checking for outages seems to provide good coverage for all tested PCs and mobile browsers.
alert((function isInputTypeFileImplemented(){ var elem; try { elem = document.createElement("input"); elem.type = "file"; } catch(e) { return -1; // type=file is not implemented } try { elem.value = "Test"; if (elem.value == "Test") { return -2; // type=file should throw an error on line above } else { if (elem.disabled) { return -3; // type=file disabled in iOS < 6 } else { return true; } } } catch(e){ return true; // type=file implemented correctly } })()) NOTE. You can change the logical order if you prefer a different thread.
Fiddle: http://jsfiddle.net/BRk5J/
Upgrading to Rob W's solution above that supports iOS 5 + iOS 6 beta. (Throwing an exception is not what I would recommend, but it works):
function isInputTypeFileImplemented(){ var elem = document.createElement("input"); elem.type = "file"; try { elem.value = "Test"; //If type=file is implemented, this would throw an if (elem.disabled) { return false; } else { return true; } } catch(e){ return false; } } I was also looking for a solution to this problem. It is not as simple as the solutions offered here. Some of the browsers claim to support certain types, but some of these types have been disabled due to incompleteness. So what happens when you return InputElement.type, it can be returned as a “file” or “tel” or “number”, but it is still treated by the browser as “text”. Unfortunately, I don’t think you can do this atm if you cannot talk to the developers of the browser about fixing it so that disabled types are returned as text.
as an added note, IE returns all unsupported types as text. I tested this with the latest versions of Chrome and FF. Chrome "lies" about support for numbers, phone types that I still know, and FF also returns tel when it's not supported. I am sure that this is happening with other types.