Purpose: Allows a user to upload multiple files to a web form with a single process.

Category: Forms / File Upload

Related jiras:

Process Phase:

    • UXI JIRA Created (insert link above)
    • Component Specification draft complete
    • UXI code review complete
    • Reconcile with UIM and KRAD existing designs
    • Conduct user testing (if needed)
    • Routed for review with Kuali UX Working Group and UX/KRAD Working Group
    • Reviewed with KAI
    • Rice JIRA Created (in KULRICE Project)
    • KRAD Implementation complete
    • Component released (insert rice release version below)

Version: 1.0

Description

The Batch File Upload component allows users to upload multiple files of various document types to a web form. This component would be used in situations where a user is expected to upload multiple files to a web form. Rather than uploading each file individually, this component will allow the user to select multiple files and upload all with a single action. This feature will be particularly useful to admin data screens, but should have universal appeal to all types of users.

Prototype file viewable on our test pages site.

 

Usage

Interaction/Behavior of component

This component will have the following user interaction points:

  • Select local files for inclusion in a batch upload process. This can happen one of two ways:
    • Using the operating system file browser to select local files.
    • Drag and drop local files onto a 'target area' of the component.
  • Execute a batch upload of all selected files with a single action.
  • View a listing of uploaded files.
  • Add and edit metadata associated with each individual file (e.g. add comments about a particular file, specify what type of document, etc...).
  • Download previously uploaded files.
  • Remove files that have previously been uploaded

When to use this component

This component is to be used in situations when the user is required to upload multiple files to a web form.

Problem being solved

On occasion, users are expected to upload multiple files to a web form. Using the standard file input field (<input type="file">) only allows the user to upload one file at a time. The Batch File Upload component will streamline the process of uploading multiple files to a web form.

Demos

This component relies on the jQuery Multiple File Upload plugin, which has been approved by Kuali.

HTML

The following is basic markup for the above example.

<form action="#" method="post" enctype="multipart/form-data">
    <div class="container">
        <div class="clearfix">
            <div>
                <h1>Multiple file upload example</h1>
            </div>
        </div>
        
        <table id="file_list" role="presentation" class="table table-condensed" aria-live="polite" tabindex="-1">
            <caption>This tables lists all uploaded files, their file size, and available actions.</caption>
            <thead>
                <tr class="active">
                    <th scope="col">Filename</th>
                    <th scope="col">Size</th>
                    <th scope="col">Title</th>
                    <th scope="col">Details</th>
                    <th scope="col">Actions</th>
                </tr>
            </thead>
            <tbody id="files"></tbody>
            <tfoot>
                <tr class="active">
                    <td colspan="3">
                        <span id="file_totals" tabindex="0"></span>
                    </td>
                    <td colspan="2">
                        <span class="btn btn-primary btn-sm fileinput-button pull-right" role="button" tabindex="0" onclick="show_file_list_click()" onKeyUp="show_file_list_keyup()" aria-pressed="false">
                            <i class="glyphicon glyphicon-plus"></i>
                            <span>Select files...</span>
                        </span>
                        <input id="fileupload" type="file" name="files[]" multiple class="fade" />
                    </td>
                </tr>
            </tfoot>
        </table>
        
        <div class="uif-drag-drop-area" id="uif-mfu">
            <p>Drop files here</p>
        </div>
    </div>
</form>

CSS

Stylesheet dependencies:

  • Bootstrap 3+
  • jquery.fileupload.css

There are a few more custom CSS rules that we use, which will eventually go into the master CSS file.

.uif-drag-drop-area {
    min-height: 200px;
    background: #f2f2f2;
    padding: 12px;
    border: 2px dashed #ccc;
}

.uif-drag-drop-area p {
    font-size: 150%;
    text-transform: uppercase;
    color: #ccc;
    text-align: center;
    margin-top: 70px;
}

.uif-action-row {
    margin: 16px 0;
}

