2

I have this small problem with a website I'm designing. It's fairly over, but I think the jQuery is the problem here.

The code is as follows:

<img src="files/register_page/upload_photo/body.png" id="upload">
<input type="file" name="file_upload" id="file_upload" style="visibility:hidden;">

And the jQuery is the following, in the part of the document:

$(document).ready( function(){
      $("#upload").click( function(){
          $('#file_upload').click();
      });
    });

However, upon clicking the img, nothing happens, where a file upload dialog should pop up. Please, if you need any more information or something, let me know. If not, what could the problem be here? I'm using jQuery 1.8.0.

Jose Salvatierra
  • 2,407
  • 6
  • 21
  • 41

1 Answers1

5

Using HTML5 label element:

<label for="file_upload"><img src="files/register_page/upload_photo/body.png" id="upload"></label>
<input type="file" name="file_upload" id="file_upload" style="visibility:hidden;">

Fiddle

Works in Chrome, IE and Opera but not FF.

Browsers tend to limit what you can do with input type="file". The label element redirects the focus to the input with the id property equal to its for property, so this is an workaround to trigger the invisible element.


Modern browsers have alleviated a good part of those restrictions though, so you can trigger the .click() without problem.

You may however, change the CSS hack to hide it without using display:none or visibility:hidden for back-compat with older browsers. Either

position:absolute; top:-100px;

Or

opacity:0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
width:0; height:0;

Can hide the element without using the display or visibility CSS properties.

Fiddle


Also, here's an workaround for the label element on FF, you can change the visibility:hidden by opacity:0 and:

$('#file_upload').focus(function() {
    $(this).click();
});

Fiddle. But this should be unnecessary if the primary script works fine.

Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166
  • This worked! Amazing, could you explain why it works like this? – Jose Salvatierra Aug 23 '12 at 17:41
  • Oh I see :P Have you got any suggestions on making it work for FF too? I think this could be important for many users ;/ – Jose Salvatierra Aug 23 '12 at 17:46
  • @jslvtr Yup, I'm trying some more hackish jQuery, let's see if I succeed in a min or two. – Fabrício Matté Aug 23 '12 at 17:50
  • @jslvtr This may seem a little awkward but, your original code seems to work fine on FF/Chrome/IE? [fiddle](http://jsfiddle.net/ult_combo/YZgDB/5/) – Fabrício Matté Aug 23 '12 at 17:53
  • @jslvtr In which browser? Anyway try changing the `visibility:hidden` by `opacity:0`, I posted the workaround for the label element in FF on my answer. By any chance, are these input elements added dynamically? – Fabrício Matté Aug 23 '12 at 18:08
  • I am getting an error in the last }); for both jscript snippets, and I don't know why. Maybe that is the reason it doesn't work? The error is unexpected token ILLEGAL. It works in no browser if I remove the – Jose Salvatierra Aug 23 '12 at 18:10
  • @jslvtr Exactly, syntax errors kill the script tag. Post the full code on http://jsfiddle.net or try to validate it at http://jshint.com and it'll show the syntax error. `=]` – Fabrício Matté Aug 23 '12 at 18:11
  • This is the full code: http://pastebin.com/mZW3g0md Now I'm not getting any errors, weirdly enough. – Jose Salvatierra Aug 23 '12 at 18:15
  • @jslvtr Also, you may have a problem with invisible white spaces, that's usually the cause of that bug. http://stackoverflow.com/a/4404547/1331430 Go pressing the arrow keys slowly by the end of the script and check if there aren't any invisible characters. `=]` – Fabrício Matté Aug 23 '12 at 18:16
  • It works now... This is so strange! I had been using focus instead of click after changing it from visibility:hidden to opacity:0, but now, with opacity:0 and click it is working. I shall check other browsers too and come back – Jose Salvatierra Aug 23 '12 at 18:17
  • Yup, I already checked `.click()` in FF/Chrome/IE/Opera. Browsers are slightly skeptic about what you can do with `input type="file"`, so polices may change in the future. Here's a [CSS+JS hack](http://www.shauninman.com/archive/2007/09/10/styling_file_inputs_with_css_and_the_dom) that also works cross-browser (but jQuery should suffice for now IMO). `=]` – Fabrício Matté Aug 23 '12 at 18:27
  • @jslvtr Here's more info why `display:none` and `visibility:none` didn't allow to trigger it in some browsers: [linked answer](http://stackoverflow.com/a/7302101/1331430). Seems like this restriction has been alleviated in modern browsers, but you may use one of those hacks (`position:abolute;top:-100px;`, `opacity:0, height:0` etc) to make it invisible without using display or visibility to support old browsers. – Fabrício Matté Aug 23 '12 at 18:39
  • Alright, added my final revision for now, comment if it bugs in any browser. `=]` – Fabrício Matté Aug 23 '12 at 19:03
  • It works perfectly in all browsers! Thank you very much for your time Fabricio :P I really appreciate it – Jose Salvatierra Aug 23 '12 at 19:09