143

I need a solution to display open file dialog in HTML while clicking a div. The open file dialog box must open when the div is clicked.

I don't want to display the input file box as part of HTML page. It must be displayed in separate dialog, which is not a part of the web page.

Karol Selak
  • 4,248
  • 6
  • 35
  • 65
ArK
  • 20,698
  • 67
  • 109
  • 136

13 Answers13

91

    $("#logo").css('opacity','0');
    
    $("#select_logo").click(function(e){
       e.preventDefault();
       $("#logo").trigger('click');
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" id="select_logo">Select Logo</a> <input type="file" id="logo">

for IE add this:

$("#logo").css('filter','alpha(opacity = 0');
700 Software
  • 85,281
  • 83
  • 234
  • 341
Somwang Souksavatd
  • 4,947
  • 32
  • 30
  • 3
    Why do you return false in the #select_logo click handler? – Sethish Nov 18 '12 at 05:34
  • 4
    It wouldn't produce a 404 error, it would just try and navigate to the current page, with the # added at the end. Which would make the page jump to the top. So it's good to be there, just for a different reason :) – manavo Jan 09 '13 at 16:52
  • 3
    Though I haven't tested it enough, "visibility: hidden;" seems more compatible. In addition, despite the opacity: 0 a click event will trigger if the "invisible" element clicked, while visibility: hidden will not. – Aron Sep 21 '13 at 15:21
  • 1
    MDN indicates that `document.getElementById("logo").click()` is enough. They also show another way "Drag & Drop". https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications – Eric Jun 21 '18 at 11:56
  • 2
    You should convert this to normal Javascript, JQuery isnt logical to use on such a small project ^_^ – Mister SirCode Oct 11 '19 at 13:11
  • @Tay - Nah... I like to use good old JQuery on even the smallest projects ^_^ – Momoro Mar 26 '20 at 00:47
67

I dont't know why nobody has pointed this out but here's is a way of doing it without any Javascript and it's also compatible with any browser.


EDIT: In Safari, the input gets disabled when hidden with display: none. A better approach would be to use position: fixed; top: -100em.

EDIT 2: A different approach would be to use opacity: 0. The problem is that it can mess with the layout. I added some CSS to the example to illustrate the problem.


label {
    display: inline-block;
    background: #ddd;
    border: 1px outset #ccc;
    border-radius: .3em;
    padding: .3em 1em;
    margin: .5em;
}

label:active {
  border-style: inset;
}
<label>
  Using <code>position: fixed</code>
  <input type="file" style="position: fixed; top: -100%">
</label>

<label>
  Using <code>opacity: 0</code>
  <input type="file" style="opacity: 0">
</label>

If you prefer you can go the "correct way" by using for in the label pointing to the id of the input like this:

<label for="inputId">file dialog</label>
<input id="inputId" type="file" style="position: fixed; top: -100em">
JP de la Torre
  • 1,593
  • 18
  • 20
  • 6
    this works like charm, however, here are some recommendations: 1. `` tag should have `name` attribute; 2. if `for` attribute is specified, `` file tag will require a `id`. – Raptor Jul 23 '15 at 06:46
  • 9
    `Simplicity is the ultimate sophistication` – ncubica Oct 14 '15 at 03:44
  • 3
    great! it works like a charm even with a background image or making the label receive a click javascript triggered. Thanks! – Leo Nomdedeu Oct 14 '15 at 08:03
  • 2
    BTW, someone pointed one catch with this solution, in Safari, inputs hidden with `display: none` are disabled. The workaround is using a different approach to hide the input. I'll update the answer to reflect that. – JP de la Torre Oct 15 '15 at 18:42
  • 1
    @JPdelaTorre It would be way better if you were to use opacity: 0 instead to hide the input. – Adrian Jul 16 '19 at 22:40
  • @4dr14n31t0rTh3G4m3r You are absolutely right. I started using opacity lately and it is better. – JP de la Torre Jul 18 '19 at 01:54
  • It seems that this idea doesn't work anymore in the most modern browsers (just like how triggering `click()` doesn't work). Perhaps the new security requirements consider this to be an insecure method and prevents it from opening the file dialog. – ADTC Sep 24 '21 at 13:14
  • 1
    @ADTC I just tested it in Chrome, Firefox, Edge, and Opera to make sure, and it worked in all of them. I added a code snippet that can be run to test. – JP de la Torre Sep 25 '21 at 21:54
  • 1
    @JPdelaTorre thanks. Maybe I did something wrong and got confused. The code snippet is helpful. Thank you for that. – ADTC Sep 27 '21 at 07:42
58

Here is a nice one

Fine Uploader demo

It is an <input type='file' /> control itself. But a div is placed over that and css styles are applied to get that feel. Opacity of the file control is set to 0 so that it appears that the dialog window is opened when clicking on the div.

