angular-file-upload.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /**!
  2. * AngularJS file upload/drop directive with http post and progress
  3. * @author Danial <danial.farid@gmail.com>
  4. * @version 1.1.10
  5. */
  6. (function() {
  7. var angularFileUpload = angular.module('angularFileUpload', []);
  8. angularFileUpload.service('$upload', ['$http', '$rootScope', '$timeout', function($http, $rootScope, $timeout) {
  9. this.upload = function(config) {
  10. config.method = config.method || 'POST';
  11. config.headers = config.headers || {};
  12. config.headers['Content-Type'] = undefined;
  13. config.transformRequest = config.transformRequest || $http.defaults.transformRequest;
  14. var formData = new FormData();
  15. if (config.data) {
  16. for (var key in config.data) {
  17. var val = config.data[key];
  18. if (!config.formDataAppender) {
  19. if (typeof config.transformRequest == 'function') {
  20. val = config.transformRequest(val);
  21. } else {
  22. for (var i = 0; i < config.transformRequest.length; i++) {
  23. var fn = config.transformRequest[i];
  24. if (typeof fn == 'function') {
  25. val = fn(val);
  26. }
  27. }
  28. }
  29. formData.append(key, val);
  30. } else {
  31. config.formDataAppender(formData, key, val);
  32. }
  33. }
  34. }
  35. config.transformRequest = angular.identity;
  36. formData.append(config.fileFormDataName || 'file', config.file, config.file.name);
  37. formData['__setXHR_'] = function(xhr) {
  38. config.__XHR = xhr;
  39. xhr.upload.addEventListener('progress', function(e) {
  40. if (config.progress) {
  41. $timeout(function() {
  42. config.progress(e);
  43. });
  44. }
  45. }, false);
  46. //fix for firefox not firing upload progress end
  47. xhr.upload.addEventListener('load', function(e) {
  48. if (e.lengthComputable) {
  49. $timeout(function() {
  50. config.progress(e);
  51. });
  52. }
  53. }, false);
  54. };
  55. config.data = formData;
  56. var promise = $http(config);
  57. promise.progress = function(fn) {
  58. config.progress = fn;
  59. return promise;
  60. };
  61. promise.abort = function() {
  62. if (config.__XHR) {
  63. $timeout(function() {
  64. config.__XHR.abort();
  65. });
  66. }
  67. return promise;
  68. };
  69. promise.then = (function(promise, origThen) {
  70. return function(s, e, p) {
  71. config.progress = p || config.progress;
  72. origThen.apply(promise, [s, e, p]);
  73. return promise;
  74. };
  75. })(promise, promise.then);
  76. return promise;
  77. };
  78. }]);
  79. angularFileUpload.directive('ngFileSelect', [ '$parse', '$http', '$timeout', function($parse, $http, $timeout) {
  80. return function(scope, elem, attr) {
  81. var fn = $parse(attr['ngFileSelect']);
  82. elem.bind('change', function(evt) {
  83. var files = [], fileList, i;
  84. fileList = evt.target.files;
  85. if (fileList != null) {
  86. for (i = 0; i < fileList.length; i++) {
  87. files.push(fileList.item(i));
  88. }
  89. }
  90. $timeout(function() {
  91. fn(scope, {
  92. $files : files,
  93. $event : evt
  94. });
  95. });
  96. });
  97. elem.bind('click', function(){
  98. this.value = null;
  99. });
  100. };
  101. } ]);
  102. angularFileUpload.directive('ngFileDropAvailable', [ '$parse', '$http', '$timeout', function($parse, $http, $timeout) {
  103. return function(scope, elem, attr) {
  104. if ('draggable' in document.createElement('span')) {
  105. var fn = $parse(attr['ngFileDropAvailable']);
  106. $timeout(function() {
  107. fn(scope);
  108. });
  109. }
  110. };
  111. } ]);
  112. angularFileUpload.directive('ngFileDrop', [ '$parse', '$http', '$timeout', function($parse, $http, $timeout) {
  113. return function(scope, elem, attr) {
  114. if ('draggable' in document.createElement('span')) {
  115. var fn = $parse(attr['ngFileDrop']);
  116. elem[0].addEventListener("dragover", function(evt) {
  117. evt.stopPropagation();
  118. evt.preventDefault();
  119. elem.addClass(attr['ngFileDragOverClass'] || "dragover");
  120. }, false);
  121. elem[0].addEventListener("dragleave", function(evt) {
  122. elem.removeClass(attr['ngFileDragOverClass'] || "dragover");
  123. }, false);
  124. elem[0].addEventListener("drop", function(evt) {
  125. evt.stopPropagation();
  126. evt.preventDefault();
  127. elem.removeClass(attr['ngFileDragOverClass'] || "dragover");
  128. var files = [], fileList = evt.dataTransfer.files, i;
  129. if (fileList != null) {
  130. for (i = 0; i < fileList.length; i++) {
  131. files.push(fileList.item(i));
  132. }
  133. }
  134. $timeout(function() {
  135. fn(scope, {
  136. $files : files,
  137. $event : evt
  138. });
  139. });
  140. }, false);
  141. }
  142. };
  143. } ]);
  144. })();