Stack Overflow question: Angular file upload

http://stackoverflow.com/questions/32840813/angular-file-upload

HTML

<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="https://nervgh.github.io/js/es5-shim.min.js"></script>
<script src="https://nervgh.github.io/js/es5-sham.min.js"></script>
<script src="https://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://nervgh.github.io/pages/angular-file-upload/examples/console-sham.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://code.angularjs.org/1.1.5/angular.min.js"></script>
<script src="https://nervgh.github.io/pages/angular-file-upload/dist/angular-file-upload.min.js"></script>
<div id="ng-app" ng-app="app">
    <div ng-controller="AppController" nv-file-drop="" uploader="uploader">
        <div class="container">
            <div class="row">
                <div class="col-md-3">
                     <h3>Select files</h3>

                    <div ng-show="uploader.isHTML5">
                        <!-- 3. nv-file-over uploader="link" over-class="className" -->
                        <div class="well my-drop-zone" nv-file-over="" uploader="uploader">Base drop zone</div>
                        <!-- Example: nv-file-drop="" uploader="{Object}" options="{Object}" filters="{String}" -->
                        <div nv-file-drop="" uploader="uploader" options="{ url: '/foo' }">
                            <div nv-file-over="" uploader="uploader" over-class="another-file-over-class" class="well my-drop-zone">Another drop zone with its own settings</div>
                        </div>
                    </div>
                    <!-- Example: nv-file-select="" uploader="{Object}" options="{Object}" filters="{String}" -->
                    <input type="file" nv-file-select="" uploader="uploader" multiple />
                    <br/>
                </div>
                <div class="col-md-9" style="margin-bottom: 40px">
                     <h2>Uploads only images (with...

CSS

.my-drop-zone {
    border: dotted 3px lightgray;
}
.nv-file-over {
    border: dotted 3px red;
}
/* Default class applied to drop zones on over */
 .another-file-over-class {
    border: dotted 3px green;
}
html, body {
    height: 100%;
}
canvas {
    background-color: #f3f3f3;
    -webkit-box-shadow: 3px 3px 3px 0 #e3e3e3;
    -moz-box-shadow: 3px 3px 3px 0 #e3e3e3;
    box-shadow: 3px 3px 3px 0 #e3e3e3;
    border: 1px solid #c3c3c3;
    height: 100px;
    margin: 6px 0 0 6px;
}

JavaScript

angular.module('app', ['angularFileUpload'])
    .controller('AppController', ['$scope', 'FileUploader', function ($scope, FileUploader) {
    var uploader = $scope.uploader = new FileUploader({
        url: 'upload.php'
    });

    // FILTERS

    uploader.filters.push({
        name: 'imageFilter',
        fn: function (item /*{File|FileLikeObject}*/ , options) {
            var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|';
            return '|jpg|png|jpeg|bmp|gif|pdf|'.indexOf(type) !== -1;
        }
    });

    // CALLBACKS

    uploader.onWhenAddingFileFailed = function (item /*{File|FileLikeObject}*/ , filter, options) {
        console.info('onWhenAddingFileFailed', item, filter, options);
    };
    uploader.onAfterAddingFile = function (fileItem) {
        console.info('onAfterAddingFile', fileItem);
    };
    uploader.onAfterAddingAll = function (addedFileItems) {
        console.info('onAfterAddingAll', addedFileItems);
    };
    uploader.onBeforeUploadItem = function (item) {
        console.info('onBeforeUploadItem', item);
    };
    uploader.onProgressItem = function (fileItem, progress) {
        console.info('onProgressItem', fileItem, progress);
    };
    uploader.onProgressAll = function (progress) {
        console.info('onProgressAll', progress);
    };
    uploader.onSuccessItem = function (fileItem, response, status, headers) {
        console.info('onSuccessItem', fileItem, response, status, headers);
    };
    uploader.onErrorItem = function (fileItem, response, status, headers) {
        console.info('onErrorItem', fileItem, response, status, headers);
    };
    uploader.onCancelItem = function (fileItem, response, status, headers) {
        console.info('onCancelItem', fileItem, response, status, headers);
    };
    uploader.onCompleteItem = function (fileItem, response, status, headers) {
        console.info('onCompleteItem', fileItem, response, status, headers);
    };
    uploader.onCompleteAll =...