views:

16817

answers:

10

I'd like to make a click event fire on an <input type="file"> tag programmatically.

Just calling click() doesn't seem to do anything or at least it doesn't pop up a file selection dialog.

I've been experimenting with capturing events using listeners and redirecting the event, but I haven't been able to get that to actually perform the event like someone clicked on it.

+5  A: 

You cannot do that in all browsers, supposedly IE does allow it, but Mozilla and Opera do not.

When you compose a message in GMail, the 'attach files' feature is implemented one way for IE and any browser that supports this, and then implemented another way for Firefox and those browsers that do not.

I don't know why you cannot do it, but one thing that is a security risk, and which you are not allowed to do in any browser, is programmatically set the file name on the HTML File element.

Jason Bunting
Drat. Well I certainly understand that it's exploitable. Is this documented anywhere? I guess it would be implemented by each browser?
Updated my answer to be more correct than previous answer - the gist is the same, but clarification should help a bit. This guy ran into the same problem: http://bytes.com/forum/thread542877.html
Jason Bunting
A: 

I hear it's possible but very difficult to do this on Windows for IE only. But as Jason said, it's that way for a reason.

.If you really want that kind of functionality, use a signed applet

Eric Wendelin
A: 

I haven't tried this but you might be able to do it with jQuery.

$('input[type=file]:first').trigger('click')

The reason you can't just do .click() is that this is only supported for inputs of type button.

[EDIT] Ordinarily I'd test this before posting, but I've got to run and pick up my daughter. If it doesn't work, leave a comment and I'll delete my answer.

[EDIT] The following works in Safari, but not Firefox. Didn't test IE as not working in Firefox is probably a deal breaker. Probably need to find a different way of doing it.

<html>
<head>
    <script type="text/javascript" src="jquery-1.2.6.js"></script>
    <script type="text/javascript">
       function clickFileUpload() {
          $('input[type=file]:first').trigger('click');
     }
    </script>
</head>
<body>
<form action="test_submit" method="POST" accept-charset="utf-8">
    <p>
     <input type="file">
    </p>
    <p>
     <input type="button" onclick="clickFileUpload();" value="Get File" />
    </p>
</form>

</body>

tvanfosson
This probably works okay in browsers that support this for the HTML File element, but Firefox and Opera don't at this time, AFAIK.
Jason Bunting
A: 

See my post here:
http://stackoverflow.com/questions/143747/is-it-possible-to-trigger-a-links-or-any-elements-click-event-through-javascript#143771

Chris MacDonald
Chris, you cannot do it in Firefox or Opera though, regardless. This applies specifically to the HTML File element.
Jason Bunting
Do you mean you cannot fire that on the input type=file?
Chris MacDonald
+1  A: 

There are ways to redirect events to the control but don't expect to be able to easily fire events to the fire control yourself as the browsers will try to block that for (good) security reasons.

If you only need the file dialog to show up when a user clicks something, let's say because you want better looking file upload buttons, then you might want to take a look at what Shaun Inman came up with.

I've been able to achieve keyboard triggering with creative shifting of focus in and out of the control between keydown, keypress & keyup events. YMMV.

My sincere advice is to leave this the alone, because this is a world of browser-incompatibility-pain. Minor browser updates may also block tricks without warning and you may have to keep reinventing hacks to keep it working.

Borgar
A: 

I was researching this a while ago because I wanted to create a custom button that would open the file dialog and start the upload immediately. I just noticed something that might make this possible - firefox seems to open the dialog when you click anywhere on the upload. So the following might do it:

  1. Create a file upload and a separate element containing an image that you want to use as the button
  2. Arrange them to overlap and make the file element backgroud and border transparent so the button is the only thing visible
  3. Add the javascript to make IE open the dialog when the button/file input is clicked
  4. Use an onchange event to submit the form when a file is selected

This is only theoretical since I already used another method to solve the problem but it just might work.

What other method?
Marcus Downing
+8  A: 

I have been searching for solution to this whole day. And these are the conclusions that I have made:

  1. For the security reasons Opera and Firefox don't allow to trigger file input.
  2. The only convenient alternative is to create a "hidden" file input (using opacity, not "hidden" or "display: none"!) and afterwards create the button "bellow" it. In this way the button is seen but on user click it actually activates the file input.

Hope this helps! :)

<div style="display: block; width: 100px; height: 20px; overflow: hidden;">
<button style="width: 110px; height: 30px; position: relative; top: -5px; left: -5px;"><a href="javascript: void(0)">Upload File</a></button>
<input type="file" id="upload_input" name="upload" style="font-size: 50px; width: 120px; opacity: 0; filter:alpha(opacity: 0);  position: relative; top: -40px;; left: -20px" />
</div>
Romas
this solution works great. Not sure why it's been overlooked and un-uprated. It's not *exactly what the question asks for, but it's a great work around. Have you found it to be incompatible with any browsers? I don't have the time to work my way through all 10+ flavors of relevant ones to test on.
Dr.Dredel
This solution is awesome. Thanks!!!
SKR
A: 

For those who understand that you have to overlay an invisible form over the link, but are too lazy to write, I wrote it for you. Well, for me, but might as well share. Comments are welcome.

HTML (Somewhere):

<a id="fileLink" href="javascript:fileBrowse();" onmouseover="fileMove();">File Browse</a>

HTML (Somewhere you don't care about):

<div id="uploadForm" style="filter:alpha(opacity=0); opacity: 0.0; width: 300px; cursor: pointer;">
    <form method="POST" enctype="multipart/form-data">
        <input type="file" name="file" />
    </form>
</div>

JavaScript:

function pageY(el) {
    var ot = 0;
    while (el && el.offsetParent != el) {
        ot += el.offsetTop ? el.offsetTop : 0;
        el = el.offsetParent;
    }
    return ot;
}

function pageX(el) {
    var ol = 0;
    while (el && el.offsetParent != el) {
        ol += el.offsetLeft ? el.offsetLeft : 0;
        el = el.offsetParent;
    }
    return ol;
}

function fileMove() {
    if (navigator.appName == "Microsoft Internet Explorer") {
        return; // Don't need to do this in IE. 
    }
    var link = document.getElementById("fileLink");
    var form = document.getElementById("uploadForm");
    var x = pageX(link);
    var y = pageY(link);
    form.style.position = 'absolute';
    form.style.left = x + 'px';
    form.style.top = y + 'px';
}

function fileBrowse() {
    // This works in IE only. Doesn't do jack in FF. :( 
    var browseField = document.getElementById("uploadForm").file;
    browseField.click();
}
McTrafik
A: 

It's true that you can't programmatically click on input[type=file]. That's why for file upload people either use flash or overlay input field solution suggested here. The challenge with that one is changing the default cursor to something else. By default, cursor for file field is different, and you can't change it. Unless someone proves me wrong here? Anyone?

MAP
A: 

Try this solution: http://code.google.com/p/upload-at-click/

Vitaly Fadeev