Hacker News new | ask | show | jobs
by megous 2865 days ago
You realize you don't need input field for file input in any of the modern browsers. Just capture the click event and create input field temporarily.

    let i = document.createElement('input');
    i.type = 'file';
    // other attributes if you like
    i.onselect = ev => {
      // ev.files contains selected files
    };
    i.click();
    i.remove();
No stupid styling hacks needed. At most you may need tabIndex on the <a> or <div> that represents the button for selecting files.

You can leave <input type=file> around if you want to submit data via <form> and not via XHR.

3 comments

>No stupid styling hacks needed.

You’ve just replaced them with stupid DOM hacks.

Not a hack, just regular API.

You clearly never implemented any of the above stupidity with file input styling and overlays and passthrough of events, and different unchangeable widths of file inputs you had to account for in various versions of browsers, and bugs in specific browser versions, and discontinuity in the input field clickable surface so part of the button is not clickable for no reason whatsoever to the user, so that everything works as expected in E6+IE7+IE8+IE9+FF1+Sfari,... to think it's even comparable on the hackiness scale.

That would have saved me a ton of effort if I had known that before getting started. Thanks, I'll keep that technique in mind for next time.
Please don't do this unless you also handle dragging files on it.
That's another issue easily solved by DnD API modern browsers implement. And should probably be done differently with regards to UX depending on whether the clicky part was a button, or a larger upload area.

Frankly, I don't find the original UX of dragging files onto an upload button all that intuitive. So instead I add drop functionality to a larger container in my apps. So if I have dialog that accepts files, users can drag files anywhere over the dialog and the dialog highlights that it accepts drops while dragging.