Ray Nicholus
  • 19,538
  • 14
  • 59
  • 82
rahul
  • 184,426
  • 49
  • 232
  • 263
  • 1
    is there a way to control the displayed files by javascript... say I wanted to open file dialog and just wanted file extension with .pdf to display.. – Ajax3.14 Feb 24 '12 at 21:40
  • 1
    @Ajax3.14 new browsers has the FileReader object, old browsers you gotta use the value and look for the file extension. – Vicary Jan 19 '13 at 11:22
  • 2
    @Ajax3.14 No need to use FileReader or parse extensions. Many browsers support the accept attribute on file inputs. This allows you to limit the file types displayed in the file browser dialog. Fine Uploader provides access to this functionality via the acceptFiles property of the validation option. See the [validation section of the options documentation](http://docs.fineuploader.com/branch/master/integrating/options/fineuploaderbasic.html#validation-option-properties) for more details. Note that the accept attribute is not supported in IE9 or earlier. – Ray Nicholus Jul 11 '13 at 03:00
  • 1
    how come this is good? this is a good practice at all? shouldnt be something like this: http://stackoverflow.com/a/18659941/915865? – Kat Lim Ruiz Sep 25 '13 at 19:27
  • 1
    @KatLimRuiz No, the answer you linked to is not a good solution. This will cause IE to throw an error if you end up submitting the associated form programmatically as well. – Ray Nicholus Oct 22 '13 at 21:48
  • 1
    As of version 5.9.0, Fine Uploader is, once again, 100% free (MIT license). – Ray Nicholus May 20 '16 at 17:15
50

Actually, you don't need all that stuff with opacity, visibility, <input> styling, etc. Just take a look:

<a href="#">Just click me.</a>
<script type="text/javascript">
    $("a").click(function() {
        // creating input on-the-fly
        var input = $(document.createElement("input"));
        input.attr("type", "file");
        // add onchange handler if you wish to get the file :)
        input.trigger("click"); // opening dialog
        return false; // avoiding navigation
    });
</script>

Demo on jsFiddle. Tested in Chrome 30.0 and Firefox 24.0. Didn't work in Opera 12.16, however.

Tigran Saluev
  • 3,351
  • 2
  • 26
  • 40
29

The simplest way:

#file-input {
  display: none;
}
<label for="file-input">
  <div>Click this div and select a file</div>
</label>
<input type="file" id="file-input"/>

What's important, usage of display: none ensures that no place will be occupied by the hidden file input (what happens using opacity: 0).

Karol Selak
  • 4,248
  • 6
  • 35
  • 65
18
  1. Put input element type="file" anywhere on page and hide it with style="display:none". Give an id to input element. e.g. id="myid".
<input type="file" style="display:none" id="myid"/>
  1. Chose any div, image, button or any element which you want to use to open file dialog box, set an onclick attribute to it, like this:
<a href="#" onclick="document.getElementById('myid').click()"/>
Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
Navin Giri
  • 181
  • 1
  • 5
  • 1
    This works very well. Here is a JSFiddle demonstrating the approach: https://jsfiddle.net/0x4ydrzv/ – jelhan May 19 '21 at 14:40
  • 1
    I came here specifically bc I wanted to open the dialog using JS. For me it's not obvious that you can call click on an input element. Thx! – Nils Dec 28 '21 at 16:40
  • 1
    However it does not seem to work if the user does not actually click on something. For example calling click in the console does not and calling click in onload does also not work. – Nils Dec 28 '21 at 16:44
14

This is what worked best for me (Tested on IE8, FF, Chrome, Safari).

#file-input {
  cursor: pointer;
  outline: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  overflow: hidden;
  filter: alpha(opacity=0); /* IE < 9 */
  opacity: 0;
}
.input-label {
  cursor: pointer;
  position: relative;
  display: inline-block;
}
<label for="file-input" class="input-label">
  Click Me <!-- Replace with whatever text or icon you wish to use -->
  <input type="file" id="file-input">
</label>

Explanation: I positioned the file input directly above the element to be clicked, so any clicks would either land on it or its label (which pulls up the upload dialog just as if you clicked the label itself). I had some issues with the button part of the default input sticking out of the side of the label, so overflow: hidden on the input and display: inline-block on the label were necessary.

Chris
  • 2,174
  • 28
  • 37
13

What if javascript is Turned Off on clients machine? Use following solution for all scenarios. You dont even need javascript/jQuery. :

HTML

<label for="fileInput"><img src="File_upload_Img"><label>
<input type="file" id="fileInput"></label>

CSS

#fileInput{opacity:0}  
body{
    background:cadetblue;
}

Explanation : for="Your input Id" . Triggers click event by default by HTML. So it by default triggers click event, no need of jQuery/javascript. If its simply done by HTML why use jQuery/jScript? And you cant tell if client disabled JS. Your feature should work even though JS is turned off.

