23

I'm building a mobile version of my site which has a file upload facility, accessed via an 'Upload Button'

I would like to hide the button from iPhone users, as the control just appears greyed out - is this possible?

I don't really want to detect the iPhone; I feel it would be much better to detect the feature - making it start to work automatically should Apple enable this (or the phone is Jailbroken, or something...)

Ben Robinson
  • 1,602
  • 3
  • 16
  • 30

7 Answers7

5

Function to check whether input[type=file] is implemented:

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

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • I get the same result using this on Firefox and Mobile Safari ? – Nasreddine Nov 10 '11 at 10:28
  • That is, true? If it's true, `input[type=file]` IS supported, but not implemented. See my updated answer. – Rob W Nov 10 '11 at 10:30
  • Returns true :-( - even tried adding it to the dom and waiting before testing it's type – Ben Robinson Nov 10 '11 at 10:34
  • @Rob: iPhone returns false, but so does chrome - elem.value='Test'; doesn't throw an error! input[file=type] is implemented! – Ben Robinson Nov 10 '11 at 10:44
  • @BenRobinson I have made some small modifications. Try this fiddle: http://jsfiddle.net/8EqEE/ – Rob W Nov 10 '11 at 10:52
  • @RobW: Still no joy - WebKit doesn't seem to mind setting the value - no error is thrown on iPhone or Chrome and returns true! – Ben Robinson Nov 10 '11 at 10:59
  • 1
    On iPhone iOS 5 this doesn't work, but elem.disabled is set to true. Add this for iOS support. – Zymotik Sep 19 '12 at 17:12
  • On IE10 for Windows Phone 8 this does not work aswell. The element reports that it is not disabled, the value cannot be set, no error is thrown and typical properties of input file (e.g. elem.files) are present – Marcus Krahl Aug 15 '14 at 08:23
4

UPDATE: This is now part of Modernizr now.

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;
Gavin Brock
  • 5,027
  • 1
  • 30
  • 33
  • It also checks the navigator.userAgent for certain browsers that are known to give false positives. Relevant code: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/forms/fileinput.js – Luke Jan 14 '14 at 23:59
2

Create a <input type="file"> and check to see if it's 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.

ESV
  • 7,620
  • 4
  • 39
  • 29
0

A hybrid of the value based error checking (try/catch) plus a check for disabled seems to give good coverage across all the PC and mobile browsers we tested.

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 could change the logic order around if you prefer a different flow.

Fiddle: http://jsfiddle.net/BRk5J/

roBman
  • 91
  • 1
0

Update to Rob W's solution above that supports iOS 5 + iOS 6 Beta too. (Causing an exception isn't what I would recommend, but this 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;
        }
    }
Zymotik
  • 6,412
  • 3
  • 39
  • 48
0

Note that I haven't tested this, so I'm not sure if it would work. This is basically how you test support for HTML5 input types (e.g. <input type="color" />). But you can try it:

function upload_supported() {
  var file_input = document.createElement("input");
  file_input.setAttribute("type", "file");
  return file_input.type !== "text";
}

This is based on the browser's behavior of resetting the type attribute to text when it encounters an unknown input type. However, since you say that it appears grayed out, it would mean that it's not unknown, per se.

Felix
  • 88,392
  • 43
  • 149
  • 167
-1

I too have been searching for a solution to this problem. It is not as simple as the solutions suggested here already. Some of the browsers claim to support certain types but some of those types have been disabled due to incompleteness. So what ends up happening is that when you return InputElement.type it may return as the "file" type or "tel" or "number" but it is still treated by the browser as "text".. Sadly I do not think you can do this atm unless you can talk the browser devs into fixing it so that the disabled types return as text..

as an added note IE returns all unsupported types as text. I have tested this with lastest versions of Chrome and FF aswell. Chrome "lies" about support for numbers, telphone types i know so far and FF also returns tel when it is not supported. I am sure this happens with other types as well.

eff
  • 1