Tag Archives: ui

Fine Uploader 5.3 – Scaling and form support improvements & lots of squashed bugs

Update: September 22, 2015 – 5.3.2 Hotfix Release

  • Huge number of files from initial files endpoint causes the browser to hang or crash (#1466)

Update: August 28, 2015 – 5.3.1 Hotfix Release

  • Retry button remains visible when initiating a retry through API (#1455)

Version 5.3 brings a few requested feature updates as well as fixes that allow Fine Uploader to work even better in environments that routinely handle a very large number of file uploads per user session. We are committed to continually enhancing existing features based on customer feedback and improving support for enterprise-level upload traffic. After all, Fine Uploader exists to provide the support and features that none of the other browser-based upload tools are capable of offering. Version 5.3 is more proof of that.

Feature Enhancements

Downloading Fine Uploader

We’ve made it easier to use Fine Uploader in an environment that switches between Azure, S3, and traditional endpoints. Starting with version 5.3, you can now download a single build of Fine Uploader that contains support for all three endpoint types. Simple select the new “S3 + Azure + traditional” option in the server type section.

Form support

You can now “lazily” bind forms to Fine Uploader. In other words, you can attach Fine Uploader to an HTML form element at any time after Fine Uploader has been initialized. Previously, you were only able to associate a form with Fine Uploader during initialization as part of your configuration options, but this is no longer a limitation as of version 5.3! This is an enhancement to the form support feature. Thanks to Joel Kemp of Adobe for the feature request.

Image scaling

Are you making use of the scaled image upload feature and omitting the original image? You may find this useful to conserve bandwidth by only sending a small scaled version of a dropped image. We’ve made this workflow more appealing in 5.3 as we are now sending the original image’s UUID with each scaled upload request.

Fixed Bugs

Image scaling

If you are using the image scaling feature, you may have noticed that image previews are not rendered when the hideScaled option was set to true due to a bug. This was fixed in 5.3. We also fixed a somewhat related bug in the image scaling module that prevented an attempt to cancel all in-progress uploads when a scaled image is currently in progress. Scaled images are cancelled as part of the call to the cancelAll method, even if the scaled images are “hidden” in Fine Uploader UI.

Manual uploading

We recorded two fixes to the manual upload feature, which allows you to defer uploading of user-selected files to a later point via an API method. The first fix allows you to trigger uploading of stored files via the API inside of an onSubmitted callback handler. And the second addresses an issue that prevents the call to uploadStoredFiles from uploading all submitted files when a very large number of files (thousands) have been submitted.

Resuming uploads

Tim Daubenschütz found an issue that prevented the getResumableFilesData method from returning information about resumable files. This was fixed in 5.3 as well. Thanks for catching this Tim!

What’s Next?

The next planned release is currently version 5.4. We plan to add support for version 4 signatures to Fine Uploader S3. This will allow files to be sent to new S3 regions, such as the Germany (Frankfurt) region. We’ll also clean up and update the S3 documentation and smooth out support for sending headers and parameters to S3 along with each file. We also hope to add support for Microsoft Edge, but will likely forgo explicit support until the Edge team adds the ability to drop files from the desktop into the browser.

We Love Customer Feedback

Is something missing from Fine Uploader? Please let us know. We always give priority to useful customer-requested features. Take the opportunity to guide the evolution of Fine Uploader around your needs. The community is the most important aspect of this library, and we always love to hear from you.

Happy Uploading!

Fine Uploader 5.2 – Major UI Improvements, New Gallery View, Accessibility Updates

Update: June 8, 2015 – 5.2.2 Hotfix Release

  • Canceling a file with a queued thumbnail preview prevents other queued thumbnails from being generated. (#1416)
  • Deleting an uploaded file with a thumbnail in the (to-be-generated) preview queue prevents subsequently selected files from receiving generated thumbnail previews. (#1419)
  • Trash button is occasionally pushed to the next line in gallery mode. (#1418)
  • Trash button submits the form (if enclosed in a non-Fine-Uploader controlled form) after files have been uploaded successfully. (#1417)

Update: April 21, 2015 – 5.2.1 Hotfix Release

  • File input elements cannot be passed into addFiles API method on modern (File API) browsers  (#1398)

We are excited to announce the official release of Fine Uploader version 5.2!

UI Enhancements

5.2 brings major updates for Fine Uploader UI. Until version 5.2, Fine Uploader’s UI has remained mostly constant since its inception. We now offer a brand new modern CSS file, fine-uploader-new.css, which can be used with any existing Fine Uploader UI templates. To use the new look, simply reference this new CSS file in your project after upgrading to Fine Uploader 5.2. If you wish to continue using the old Fine Uploader UI display, you will not need to change anything.

We also added support for the new native browser element. As of 5.2, only Opera and Chrome support this element. However, once other browser add support, Fine Uploader will be able to use this new element in those browsers as well, without any code changes required. Currently, you must include appropriate

elements in your Fine Uploader template (already included for you in the default provided templates). If these are present, and the current browser has sufficient support, the element will be used to render confirm, alert, and prompt dialogs.

The new UI updates have been introduced without any breaking changes at all. You may continue to use Fine Uploader’s old look and continue to use any custom template adjustments or dialog/alert message implementations without changing any code.

You can also make use of the new gallery view. To integrate Fine Uploader’s customizable gallery view into your project, you will need to use the new gallery template and the fine-uploader-gallery.css file. The gallery view also makes use of several new icons introduced as part of the 5.2 release. Ensure that these new icons – continue.gif, pause.gif. retry.gif, and trash.gif – are accessible via the gallery CSS file as well.

Both new UIs share a default visible drop zone with background text (controlled by CSS) that matches the current browser’s capabilities:

visible-dropzone

Here is a preview of the gallery view, before and after uploading files:

gallery-view

gallery-view-done

Have a look at our updated live demo section on the Fine Uploader home page for code examples and additional designs. Customization and use of the new templates, styles,

support, and CSS is described in the updated styling documentation on our documentation site.

Accessibility Improvements

There were a number of accessibility-related adjustments to be made to Fine Uploader UI, the docs site, and the home page. In the interest of accommodating any and all users who must interact with Fine Uploader, we wanted to make a concerted effort to address any related deficiencies in this library and associated sites. We are happy to announce that this effort was successful, and Fine Uploader 5.2 (along with the docs site and home page) contains a substantial number of accessibility adjustments. We will continue to audit Fine Uploader for accessibility conformance going forward. If you happen to notice any accessibility obstacles we missed, please file an issue so we can schedule a fix as soon as possible.

Other Features

Support for uploading via PUT request

For all browsers other than IE9 and older, you may now ask Fine Uploader to submit upload requests to your server via a PUT (or even PATCH) request. Upload success requests may be sent via PUT as well. These methods can be specified via a new request.method option and the new S3 uploadSuccess.method option, respectively.

Uploading videos via iOS8 mobile Chrome now supported by default again

A workaround was put into Fine Uploader 5.0.5 to prevent Chrome from crashing in iOS8 due to issues with the Chrome browser and iOS8. This workaround, unfortunately, prevented videos from being uploaded in mobile Chrome due to another long-standing Apple iOS bug. This workaround is now disabled by default in Fine Uploader 5.2 as the underlying issue in mobile Chrome and iOS8 appears to be fixed.

Bug Fixes

  • Large S3 uploads hang w/ async key function and concurrent chunking enabled (#1394)
  • QuotaExceededError when trying to upload file when using Safari private browsing (#1395)
  • Empty file check validation is broken. (#1381)
  • “Retrying…” message remains in Fine Uploader UI even after failed chunk retry has succeeded. (#1349)
  • Pause button remains visible in Fine Uploader UI even after upload has failed. (#1367)

Next…

Fine Uploader 5.3 is the next planned version. Our top priority for 5.3 is to tackle S3 version 4 signature support. For a list of other cases to be completed in this version, please see the 5.3 milestone tracker in GitHub. Please be advised that cases may be removed or added from the milestone even after work on the milestone has commenced.

As always, we have continued to add the features that you all demand the most. Thanks again for your continued support. It is due to the backing of commercial license holders, everyone reporting bugs, those who suggest great features, and all the people that have expressed their support for this library that make it as great as it is.

Thanks for being a part of Fine Uploader!

P.S. Head on over to http://fineuploader.com for demos, documentation, and downloads!

 

Alertify Your Notifications and Dialogs

This is the first in a series of planned blog posts which will demonstrate how to integrate Fine Uploader along with various external libraries. If you would like to a specific library featured, then open up a feature request with reasons why you think it’d be awesome.

NOTE: This post assumes you are using Fine Uploader 4.x, as some of the syntax, particularly related to templates, changed (for the better) in 4.0. Please see the documentation site for more information.


Today, I’ll demonstrate how you can add a bit of spiff to Fine Uploader’s default UI by overriding the default dialog windows and adding notifications on certain events. Hopefully after reading this, it’ll be simple for you to get your uploader UI from looking like this:

bad-alert-2

To looking like this:

fine-message

We’ll use the alertify.js library to do most of the work for us. Also, we’ll use the latest version of Bootstrap to show how easy it is integrate and really make the uploader a cynosure.

Page Setup

First thing is first, acquire Fine Uploader, and ensure to include it on your page. The following HTML page should serve as a good starting point:

index.html

<!DOCTYPE html>
<html>
    <head>
        <!-- STYLESHEETS
        ========== -->
        <link rel="stylesheet"
              href="assets/vendor/fineuploader-4.0.0/custom.fineuploader-4.0.0.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs/alertify.js/0.3.10/alertify.core.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs/alertify.js/0.3.10/alertify.default.css">
        <link rel="stylesheet" href="assets/css/style.css">

    <!-- TEMPLATE
    ========== -->
    <script type="text/template" id="qq-template">
        <div class="qq-uploader-selector qq-uploader">
            <div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
                <span>Drop files here to upload</span>
            </div>
            <div class="qq-upload-button-selector qq-upload-button">
                <div>Upload a file</div>
            </div>
            <span class="qq-drop-processing-selector qq-drop-processing">
                <span>Processing dropped files...</span>
                <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
            </span>
            <ul class="qq-upload-list-selector qq-upload-list">
                <li>
                    <div class="qq-progress-bar-container-selector">
                        <div class="qq-progress-bar-selector qq-progress-bar"></div>
                    </div>
                    <span class="qq-upload-spinner-selector qq-upload-spinner"></span>
                    <span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
                    <span class="qq-upload-file-selector qq-upload-file"></span>
                    <input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
                    <span class="qq-upload-size-selector qq-upload-size"></span>
                    <a class="qq-upload-cancel-selector qq-upload-cancel" href="#">Cancel</a>
                    <a class="qq-upload-retry-selector qq-upload-retry" href="#">Retry</a>
                    <a class="qq-upload-delete-selector qq-upload-delete" href="#">Delete</a>
                    <span class="qq-upload-status-text-selector qq-upload-status-text"></span>
                </li>
            </ul>
        </div>
    </script>
    </head>
    <body>

        <div class="container">
            <div id="uploader">
            </div>
        </div> <!-- /container -->

        <!-- JAVASCRIPTS
        ========== -->
        <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/alertify.js/0.3.10/alertify.min.js"></script>
        <script src="assets/vendor/fineuploader-4.0.0/custom.fineuploader-4.0.0.js"></script>
        <script src="assets/js/main.js"></script>

    </body>
</html>

main.js

var options = {
  element: $("#uploader"),
  request: {
    endpoint: '/upload/receiver'
  },
  showMessage: function(message) {},
    showConfirm: function(message) {},
  showPrompt: function(message, defaultValue) {}
};

$(document).ready(function() {
    alertify.set({ delay: 10000 }); // delay log alerts for 10 seconds

    $("#uploader").fineUploader(options);
  });

Fine Uploader UI mode, by default, displays three kinds of modal dialogs: prompts, messages, and confirms. These dialogs are implemented with window.prompt, window.alert, and window.confirm, respectively. If you have ever seen these dialogs you know their appearance is unprofessional and implemented differently on different browsers. With alertify, Fine Uploader, and a few lines of code we can unify the appearance of dialogs and improve their look and feel.

Notification Station

Users like it when the page responds to their actions with visual cues. Let’s say we would like to show a notification to the user when an upload completes or fails, and if it fails we want the reason to be shown to the user. With Fine Uploader’s events we can hook in almost any logic we want at the moment something happens (whatever that something may be). For this, we’ll need to provide custom callbacks that will display a proper message for the complete and error events.

$("#uploader")
    .on('complete', function (event, fileId, fileName, responseJSON, xhr) {
        if (responseJSON.success === true) {
            alertify.success("Successfully uploaded: " + fileName, "", 0);
        } else {
            alertify.error("Error: " + error);
        }               
    });

Now, when a user successfully uploads a file they’ll get a notification like so:

success-notification

And when the uploader has a problem uploading, there will be a notification message showing exactly what went wrong:

failure-notification

‘Alert!’

Fine Uploader UI will issue a window.alert the moment one of its validators detects some sort of issue with a file that has been submitted.

Before we override this show method, let’s set up a simple validator that will stop the user from uploading more than 3 files. (Note that you can set up all sorts of validators see the docs, but this one is kept trivial for demonstration purposes.

var options = {
  element: $("#uploader"),
  request: {
    endpoint: '/upload/receiver'
  },
  validation: {
      itemLimit: 3 // Disallow >3 submitted files
  },
  showMessage: function(message) {},
  showConfirm: function(message) {},
  showPrompt: function(message, defaultValue) {}
};

Alright, so now when a user drops 4 or more files a window.alert will pop up like so:

bad-alert-2

That’s not pretty, and we want pretty. Provide a new callback to the showMessage option which will instead display our own message via alertify:

showMessage: function (message) {
    return alertify.alert(message);
},

fine-message

Woah, that is hella better. It’s like a breath of fresh air. Onward!

Please confirm …

Sometimes Fine Uploader UI needs confirmation from the user that it is safe to continue with the operation it is about to perform. For example, if the deleteFile.confirmMessage option is true then Fine Uploader will display a confirmation dialog to the user to ensure that it is safe to delete the corresponding file.

First, enable the delete feature in Fine Uploader and on your server:

var options = {
  element: $("#uploader"),
  request: {
    endpoint: '/upload/receiver'
  },
  validation: {
      itemLimit: 3
  },
  deleteFile: {
      enabled: true, // turn the delete file feature on
      forceConfirm: true // enable FU confirming with the user that they want to proceed with delete
  },  
  showMessage: function (message) {
      return alertify.alert(message);
  },
  showConfirm: function(message) {},
  showPrompt: function(message, defaultValue) {}
};

Now, when the user presses ‘Delete’ next to a successfully uploaded file, they’ll see a confirmation dialog:

bad-confirm

We can completely customize this dialog very easily with alertify. All we have to do is provide a promissory function as the value of the showConfirm option.

showConfirm: function (message) {
    var promise;
    promise = new qq.Promise();
    alertify.confirm(message, function(result) {
      if (result) {
        return promise.success(result);
      } else {
        return promise.failure();
      }
    });
    return promise; 
}

And with 10 lines of code, we have a spiffy looking confirmation dialog (well, at least one that’s waaay better than window.confirm).

fine-confirm

PRO-mpting

The last dialog function in Fine Uploader’s repertoire is showPrompt.
A prompt is useful when you want to query the user for some information (e.g., a custom filename). There is only one instance where Fine Uploader makes use of prompts, but it’ s a necessary one. Fine Uploader has support for submitting images via the ClipboardAPI. The ClipboardAPI is young, though, and does not yet have the ability to grab the filename from the submitted file. If paste is enabled in Fine Uploader, and promptForName is true then the user will be prompted for a filename to enter before Fine Uploader begins processing.

So first, enable the paste feature:

var options = {
  element: $("#uploader"),
  request: {
    endpoint: '/upload/receiver'
  },
  validation: {
      itemLimit: 3
  },
  deleteFile: {
      forceConfirm: true,

  },  
  paste: {
      promptForName: true, // enabling prompting for filename on paste received
      targetElement $(document) // set the paste target element to be the entire web page
  },
  showMessage: function (message) {
    return alertify.alert(message);
  },
  showConfirm: function (message) {
    var promise;
    promise = new qq.Promise();
    alertify.confirm(message, function(result) {
      if (result) {
        return promise.success(result);
      } else {
        return promise.failure();
      }
    });
    return promise; 
  },
  showPrompt: function(message, defaultValue) {},
};

bad-prompt

showPrompt: function(message, defaultValue) {
  promise = new qq.Promise()
  alertify.prompt(message, (result, inStr) ->
    if result
      promise.success(inStr)
    else
      promise.failure(inStr)
  , defaultValue)
  return promise
},

fine-prompt

Making Promises

You may have noticed the use of the qq.Promise() throughout this code. When showConfirm or showPrompt return a qq.Promise() Fine Uploader will internally hold of on executing code until immediately after the promise is fulfilled.

For example, showConfirm will be called the moment the user clicks the “delete” button for an uploaded file. If the promise is successful (i.e., promise.success() fulfills the promise), then the delete request is submitted. If the promise is a failure (i.e., promise.failure() fulfills the promise), then the delete request is not submitted.

This is a huge win because the UI thread will continue running while the app is waiting for the user’s confirmation.

This Time With More Style

Why stop now. Let’s keep adding some style tweaks (mostly because they bug me). Throw Bootstrap in there! Hack some CSS! Have some fun! I’ve provided the complete example I used to cook up this tutorial below, hopefully someone finds it useful.

First, add bootstrap to your already set up page:

<link rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0-rc2/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>

Include a modified template in your document, based off of the bundled default template:

<script type="text/template" id="qq-template">
    <div class="qq-uploader-selector qq-uploader col-lg-12">
        <pre class="qq-upload-drop-area-selector qq-upload-drop-area col-lg-12" qq-hide-dropzone>
            <span>Drop files here to upload</span>
        </pre>
        <div class="qq-upload-button-selector btn btn-success">
            <div>Upload a file</div>
        </div>
        <span class="qq-drop-processing-selector qq-drop-processing">
            <span>Processing dropped files...</span>
            <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
        </span>
        <ul class="qq-upload-list-selector qq-upload-list list-group">
            <li>
                <div class="qq-progress-bar-container-selector progress">
                    <div class="qq-progress-bar-selector bar"></div>
                </div>
                <span class="qq-upload-spinner-selector qq-upload-spinner"></span>
                <span class="qq-upload-file-selector qq-upload-file"></span>
                <span class="qq-upload-size-selector qq-upload-size"></span>
                <a class="qq-upload-delete-selector btn" href="#">Delete</a>
                <span class="qq-upload-status-text-selector qq-upload-status-text"></span>
            </li>
        </ul>
    </div>
</script>

Add some custom styles to your own stylesheet:

style.css

.qq-upload-list {
  margin-top: 7px;
  text-align: left;
}
.qq-upload-list > li {
  margin-top: 3px;
}
.qq-drop-area {
  min-height: 200px;
}
.alert-error .qq-upload-failed-text {
  display: inline;
}

And add the corresponding classes to Fine Uploader’s classes option:

classes: {
    success: 'alert alert-success list-group-item',
    fail: 'alert alert-error list-group-item'
}

We can also modify many of the messages that are used in the prompts we’ve customized. Let’s change the default delete message by changing the confirmMessage property on the delete option we created earlier:

deleteFile: {
  enabled: true,
  confirmMessage: 'Send <code>{filename}</code>; into the abyss?',
  forceConfirm: true
},

The Final Product

This is probably what you’ve been waiting for. Below is the entire HTML, CSS, JS code that I used to create everything above. Happy hacking!

index.html

<!DOCTYPE html>
<html>
    <head>
        <!-- STYLESHEETS
        ========== -->
        <link rel="stylesheet"
              href="assets/vendor/fineuploader-4.0.0/custom.fineuploader-4.0.0.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0-rc2/css/bootstrap.min.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs/alertify.js/0.3.10/alertify.core.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs/alertify.js/0.3.10/alertify.default.css">
        <style>
            body {
                padding-top: 60px;
                padding-bottom: 40px;
            }
        </style>
        <link rel="stylesheet" href="assets/css/style.css">

        <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
    <script type="text/template" id="qq-template">
        <div class="qq-uploader-selector qq-uploader col-lg-12">
            <pre class="qq-upload-drop-area-selector qq-upload-drop-area col-lg-12" qq-hide-dropzone>
                <span>Drop files here to upload</span>
            </pre>
            <div class="qq-upload-button-selector btn btn-success">
                <div>Upload</div>
            </div>
            <span class="qq-drop-processing-selector qq-drop-processing">
                <span>Processing dropped files...</span>
                <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
            </span>
            <ul class="qq-upload-list-selector qq-upload-list list-group">
                <li>
                    <div class="qq-progress-bar-container-selector progress">
                        <div class="qq-progress-bar-selector bar"></div>
                    </div>
                    <span class="qq-upload-spinner-selector qq-upload-spinner"></span>
                    <span class="qq-upload-file-selector qq-upload-file"></span>
                    <span class="qq-upload-size-selector qq-upload-size"></span>
                    <a class="qq-upload-delete-selector btn" href="#">Delete</a>
                    <span class="qq-upload-status-text-selector qq-upload-status-text"></span>
                </li>
            </ul>
        </div>
    </script>
    </head>
    <body>

        <div class="container">
            <div id="uploader">
            </div>
        </div> <!-- /container -->

        <!-- JAVASCRIPTS
        ========== -->
        <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/alertify.js/0.3.10/alertify.min.js"></script>
        <!--
        <script src="assets/vendor/bootbox.min.js"></script>
        -->
        <script src="assets/vendor/fineuploader-4.0.0/custom.fineuploader-4.0.0.js"></script>
        <script src="assets/js/main.js"></script>

    </body>
</html>

style.css

.qq-upload-list {
  margin-top: 7px;
  text-align: left;
}
.qq-upload-list > li {
  margin-top: 3px;
}
.qq-drop-area {
  min-height: 200px;
}
.alert-error .qq-upload-failed-text {
  display: inline;
}

main.js

  var options = {
    debug: true,
    element: $("#uploader"),
    deleteFile: {
      enabled: true,
      confirmMessage: 'Send <code>{filename}</code> into the abyss?',
      forceConfirm: true
    },
    template: template,
    classes: {
      success: 'alert alert-success list-group-item',
      fail: 'alert alert-error list-group-item'
    },
    validation: {
      itemLimit: 3
    },
    paste: {
      promptForName: true,
      targetElement: $(window.document)
    },
    showMessage: function(message) {
      return alertify.alert(message);
    },
    showPrompt: function(message, defaultValue) {
      var promise;
      promise = new qq.Promise();
      alertify.prompt(message, function(result, inStr) {
        if (result) {
          return promise.success(inStr);
        } else {
          return promise.failure(inStr);
        }
      }, defaultValue);
      return promise;
    },
    showConfirm: function(message) {
      var promise;
      promise = new qq.Promise();
      alertify.confirm(message, function(result) {
        if (result) {
          return promise.success(result);
        } else {
          return promise.failure();
        }
      });
      return promise;
    }
  };

  $(document).ready(function() {
    alertify.set({
      delay: 10000
    });
    return $("#uploader").fineUploader(options).on('complete', function(event, fileId, fileName, responseJSON, xhr) {
      if (responseJSON.success != null) {
        return alertify.success("Successfully uploaded: <code>" + fileName + "</code>", "", 0);
      }
    }).on('error', function(event, fileId, fileName, error, xhr) {
      return alertify.error("Error: " + error);
    });
  });

Other Libraries

Of course, we aren’t limited to using alertify, we could hook in any other sort of prompting library we wanted. Other alternatives include Bootbox.js, Bootstrap’s modal.js, and much more.

If you think you’ve created something neat, share it on GitHub and/or send us a screenshot, we’re always looking for ideas and cutting-edge uses of Fine Uploader.