Working jsFiddle (You dont need JS , jquery)

Pratik Joshi
  • 11,485
  • 7
  • 41
  • 73
12

First add in the head tags:

<script>
   function showDialog(openFileDialog) {
       document.getElementById(openFileDialog).click();
   }
   function fileName(openFileDialog) {
       return document.getElementById(openFileDialog).value;
   }
   function hasFile(openFileDialog) {
       return document.getElementById(openFileDialog).value != "";
   }
   function fileNameWithoutFakePath(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(fileName.lastIndexOf('\\') + 1);
   }
   function fakePathWithoutFileName(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(0, fileName.lastIndexOf('\\'));
   }
</script>

if you already have script tags, just add these functions above.

In your body or form tags adding:

<input type="file" style="display:none" id="yourDesiredOrFavoriteNameForTheNewOpenFileDialogInstance"/>

No matter where in your html, is just like that you've created a new instance of type OpenFileDialog class as global variable, whose name is the id of the element, no matter where in your code or xaml, but in your script or code, you can't type his name, and then read a property or call a function, because there are global functions that do those that are not defined in the element input type="file". You just have to give these functions the id of the hidden input type="file" which is the name of the OpenFileDialog instance as string.

To ease your life in creating open file dialogs instances to your html, you can make a function that does it:

function createAndAddNewOpenFileDialog(name) {
     document.getElementById("yourBodyOrFormId").innerHtml += "<input type='file' style='display:none' id='" + name + "'/>"
}

and if you want to remove open file dialog, then you can make and use the following function:

function removeOpenFileDialog(name) {
    var html = document.getElementById("yourBodyOrFormId").innerHtml;
    html = html.replace("<input type='file' style='display:none' id='" + name + "'/>", "");
    document.getElementById("yourBodyOrFormId").innerHtml = html;
}

but before you remove open file dialog, ensure that it exists by making and using the following function:

function doesOpenFileDialogExist(name) {
    return document.getElementById("yourBodyOrFormId").innerHtml.indexOf("<input type='file' style='display:none' id='" + name + "'/>") != -1
}

and if you don't want to create and add the open file dialogs in the body or form tags in the html, because this is adding hidden input type="file"s, then you can do it in script using the create function above:

function yourBodyOrFormId_onload() {
    createAndAddNewOpenFileDialog("openFileDialog1");
    createAndAddNewOpenFileDialog("openFileDialog2");
    createAndAddNewOpenFileDialog("openFileDialog3");
    createAndAddNewOpenFileDialog("File Upload");
    createAndAddNewOpenFileDialog("Image Upload");
    createAndAddNewOpenFileDialog("bla");
    //etc and rest of your code
}

Ensure that near your body or form tags, you added:

onload="yourBodyOrFormId_onload()"

You don't have to do this line above, if you did it already.

TIP: You can add to your project or website new JScript File, if you don't have yet, and in this file you can put all the open file dialog functions away from the script tags and the html or web form page, and use them in your html or web form page from this JScript file, but don't forget before to link the html or web form page to the JScript File of course. You can do it just by dragging the JScript file to your html page in the head tags. If your page is web form and not simple html, and you don't have head tags, then put it anywhere so that it can work. Don't forget to define global variable in that JScript File, whose value will be your body or form id as string. After you linked the JScript file to your html or web form page, you can onload event of your body of form, set the value of that variable to your body or form id. Then in the JScript File, you don't have to give to the document the id of the body or form of one page anymore, just give it the value of that variable. You can call that variable bodyId or formId or bodyOrFormId or any other name you want.

Good luck man!

7

Here is a solution I developed after I failed to find a good solution

let input = document.createElement("input");
input.type = "file";
input.setAttribute("multiple", true);
input.setAttribute("accept", "image/*");
input.onchange = function (event) {
    //
    console.log(this.files);
};
input.click();
Peter
  • 626
  • 6
  • 6
3

AFAIK you still need an <input type="file"> element, then you can use some of the stuff from quirksmode to style it up

Dan F
  • 11,958
  • 3
  • 48
  • 72
1

The only without <input type="file"> is by embedding a transparent flash movie over the div. You can then use a user generated click event (compliant with Flash 10 new security rules) to trigger a call to flash's FileReference.browse.

It offers an added dependency over the quirksmode way but in return you get alot more events (such as built in progress events).

Martijn Laarman
  • 13,476
  • 44
  • 63
0

May use

$('<input type="file" />').click()
Hamed Zakery Miab
  • 738
  • 2
  • 12
  • 34
  • in my case, this causes an automatic redirection to the same page where the original click event happened - making the whole page reload and lose all data previously entered in the page. – Muntasir Mar 30 '20 at 10:21