10

We want to reduce the number of steps it takes for a user to upload a file on our website; so we're using jQuery to open and postback files using the below markup (simplified):

<a onclick="$('#uplRegistrationImage').click();">
    Change profile picture
</a>

<!-- Hidden to keep the UI clean -->
<asp:FileUpload ID="uplRegistrationImage" 
                runat="server" 
                ClientIDMode="static"
                Style="display:none"
                onchange="$('#btnSubmitImage').click();"    />

<asp:Button runat="server" 
            ID="btnSubmitImage" 
            ClientIDMode="static" 
            Style="display:none" 
            OnClick="btnSubmitImage_OnClick" 
            UseSubmitBehavior="False" />

This works absolutely fine in Firefox and Chrome; opening the file dialog when the link is clicked and firing the postback when a file is selected.

However in IE9 after the file upload has loaded and a user has selected a file; insteaed of the OnChange working I get a "SCRIPT5 Access is denied" error. I've tried setting an arbitrary timeout, setting intervals to check if a file is given to no avail.

There are a number of other questions relating to this; however none appear to have a decent answer (One said set the file dialog to be transparent and hover behind a button!)

Has anyone else resolved this? Or is it absolutely necessary that I provide a button for IE users?

Luke Merrett
  • 5,394
  • 6
  • 36
  • 66

4 Answers4

13

For security reasons, what you are trying to do is not possible. It seems to be the IE9 will not let you submit a form in this way unless it was an actual mouse click on the File Upload control that triggers it.

For arguments sake, I was able to use your code to do the submit in the change handler, but it worked only when I clicked the Browse button myself. I even set up polling in the $(document).ready method for a variable set by the change handler that indicates a submission should be triggered - this didn't work either.

The solutions to this problem appear to be:

  1. Styling the control in such a way that it sits behind a button. You mentioned this in your question, but the answer provided by Romas here In JavaScript can I make a "click" event fire programmatically for a file input element? does in fact work (I tried in IE9, Chrome v23 and FF v15).
  2. Using a Flash-based approach (GMail does this). I tried out the Uploadify demo and it seems to work quite nicely.

Styling a File Upload:

http://www.quirksmode.org/dom/inputfile.html

http://www.shauninman.com/archive/2007/09/10/styling_file_inputs_with_css_and_the_dom

References:

jQuery : simulating a click on a <input type="file" /> doesn't work in Firefox?

IE9 file input triggering using Javascript

getting access is denied error on IE8

Community
  • 1
  • 1
nick_w
  • 13,990
  • 2
  • 47
  • 67
  • 1
    Perfect answer cheers Nick. We ended up using [FineUploader](http://fineuploader.com/) with a HTTP Handler; achieving roughly the same solution with a lot more boiler plate code. – Luke Merrett Nov 15 '12 at 09:40
  • Weird, this jsfiddle seems to prove this answer wrong: http://jsfiddle.net/NkycS/27/ The file input click is triggered via JS, and so's the submit, and it works in IE9. Wonder if I'm missing something. – RwwL Dec 06 '12 at 23:18
  • Yep, I was missing something: my file input didn't have a name attribute on it. As soon as I add one, I do get the access denied error. http://jsfiddle.net/NkycS/32/ – RwwL Dec 07 '12 at 17:08
3

Hey this solution works. for download we should be using MSBLOB

$scope.getSingleInvoicePDF = function(invoiceNumberEntity) {
   var fileName = invoiceNumberEntity + ".pdf";
   var pdfDownload = document.createElement("a");
   document.body.appendChild(pdfDownload);

   AngularWebService.getFileWithSuffix("ezbillpdfget",invoiceNumberEntity,"pdf" ).then(function(returnedJSON) {
       var fileBlob = new Blob([returnedJSON.data], {type: 'application/pdf'});
       if (navigator.appVersion.toString().indexOf('.NET') > 0) { // for IE browser
           window.navigator.msSaveBlob(fileBlob, fileName);
       } else { // for other browsers
           var fileURL = window.URL.createObjectURL(fileBlob);
           pdfDownload.href = fileURL;
           pdfDownload.download = fileName;
           pdfDownload.click();      
       }
   });
};
Shankar Shastri
  • 1,031
  • 10
  • 17
2

This solution looks like it might work. You'll have to wrap it in a <form> and get it to post in the jquery change handler, and probably handle it in form_load using the __eventtarget or and iframe or whatever it is that web forms uses, but it allows you to select a file, and by submitting the form, it should send it. I can't test it however, since I don't have an environment set up at home.

http://jsfiddle.net/axpLc/1/

<a onclick="$('#inputFile').click();">
    Change profile picture
</a>
<div id='divHide'>

    <input id='inputFile' type='file' />

</div>


$('#inputFile').change(function() { alert('ran'); });

#divHide { display:none; }
NibblyPig
  • 46,891
  • 62
  • 180
  • 311
0

Well, like SLC stated you should utilize the <Form> tag.

First you should indicate the amount of files; which should be determined by your input fields. The second step will be to stack them into an array.

<input type="file" class="upload" name="fileX[]"/>

Then create a loop; by looping it will automatically be determined based on the input field it's currently on.

 $("input[@type=file]:nth(" + n +")")

Then you'll notice that each file chosen; will replace the input name to the file-name. That should be a very, very basic way to submit multiple files through jQuery.

If you'd like a single item:

$("input[@type=file]").change(function(){
   doIt(this, fileMax);
 });

That should create a Div where the maximum file found; and attaches to the onEvent. The correlating code above would need these also:

 var fileMax = 3;
 <input type="file" class="upload" name="fileX[]" />

This should navigate the DOM parent tree; then create the fields respectively. That is one way; the other way is the one you see above with SLC. There are quite a few ways to do it; it's just how much of jQuery do you want manipulating it?

Hopefully that helps; sorry if I misunderstood your question.

Greg
  • 10,695
  • 2
  • 41
  • 73