Drag and Drop AngularJs with FileList

1.3k Views Asked by At

I am very new to front-end development and I thought it would be cool to add drag and drop to a current upload page. However after starting to hook everything up with ng-flow (a directive that assists with drag and drop) I cannot seem to make the connection on how to add the files to the file list. If you think I don't even need the directive and am just overkilling this and there is a simpler solution I would be willing to make changes as well. NOTE: I am giving only samples of the code so dont ding it for not compiling!

fileModelDirective:

app.directive('fileModel', ['$parse', '$log', '$confirm',
    function ($parse, $log, $confirm) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var model = $parse(attrs.fileModel);
                var modelSetter = model.assign;
                scope.sampleFile = model;
                element.bind('change', function () {
                    // if the file open dialog is raised and the file name
                    // is cleared and cancel is pressed then a reset is needed
                  //  document.getElementById('file-upload-name').innerHTML = "";
                  //  document.getElementById('file-upload-btn').disabled = true;

                    // status always needs reset if choosing another file
                    scope.$apply(function () {
                        modelSetter(scope, element[0].files);
                        if (document.getElementById('file-upload').files) {
                            // This iterates over to see if the total files size is greater than 100MB
                            const maxFilesSize = 104857600;
                            var totalFilesSize = 0;
                            var numberOfDataSamples = element[0].files.length;


                        }
                    });
                });
            } // link
        };
    }]); // fileModel

fileMethod

  $scope.uploadFile = function () {
                console.log(flow)
                var file = flow.file;
                $scope.numberOfFiles = document.getElementById('file-upload').files.length;
                $scope.filesTotalSize = 0;
                for (var i = 0; i < document.getElementById('file-upload').files.length; i++) {
                    $scope.filesTotalSize = document.getElementById('file-upload').files[i].size + $scope.filesTotalSize;
                }

fileUpload Service

app.service('fileUpload', ['$http', '$log',
    function ($http, $log) {
        this.uploadFileToUrl = function (file, uploadUrl) {
            //$log.debug("file(s)");
            //$log.debug(file);
            var fd = new FormData();
            angular.forEach(file, function (value, key) {
                fd.append(key, value);
            });
            return $http.post(uploadUrl, fd, {
                transformRequest: angular.identity,
                headers: {
                    'Content-Type': undefined,
                    'enctype': "multipart/form-data"
                }
            })
        }; // uploadFileToUrl
    }]); // fileUpload

html

<div flow-init flow-files-submitted="$flow.upload()" class="ng-scope">
    <div flow-drop>
        <span for="file-upload"
              class="btn btn-primary" flow-btn style="margin-top: 10px; ">Upload File
            <input id="file-upload" type="file" multiple="multiple" file-model="sampleFile"
                   style="visibility: hidden; position: absolute;"></span>
        <p flow-prevent-drop
           flow-drag-enter="style={border: '5px dashed purple'}"
           flow-drag-leave="style={}"
           ng-style="style"
           style="margin-top: 10px;width: 100%;min-height: 50px;">
            Drag And Drop your file here</p>
        <br>
        <span ng-repeat="file in $flow.files track by $index">
        {{file.name + ", " }}
    </span>

        <div style="margin-left: 2px; margin-top: 10px;">
            <button id="file-upload-btn" class="btn btn-primary"
                    ng-click="showMask(); uploadFile();">
                Upload
            </button>
            <button class="btn btn-primary" style="float: right;"
                    ng-click="navigateTo('/startup')">
                Cancel
            </button>
            <button style="float: right; margin-right: 6px;" class="btn btn-primary"
                    ng-click="$flow.cancel()">
                Clear
            </button>
        </div>
    </div>
</div>
1

There are 1 best solutions below

0
OzBob On

I'm just experimenting with a similar service. Taking angular Array of files, and pushing the items onto the javascript "file-upload".FileList array, but no luck, as the 'files' property is a readonly FileList object.

A pre-packaged solution: http://blueimp.github.io/jQuery-File-Upload/angularjs.html and it has drag and drop on to the whole page working.

This one: http://angular-file-upload.appspot.com/ even has Paste and access to Camera on mobile.

Your solution for adding files to the formData is good and inline with jquery ajaxSubmit form code

Maybe you could create a Plnk to collaborate on ...

formdata.append(a[i].name, a[i].value);