sathish kumar
sathish kumar

Reputation: 936

drag and upload multiple images in a box in angular

Any best example is there for drag and upload the image in angularjs or angular any version? I didn't find anything in angular.

jsfiddle

I have this example, But my requirement is, I have one + button in a box. If I drag and drop any image on that + button it should upload and one more box should open next to that box. Please see the image.

Image

Image

Image

Like this I need to upload more images. If any fiddle or examples are there, please anyone send me.

// Generated by CoffeeScript 1.6.3
// Couldn't get JSFiddle to work with CoffeeScript as advertised - Link to CoffeeScript Gist: https://gist.github.com/lsiv568/5623361
(function() {
  'use strict';
  angular.module('reusableThings', []).directive('fileDropzone', function() {
    return {
      restrict: 'A',
      scope: {
        file: '=',
        fileName: '='
      },
      link: function(scope, element, attrs) {
        var checkSize, isTypeValid, processDragOverOrEnter, validMimeTypes;
        processDragOverOrEnter = function(event) {
          if (event != null) {
            event.preventDefault();
          }
          event.dataTransfer.effectAllowed = 'copy';
          return false;
        };
        validMimeTypes = attrs.fileDropzone;
        checkSize = function(size) {
          var _ref;
          if (((_ref = attrs.maxFileSize) === (void 0) || _ref === '') || (size / 1024) / 1024 < attrs.maxFileSize) {
            return true;
          } else {
            alert("File must be smaller than " + attrs.maxFileSize + " MB");
            return false;
          }
        };
        isTypeValid = function(type) {
          if ((validMimeTypes === (void 0) || validMimeTypes === '') || validMimeTypes.indexOf(type) > -1) {
            return true;
          } else {
            alert("Invalid file type.  File must be one of following types " + validMimeTypes);
            return false;
          }
        };
        element.bind('dragover', processDragOverOrEnter);
        element.bind('dragenter', processDragOverOrEnter);
        return element.bind('drop', function(event) {
          var file, name, reader, size, type;
          if (event != null) {
            event.preventDefault();
          }
          reader = new FileReader();
          reader.onload = function(evt) {
            if (checkSize(size) && isTypeValid(type)) {
              return scope.$apply(function() {
                scope.file = evt.target.result;
                if (angular.isString(scope.fileName)) {
                  return scope.fileName = name;
                }
              });
            }
          };
          file = event.dataTransfer.files[0];
          name = file.name;
          type = file.type;
          size = file.size;
          reader.readAsDataURL(file);
          return false;
        });
      }
    };
  });

}).call(this);

(function() {
  'use strict';
  angular.module('reusableThings').controller('TestCtrl', function($scope) {
    $scope.image = null
    $scope.imageFileName = ''
  });

}).call(this);
.dropzone {
  width: 250px;
  height: 45px;
  border: 1px solid #ccc;
  text-align: center;
  padding: 30px;
  margin: 20px;
  font-family: Arial;
  position: absolute;
  top: 0;
  left: 0;
}

.image-container {
  width: 312px;
  height: 312px;
  margin: 20px;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
}

.image-container img {
  max-width: 100%;
}

.file-name {
  font-family: Arial;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="reusableThings" ng-controller="TestCtrl">
  <div class="dropzone" file-dropzone="[image/png, image/jpeg, image/gif]" file="image" file-name="imageFileName" data-max-file-size="3">
    <span>Drop Image Here</span>
  </div>
  <div class="image-container" ng-show="image">
    <img ng-src={{image}} />
    <span class="file-name">{{imageFileName}}</span>
  </div>
</div>

Upvotes: 2

Views: 2096

Answers (1)

Mosh Feu
Mosh Feu

Reputation: 29337

Let's agree about some steps:

  1. To support multiple images in the scope, obviously, you should keep an array of images.
  2. We want to re-use the dropzone so after a user will drop an image to it, the image will be next to it and the user could drop another image. So, we don't want to handle the scope, we will parse the file (src and name) and call a callback onDrop with these parameters, and the control itself will handle it.

Please, read my comment in the code

// Generated by CoffeeScript 1.6.3
// Couldn't get JSFiddle to work with CoffeeScript as advertised - Link to CoffeeScript Gist: https://gist.github.com/lsiv568/5623361
(function() {
  'use strict';
  angular.module('reusableThings', []).directive('fileDropzone', function() {
    return {
      restrict: 'A',
      scope: {
        // get only a drop callback which will be called with the image object
        image: '='
      },
      link: function(scope, element, attrs) {
        var checkSize, isTypeValid, processDragOverOrEnter, validMimeTypes;
        processDragOverOrEnter = function(event) {
          if (event != null) {
            event.preventDefault();
          }
          event.dataTransfer.effectAllowed = 'copy';
          return false;
        };
        validMimeTypes = attrs.fileDropzone;
        checkSize = function(size) {
          var _ref;
          if (((_ref = attrs.maxFileSize) === (void 0) || _ref === '') || (size / 1024) / 1024 < attrs.maxFileSize) {
            return true;
          } else {
            alert("File must be smaller than " + attrs.maxFileSize + " MB");
            return false;
          }
        };
        isTypeValid = function(type) {
          if ((validMimeTypes === (void 0) || validMimeTypes === '') || validMimeTypes.indexOf(type) > -1) {
            return true;
          } else {
            alert("Invalid file type.  File must be one of following types " + validMimeTypes);
            return false;
          }
        };
        element.bind('dragover', processDragOverOrEnter);
        element.bind('dragenter', processDragOverOrEnter);
        return element.bind('drop', function(event) {
          var file, name, reader, size, type;
          if (event != null) {
            event.preventDefault();
          }
          reader = new FileReader();
          reader.onload = function(evt) {
            if (checkSize(size) && isTypeValid(type)) {
              return scope.$apply(function() {
                // call the callback with the data
                scope.image.image = evt.target.result,
                scope.image.imageFileName = name;
              });
            }
          };
          file = event.dataTransfer.files[0];
          name = file.name;
          type = file.type;
          size = file.size;
          reader.readAsDataURL(file);
          return false;
        });
      }
    };
  });

}).call(this);

(function() {
  'use strict';
  angular.module('reusableThings').controller('TestCtrl', function($scope) {
    // keep in array instead of variables on the scope
    $scope.images = [];
    $scope.drop = (image) => {
//      console.log(image);
      $scope.images.unshift(image);
    }
  });

}).call(this);
.container {
  position: relative;
  width: 312px;
  height: 312px;
  margin: 20px;
}

.dropzone {
  border: 1px solid #ccc;
  text-align: center;
  padding: 30px;
  font-family: Arial;
  position: absolute;
  top: 0;
  left: 0;
  width: 250px;
  height: 45px;
}

.image-container {
  width: 100%;
  height: 100%;
  margin: 20px;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
}

.image-container img {
  max-width: 100%;
}

.file-name {
  font-family: Arial;
}

.button {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  text-align: center;
  border: 1px solid;
  font-size: 25px;
  color: #aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="reusableThings" ng-controller="TestCtrl">
  <div class="container" ng-repeat="image in images">
    <div ng-if="!image.image" class="dropzone" file-dropzone="[image/png, image/jpeg, image/gif]" image="image" data-max-file-size="3">
      <span>Drop Image Here</span>
    </div>
    <div class="image-container" ng-if="image.image">
      <img ng-src={{image.image}} />
      <span class="file-name">{{image.imageFileName}}</span>
    </div>
  </div>
  <button class="button" ng-click="images.push({})">+</button>
</div>

It could be a little complex change in the line of thought. If anything is not clear, let me know.

Upvotes: 2

Related Questions