Workaround for file input label click (Firefox)

17,693

Solution 1

thank you for this q&a... helped me out.

my variation of @marten-wikstrom's solution:

if($.browser.mozilla) {
  $(document).on('click', 'label', function(e) {
    if(e.currentTarget === this && e.target.nodeName !== 'INPUT') {
      $(this.control).click();
    }
  });
}

notes

  • using document.ready ($(function() {...});) is unnecessary, in either solution. jQuery.fn.live takes care of that in @marten-wikstrom's case; explicitly binding to document does in my example.
  • using jQuery.fn.on... current recommended binding technique.
  • added the !== 'INPUT' check to ensure execution does not get caught in a loop here:

    <label>
      <input type="file">
    </label>
    

    (since the file field click will bubble back up to the label)

  • change event.target check to event.currentTarget, allowing for initial click on the <em> in:

    <label for="field">click <em>here</em></label>
    
  • using the label element's control attribute for cleaner, simpler, spec-base form field association.

Solution 2

I came up with a feasible workaround:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        $("label").click(function () {
            $("#input").click();
        });
    });
</script>
<label for="input">Label</label><input type="file" id="input"/>

Quite strange that FF allows you to simulate a click on a file input. I thought that was considered a security risk...

UPDATE: This is a generic workaround:

<script type="text/javascript">
    $(function () {
        if ($.browser.mozilla) {
            $("label").live("click", function (event) {
                if (event.target == this) {
                    $("#" + $(this).attr("for")).extend($("input", this)).first().click();
                }
            });
        }
    });
</script>

Solution 3

The file-selection dialog can be triggered in all browsers by the click() event. An unobtrusive solution to this problem could look like that:

$('label')
    .attr('for', null)
    .click(function() {
        $('#input').click();
    });

Removing the for attribute is important since other browsers (e.g. Chrome, IE) will still ratify it and show the dialog twice.

I tested it in Chrome 25, Firefox 19 and IE 9 and works like a charm.

Solution 4

A couple problems arise when using the jQuery browser detection, most notably the anti-pattern of using browser detection rather than feature detection, in addition to the fact that 1.9+ doesn't provide that functionality.

Perhaps, then, the solution I arrived at is a bit hypocritical, but it worked well and seems to adhere to most best practices today.

First, ensure you're using Paul Irish's conditional classes. Then, use something like:

  if($("html").hasClass("ie")) {
    $("label").click();
  } else {
    $("input").click();
  }

Otherwise, I found the event would be double-fired in browsers such as Chrome. This solution seemed elegant enough.

Solution 5

A work around when you don't need/want to have the input box (like image upload) is to use opacity: 0 in the element and use pointer-events: none; in the label. The solution is really design specific but maybe should work for someone who comes to this. (until now the bug doesn't been fixed)

http://codepen.io/octavioamu/pen/ByOQBE

Share:
17,693
Mårten Wikström
Author by

Mårten Wikström

Updated on June 04, 2022

Comments

  • Mårten Wikström
    Mårten Wikström almost 2 years
    <label for="input">Label</label><input type="file" id="input"/>
    

    In Firefox 7 it is not possible to trigger the open file dialog by clicking on the label.

    This SO question is very similar but that's green checked with it's a bug in FF. I'm looking for a workaround.

    Any ideas?

  • Max Allan
    Max Allan over 12 years
    But still I thinks it's little stupid that it don't work with the normal <label for="input">........
  • Mårten Wikström
    Mårten Wikström over 12 years
    Nothing happens when I click on the label in Firefox. Even if I put the label element after the input element. Did I miss something?
  • honk31
    honk31 almost 11 years
    just want to give an update and my thoughts, not meant to be mr. knowitall ;) $.browser is obsolete since jquery 1.9. and jquery.on() on the document is kinda rude. try to narrow it down, closer to the element (performance). or why use the deligate variant anyways..? $("label[name=input]").on("click",function() {...}); should do the trick as well..
  • Pedro Luz
    Pedro Luz almost 11 years
    just a side note: after the release of jQuery 1.9+ u can only use $.browser.VENDOR if you include the jquery.migrate plugin. Or use something like modernizr for browser detection.
  • Dimitar Bonev
    Dimitar Bonev almost 11 years
    Note that this issue has been fixed in FF 22, so the script double opens the file dialog. I suggested the following script update, but oddly enough it was rejected by the reviewers, still the suggested script works properly. stackoverflow.com/review/suggested-edits/2481980