JTech Communications Logo

JTech's Image and File Uploader Provides Essential User Feedback

by Mira Brody and Patrick Milvich - October 23, 2015
The classic file uploader featured a file name field and button.
Historically, uploading images and files to websites has been a clunky and inconvenient experience for the end user. The typical upload control consisted of a single upload button and a short text field where the path and name of the image or file chosen for upload would appear. This control provided no preview, no loading progress feedback, no communication to the user whatsoever other than an error if the user broke rules that were not previously defined to the user. Updated browsers support a variety of relatively new technologies that allow us to improve this experience dramatically. By developing robust file upload and image upload controls, we have been able to improve the experience of these functions in our content management system “My JTech.” Additionally, we developed these controls so that we can customize them to easily be deployed on the sites we built for our clients as well.

In this article, we discuss the major features, thinking and methodology of these technologies in the hopes that it will help other developers provide excellent user feedback when implementing file and image upload controls.

Drag-and-drop in computing has been around since the 90s and can be a convenient way for your users to be able to upload files or images. We use two HTML5 technologies for drag-and-drop in our advanced uploaders. Drag-and-drop on a page allows you to set an element to be draggable, then register for events when you drop that element elsewhere in the DOM. However, in order to drag-and-drop files from the OS file browser, some support for the File API (1) is needed; luckily, the part of the File API required for drag-and-drop is widely supported on desktop browsers.

One of our more advanced, multi-image upload controls is on the Next FX website. If you drag-and-drop multiple images, the photos will automatically compress on the client side and provide queue feedback. Source: Next FX

We detect drag-and-drop on two levels. The first is to drag a file into the browser window, which allows us to highlight and style any available drop targets. The second level of detection is when you drag your file over a specific drop target, changing the target’s appearance to indicate that your files have reached their destination.

We built Montana Health Network a file uploader for their staffing agency page. Instead of prospective employees being forced to email their resumes separately, we streamline the user experience by implementing an advanced file upload option for resumes as part of the job application integrated on their website. Source: Montana Health Network

