Angular File drag n' drop uploader

with queue and auto upload filters and more. Custom angular fileUpload directive.

by Eric Hynds

HTML

<!DOCTYPE HTML>
<!-- 1. ng-file-drop -->
<html id="ng-app" ng-app="app" ng-file-drop> <!-- id="ng-app" IE<8 -->

    <head>
        <link rel="stylesheet" href="style.css" />

        <!-- Fix for old browsers -->
        <script src="/js/es5-shim.min.js"></script>

        <!-- Fix for IE<9 in iframe mode -->
        <!--<script src="/js/jquery/jquery-1.8.3.min.js"></script>-->

        <script src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
        <script src="functions.js"></script>
        <script src="files.js"></script>
        <script src="controllers.js"></script>

    </head>
    <body ng-controller="TestController">

        <h1>Test page</h1>

        <!-- 3. ng-file-over or ng-file-over="className" -->
        <div class="over" ng-file-over></div>

        <!-- 2. ng-file-select -->
        <input type="file" multiple ng-file-select />

        <h2>The queue. Length: {{ uploader.queue.length }}</h2>
        <ul>
            <li ng-repeat="item in uploader.queue">
                <div>Name: {{ item.file.name }}</div>
                <div>Size: {{ item.file.size }}</div>
                <div>
                    Progress: {{ item.progress }}
                    <div class="item-progress-box">
                        <div class="item-progress" ng-style="{ 'width': item.progress + '%' }"></div>
                    </div>
                </div>
                <div>Uploaded: {{ item.isUploaded }}</div>
                <div>
                    <a ng-href="#" ng-click="item.upload()" ng-hide="item.isUploaded" >upload</a>
                    <a ng-href="#" ng-click="item.remove()">delete</a>
                </div>
            </li>
        </ul>
        <div ng-show="uploader.queue.length">
            <div>
                Total progress: {{ uploader.progress }}
                <div class="total-progress-box">
                    <div class="total-progress" ng-style="{ 'width': uploader.progress + '%' }"></div>
                </div>
       ...

CSS

h1, h2 {
    background-color: steelblue;
    font-family: Tahoma, serif;
    color: white;
    padding: 10px;
    letter-spacing: 1px;
}

h1 {
    font-size: 1.3em;
}

h2 {
    font-size: 1.2em;
}

.ng-file-over {
    background-color: #FFBEA3;
}

.bg {
    background-color: lightgreen;
}

.over {
    border: 2px dashed lavender;
    height: 100px;
    padding: 4px;
}

.item-progress-box {
    height: 20px;
    margin-top: -20px;
    margin-left: 60px;
    margin-right: 10px;
}

.item-progress {
    background-color: #90B8DA;
    height: 100%;
    width: 0;
}

.total-progress-box {
    height: 20px;
    margin-top: -20px;
    margin-left: 90px;
    margin-right: 10px;
}

.total-progress {
    background-color: #90B8DA;
    height: 100%;
    width: 0;
}

.box {
    margin: 20px;
}

.progress {
    background-color: mediumpurple;
    height: 20px;
}

.uploaded {
    background-color: lightgreen;
    height: 20px;
    width: 100px;
}

ul > li:nth-child(odd) {
    background-color: #f5f5f5;
    margin: 2px;
}

JavaScript

'use strict';

/** 
 * controllers.js
 */
angular
    .module( 'app', [ 'files' ])

    // The example of the full functionality
    .controller( 'TestController', function( $scope, $fileUploader ) {

        // create a uploader with options
        var uploader = $fileUploader.create({
            url: '/upload.php',
            removeAfterUpload: true,
            filters: [
                function( item ) {                    // first user filter
                    console.log( 'filter1' );
                    return true;
                }
            ]
        });

        // ADDING FILTER

        uploader.filters.push(function( item ) { // second user filter
            console.log( 'filter2' );
        });

        // REGISTER HANDLERS

        uploader.bind( 'afteraddingfile', function( event, item ) {
            console.log( 'After adding a file', item );
        });

        uploader.bind( 'afteraddingall', function( event, items ) {
            console.log( 'After adding all files', items );
        });

        uploader.bind( 'changedqueue', function( items ) {
            $scope.$$phase || $scope.$apply();
        });

        uploader.bind( 'beforeupload', function( event, item ) {
            console.log( 'Before upload', item );
        });

        uploader.bind( 'progress', function( event, item, progress ) {
            console.log( 'Progress: ' + progress );
        });

        uploader.bind( 'success', function( event, xhr, item ) {
            console.log( 'Success: ' + xhr.response );
        });

        uploader.bind( 'complete', function( event, xhr, item ) {
            console.log( 'Complete: ' + xhr.response );
        });

        uploader.bind( 'progressall', function( event, progress ) {
            console.log( 'Total progress: ' + progress );
            $scope.$$phase || $scope.$apply();
        });

        uploader.bind( 'completeall', function( event, items ) {
            console.log( 'All files are transferred' );
   ...