JavaScript

JavaScript file dependencies:

  • jQuery 1.7.2+
  • Bootstrap 3+
  • jquery.ui.widget.js
  • jquery.iframe-transport.js
  • jquery.fileupload.js

Additionally, specific script is required on the page-level to initialize the elements:

function show_file_list_click(event) {
    event = event || window.event;
    var pressed = event.target.getAttribute('aria-pressed') == "true";
    event.target.setAttribute('aria-pressed', pressed ? "false" : "true");
    console.log('clicked');
    $('#fileupload').focus().trigger('click');
}

function show_file_list_keyup(event) {
    event = event || window.event;
    if (event.keyCode === 32 || 13) {
        console.log('keypressed');
        show_file_list_click(event);
    }
}

$(function() {
    var url = window.location.hostname === 'blueimp.github.io' ? '//jquery-file-upload.appspot.com/' : 'server/php/';
    
    $('#fileupload').fileupload({
        url: url,
        dataType: 'json',            
        done: function (e, data) {
            $.each(data.result.files, function(index, file) {
                $('#files:last').append('<tr scole="row" class="template-download"><td><p class="name" id="file_' + file.name + '">' + file.name + '</p></td><td><p class="size" aria-labelledby="file_' + file.name + '">' + file.size + ' bytes</p></td><td><label for="id1_' + file.name + '" class="sr-only" aria-labelledby="file_' + file.name + '">Title</label><input type="text" class="form-control input-sm" name="title1_' + file.name + '" id="id1_' + file.name + '" /></td><td><label for="id2_' + file.name + '" class="sr-only" aria-labelledby="file_' + file.name + '">Details</label><textarea class="form-control input-sm" name="title2_' + file.name + '" id="id2_' + file.name + '" /></td><td><button type="button" class="btn btn-sm btn-danger" data-type="' + file.deleteType + '" data-url="' + file.deleteUrl + '" aria-labelledby="file_' + file.name + '">Delete</button></td></tr>');
            });
            // Update totals and announce
            $('#file_totals').html( $('#files tr').length + ' uploaded file(s)');
            // Focus on the table to read results
            $('#file_list').focus();
        }
    }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled');
});

Note: This implementation offers just two meta data fields (title and details, respectively), but if more are desired, this script would need to be customized. It might be wise to implement this dynamically based on data-attributes of the table or something. Just an idea.

View an example of this on the JSFiddle site

Accessibility Considerations

Required Level of Compliance:

In order to meet WCAG 2.0 guidelines, these are some considerations that may apply to this component:

5.3 Do not use tables for layout unless the table makes sense when linearized. Otherwise, if the table does not make sense, provide an alternative equivalent (which may be a linearized version).
5.4 If a table is used for layout, do not use any structural markup for the purpose of visual formatting.
10.2 Until user agents support explicit associations between labels and form controls, for all form controls with implicitly associated labels, ensure that the label is properly positioned.
12.4 Associate labels explicitly with their controls.
6.4 For scripts and applets, ensure that event handlers are input device-independent.
8.1 Make programmatic elements such as scripts and applets directly accessible or compatible with assistive technologies [Priority 1 if functionality is important and not presented elsewhere, otherwise Priority 2.]
9.2 Ensure that any element that has its own interface can be operated in a device-independent manner.
9.3 For scripts, specify logical event handlers rather than device-dependent event handlers.

Behavior without script

If javascript is turned off, this component should degrade to use the standard file input form control by default (<input type="file">). Using the attribute 'multiple' will allow the user to select more than one file at a time for the single file field.

Accessibility Resources

View the accessibility report of the JQuery File Upload Plugin here.

Keyboard Shortcuts

There are no special shortcuts, however the <span> button has a JavaScript listener for clicks and keypresses for accessibility.

Research and Discussion

Includes usability research findings and recommendations, information from the UIM discussion page, links, chapters, articles, etc that supports the design decision.