0

I am trying to implement a simple file drag and drop functionality in Angular js/MVC.

I created a directive for the drag and drop.

(function (angular, undefined) {
    'use strict';

    angular.module('fileupload', [])
     .directive("myDirective", function ($parse) {
         return {
             restrict: 'A',
             link: fileDropzoneLink
         };
         function fileDropzoneLink(scope, element, attrs) {
             element.bind('dragover', processDragOverOrEnter);
             element.bind('dragenter', processDragOverOrEnter);
             element.bind('dragend', endDragOver);
             element.bind('dragleave', endDragOver);
             element.bind('drop', dropHandler);

             var onImageDrop = $parse(attrs.onImageDrop);

             //When a file is dropped
             var loadFile = function (files) {
                 scope.uploadedFiles = files;
                 scope.$apply(onImageDrop(scope));
             };

             function dropHandler(angularEvent) {
                 var event = angularEvent.originalEvent || angularEvent;
                 var files = event.dataTransfer.files;
                 event.preventDefault();
                 loadFile(files)
             }

             function processDragOverOrEnter(angularEvent) {
                 var event = angularEvent.originalEvent || angularEvent;
                 if (event) {
                     event.preventDefault();
                 }
                 event.dataTransfer.effectAllowed = 'copy';
                 element.addClass('dragging');
                 return false;
             }

             function endDragOver() {
                 element.removeClass('dragging');
             }
         }
     });
}(angular));

This is the template

<div class="dropzone" data-my-Directive on-image-drop="$ctrl.fileDropped()">
Drag and drop pdf files here
</div>

This is my component code

(function (angular, undefined) {
    'use strict';

    angular.module('test', [])
        .component('contactUs', contactUs());

    function contactUs() {
        ContactUs.$inject = ['$scope', '$http'];
        function ContactUs($scope, $http) {
            var ctrl = this;
            ctrl.files = [];
         
            ctrl.services = {
                $scope: $scope,
                $http: $http,
            };
        }

        //file dropped
        ContactUs.prototype.fileDropped = function () {
            var ctrl = this;
            var files = ctrl.services.$scope.uploadedFiles;
            angular.forEach(files, function (file, key) {
                ctrl.files.push(file);
            });
        }


        return {
            controller: ContactUs,
            templateUrl: 'partials/home/contactus/'
        };
    }
}(angular));

Sometimes the drag and drop works absolutely fine without any issue. But some times I get the below issue and the drag and drop does not work and I get the black invalid cursor.

enter image description here

This issue is random and i do not see any errors in the console.

And I also tried other third party components like angular-file-upload https://github.com/nervgh/angular-file-upload and I am seeing the exact same issue with that component also.

1 Answer 1

0

EDIT :

Answer updated for pdf preview. The code is available in the same plunker.

References : Excellent solution by @Michael at https://stackoverflow.com/a/21732039/6347317

In the example above, the response from the http POST is used in "new Blob([response]". In angular-file-upload library, the "response" would be "fileItem._file" property in "uploader.onAfterAddingFile" function. You can console log to check the data these have , so as to understand it better.

Also please note that if PDf viewer is not enabled in chrome, it has to be enabled using this: https://support.google.com/chrome/answer/6213030?hl=en

END EDIT

Since you mentioned that you tried with angular-file-upload library, i have created a plunker with it:

http://plnkr.co/edit/jeYg5fIRaC9wuEYSNOux?p=info

HTML:

<!DOCTYPE html>
    <html ng-app="plunker">
      <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
        <script>document.write('<base href="' + document.location + '" />');</script>
           <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
        <link rel="stylesheet" href="style.css" />
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
        <script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
        <script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-file-upload/2.5.0/angular-file-upload.min.js"></script>
        <script src="app.js"></script>
      </head>

      <body ng-controller="MainCtrl">
                      <div class="col-sm-4">

                        <h3>Select files</h3>

                        <div ng-show="uploader.isHTML5">
                            <!-- 3. nv-file-over uploader="link" over-class="className" -->
                          <div class="well my-drop-zone" style="width:300px" nv-file-drop nv-file-over="" uploader="uploader" 
                          filters="syncFilter">
                               <label>
                              Click here or Drag and Drop file
                                 <input type="file" style="visibility:hidden;" nv-file-select nv-file-over="" uploader="uploader" 
                                 filters="syncFilter" multiple/>
                                </label> 
                                  <div class="progress" style="margin-bottom: 0;">
                                  <div class="progress-bar" role="progressbar" ng-style="{ 'width': uploader.queue[0].progress + '%' }"></div>
                                  </div>
                                <div>{{uploader.queue[0].file.name}}</div>

                                  <div ng-show="showAlert" class="alert alert-warning alert-dismissable">
                                    <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
                                     <strong>Clear the existing file before uploading again!!</strong> 
                                  </div>
                          </div>

                        </div>
                      </div>

      </body>

    </html>

JS:

var app = angular.module('plunker', ['angularFileUpload']);

app.controller('MainCtrl', function($scope,FileUploader) {
var uploader = $scope.uploader = new FileUploader();

        // FILTERS

        // a sync filter
        uploader.filters.push({
            name: 'syncFilter',
            fn: function(item /*{File|FileLikeObject}*/, options) {
                console.log('syncFilter' + this.queue.length);
                return this.queue.length < 1;
            }
        });

        // an async filter
        uploader.filters.push({
            name: 'asyncFilter',
            fn: function(item /*{File|FileLikeObject}*/, options, deferred) {
                console.log('asyncFilter');
                setTimeout(deferred.resolve, 1e3);
            }
        });


uploader.allowNewFiles = true;
uploader.filters.push({
  name:'csvfilter',
  fn: function() {
    return this.allowNewFiles;
}
});

        // CALLBACKS

        uploader.onWhenAddingFileFailed = function(item /*{File|FileLikeObject}*/, filter, options) {
            console.info('onWhenAddingFileFailed', item, filter, options);
            $scope.showAlert=true;
        };


        uploader.onAfterAddingFile = function(fileItem) {

  };
});

It is pretty straight forward and i dont get the error you mentioned. We are actually using this library in one of our Projects. I have also added a filter to restrict upload to only 1 file.

Please check this and let me know how it goes or if you have any doubts in the code.

Sign up to request clarification or add additional context in comments.

6 Comments

thanks vijay but i am still seeing the same issue, i noticed that when i try running the code in the plain html file and running without the visualstudio/iis the files are being dropped on the web page and it works but when i run the same code in visual studio/iis i am seeing the above wierd issue
Oh ok. Then it could be some setup in Visula studio.How are you opening the web page in Visual Studio? Saw this link : stackoverflow.com/questions/15226600/…
Not sure if this is it but can you please look at the Solution at the bottom of the post. Might just be Visual Studio being Visual Studio: devexpress.com/Support/Center/Question/Details/T520060/…
I havent used Visual Studio as an IDE. I mostly use Sublime Text . Since you suspect its a Visual Studio issue, do you have the option to switch your IDE to something else? If yes, please do. Otherwise, I am afraid I dont have any more suggestions, since the code as such is working fine.
hi vijay so finally we decide to use angular file upload . but we also want to implement the pdf preview functionality , can you please advise how do we implement this? any information will be helpfull
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.