The drag-and-drop events act more like the mouseover/mouseout events instead of the :hover pseudo-class (a theoretical mouseenter/mouseleave). We’ve created a custom event we call ‘jt-drag-enter-leave’ that implements two different enter/leave detection methods. One for IE (due to dragleave events not properly firing all the time) that manually detects if the position of your cursor is over the element you are in, and the other using a simple push/pop technique of dragenter/dragleave events (once it reaches 0 we’ve left the area).
Push/Pop Technique:
var el = document.getElementById('dropEl');
var count = 0;
function enterFunc() { ... }
function leaveFunc() { ... }
el.addEventListener('dragenter', function() {
   if(count == 0) enterFunc();
el.addEventListener('dragleave', function() {
   if(count == 0) leaveFunc();

Performing this additional work allows us to avoid adding or removing classes/styles to elements while the user drags over children of the drop target element — otherwise visual flickering can occur. This visual effect is especially apparent if the child elements have borders — in some browsers, a tiny gap occurs between the dragleave event triggering and the next dragenter event as the cursor passes over an element's border.

We also support a simple click or touch if a user prefers that method. We do this by placing a file input that is oversized and anchored at the top right of a container with overflow hidden. The input has an opacity of 0 so that the input control is hidden. We anchor it in the upper right to avoid users clicking on the text component of the control that some browsers implement.
div.uploadContainer {
   position: relative;
   width: 150px;
   height: 30px;
   overflow: hidden;
div.uploadContainer > input {
   position: absolute;
   right: 0;
   top: 0;
   cursor: pointer;
   font-size: 200px;
   border: none;
   margin: 0;
   opacity: 0;

<div class="uploadContainer">
   <input type="file" name="aFile">
The options and visual communication made possible by drag-and-drop make all the difference to a user by providing feedback and a much refined appearance.

Using Canvass in the Browser
Common formatting problems that occur during an image upload can be solved by uploading images through Canvass, which allows for an uploaded image to be validated in the browser before it is saved on the server, saving time, effort and bandwidth.

As an image or a file is uploaded, we provide visual feedback to the user and store it in a temporary location on the server. This feedback prevents uploading a file multiple times on form submissions, saving bandwidth and eliminates confusion and frustration on the user's end. When the form is fully submitted and validated, we then move the temporary file on the server to the final location.

Images uploaded by a user are often from a variety of devices and therefore are sized inadequately. While there’s not much to be done about images that are too small, we can format the larger images pulled directly off of digital cameras. If a user’s browser supports FileReader and Canvas technologies, we resize and very slightly compress the image in order to create a more suitable “original” to be uploaded. The resized image is still high quality, but often reduces 10MB+ images closer to 1-2MB, saving on bandwidth and server processing.
Resize Image from file input type:
var input = document.getElementById('fileInput');
var file = input.files[0];
var reader = new FileReader();
reader.onload = function(e) {
   var img = new Image();
   img.onload = function() {
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      var width = 500, height = 500;

      ctx.drawImage(img, 0, 0, width, height);
      var data = canvas.toDataURL('image/jpeg', .95);
      ... // do what you will with data
   img.src = reader.result;
An added benefit of these technologies is that we immediately generate a secondary thumbnail image, but instead of actually uploading it, simply display it to the user. This way, the user receives feedback about what image is being uploaded even while it is still in the process of uploading.
On the Shipton's Big R community page, a white fill is placed around sponsor logos.
Editing and Crop Tools
Our advanced image control features are implemented in My JTech where users can not only upload an image, but make minors edits to it as well. We've included the ability to flip an image, replace, delete and crop.

After you've uploaded an image, we allow you to adjust the crop for all the different ‘cuts’ we produce. The cuts represent the different ways an image may be used on a website. Based on the design of the website, we define dimensions for each cut image, an image ratio if applicable, and an optional fill space around the image if an image ratio needs to be preserved; this last feature is particularly useful for logos, which are often badly cropped unless a white fill is added around the image.

The user is presented an interface that respects the crop ratio, if there is one, and allows them to resize and drag a box representing their current cut with the cropped portions shaded out. We’re able to do this by having one background image with four other elements that make up the top, left, right, and bottom shaded elements. When you drag or resize, we readjust all the shaded elements to give the impression that you’re moving one box.
A variety of editing tools are available in My JTech, like this crop tool used to size the photo on Gem Gallery's homepage. Source: The Gem Gallery

We store the new dimensions after you resize a cut, but do not replace the cropped file until you click save; we keep the original uploaded file on the server to avoid image degradation on the newly generated cuts.

These edit controls completely optimize the quality of uploaded images as well as user control over their displays, ensuring the most advanced tools for managing the content on their site.

Progress Bars and Error States
One issue with archaic image and file uploading tools are their inability to provide the user with adequate feedback. With these older uploaders, after a file is selected, there is no notion of progression until the upload is completed, leaving the user with an amount of confusion as they wait. To alleviate this negative experience, we've implemented progress bars into our upload controls as well as specific error states when an upload is unsuccessful.

Once a file has been selected, while an image or file is being uploaded we display its progress in an animated bar, allowing the user to associate their action to an impending result. If the browser supports AJAX 2, we use AJAX to send the file and are able to display a bar that fills up 0-100% as progression occurs. Otherwise, we use an iframe fallback where we create a temporary iframe and redirect the form to submit into the iframe. During the iframe upload we display a pinstriped “barber pole” progress bar instead of one that fills up. These progress bars will also display for up to three files at a time during multi-uploads, with all subsequent documents queued and waiting for their turn.

We've prepared for a variety of different error states to help in the instances that a file or image is not supported or has uploaded unsuccessfully. Before uploading, to avoid the bandwidth cost, we check the file extensions to ensure it’s part of an approved file type (we support .jpg, .png, .gif, and .bmp files) and present an error message if it is not. When uploading an image to a browser that supports pre-formatting, we are also able to validate the image before we send it to the server. As a final state, we verify valid images on the server as well.

These robust feedback cues greatly improve the user's overall experience on your website and can be the difference between a frustrated customer leaving due to lack of response, or staying to complete their transaction.

File Naming
With file uploaders, file naming is often a challenge because the information is being provided by the user, who often upload multiple files of the same name, use undesirable characters such as spaces or punctuation in their file names. We support original file naming, offering more customization to the user yet eliminating the confusion of a user choosing an unsupported file name. We automatically rename files when they are uploaded to names that are far more web-friendly, cleaning it up behind the scenes. We replace spaces with dashes, then remove any characters that are not letters, numbers, dashes, underscores or periods. This also inherently strips slashes that might otherwise cause requests to go outside the file structure we’ve defined to store the files.

The following regular expression is what we use to scrub the name:
In php:
preg_replace('/^[a-zA-Z0-9\\-_\\.]/', '', str_replace(' ', '-', $filename));
In order to maintain that improved user experience, we went to a great effort to preserve original file names as much as possible so that the items are still recognized by the user. We've found that renaming is an easier way for users to maintain control over their uploads while still making it more readable for the web.

Although image and file uploaders are extremely useful for doing anything from uploading resumes, refreshing homepage photos and more, the experience has, in the past, been less than favorable. Primitive, visually bare and with a substantial lack of user feedback, these upload controls were not friendly to the average user and often caused not only confusion, but unnecessary errors and a poorly formatted end result as well.

With the availability of advanced technologies, we’ve been able to greatly improve the experience of this website standard by providing robust user feedback, techniques we've applied to the framework of our websites. These tools are a benefit to our custom content management system and also add substantially to the fit and finish of the user-facing aspects of the advanced websites we build -- a benefit to both the site administrators and customers alike.

In the future, we intend to implement multi-file uploads, as well as feedback for when too many files are selected at one time, additional file type support and even more specific error states. As new technologies become available and supported, we will be able to provide an ever-more polished experience. If there are solutions that you’ve found useful as well, contact us; we’d love to hear your ideas.


Monthly inbox insights.

Our articles are published for free on our blog.
First Name
Last Name
Email Address