jQuery Custom File Upload Input: from the book Designing with Progressive Enhancement
Posted by Scott on 07/12/2010
As websites expand content-sharing and collaboration features, users are electing to upload more and more files—photos, videos, documents, even secure data—via web applications to store them in “cloud”-based systems rather than locally on their computers. The HTML
input element with a
type="file" attribute gives web developers a native control to handle this file upload functionality. But browsers offer almost no control over how file inputs are presented visually, making it difficult to incorporate them into a uniform interface design.
This widget is one of the 12 fully-accessible, project-ready, progressive enhancement-driven widgets we created to accompany our book, Designing with Progressive Enhancement. (Purchasers of the book can access all twelve widgets immediately).
A quick demo
Before we get into the mechanics of the custom-styled input control, here's a demo that highlights key features. The input box and buttons have distinct, custom visual style; and when the user selects a file, the custom input updates to display the file name and an icon representing the file's extension. To see the feedback in action, browse and choose any file. (FYI: The demo is completely non-functional—i.e., it will not upload files to any server. )
Note: If you click the "view low-bandwidth" link, just remember that you'll need to click it again to view the enhanced version of this site on future views.
How does this widget actually work?
The approach we've used piggybacks on top of the native file
input: The widget creates a custom-styled file control using
input's opacity to zero and dynamically position it invisibly between the cursor and the custom control. The user actually interacts only with the native
input without knowing it. The following infographic demonstrates the concept:
In addition, the widget script applies custom styling, and parses the filename's extension to recognize the file format so it can display a file-specific icon (the CSS includes a generic file icon and several specific icons—image, multimedia, zip folder—which are easily customizable).
The best part of this approach is that we get great accessibility support for keyboard users and those with disabilities automatically. Since we’re always using the native file input control, we can leverage all the functionality and accessibility that it provides—the custom file input is really a visual feedback mechanism only. And though the native
input is invisible, it’s still fully keyboard-accessible, so there’s no need to add any additional accessibility features or ARIA attributes. (We do, however, add one ARIA attribute to the custom widget to hide it from screen readers, since it’s relevant only to sighted users.)
A tip of the hat
How do I use it?
To use this script in your page, you'll need to download and reference both jQuery and jQuery.fileinput.js, as well as the associated CSS and images for the control (download instructions are found below), and call the
customFileInput method on any list element on the page. For example, to create a custom input control from a
input element with an
file, find it using jQuery and call the
customFileInput method on it:
Note: be sure to use jQuery's
$(document).ready event to wait until the DOM is ready before running the script above.
Also, you can disable and enable the control by calling either
$('#file').trigger('enable'); on the native input. Once disabled, the custom control will be styled to appear disabled as well. If the input is disabled at load, the custom control will naturally inherit that state, so you won't need to call the "disable" method when you first create the control.
That's all there is to it!
If you'd like to learn more, we explain in detail how this widget works under the covers and how to apply these principles in different interactions or more complex scenarios in our book, Designing with Progressive Enhancement.
Download (and help us improve) the code
The custom file input plugin code is open source and available in a git repository, jQuery-Custom-File-Input. If you think you can help on a particular issue, please submit a pull request and we'll review it as soon as possible.
If you've already purchased Designing with Progressive Enhancement, you can download all twelve widgets at the code examples download page.