dropify.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. var pluginName = "dropify";
  2. /**
  3. * Dropify plugin
  4. * @param {Object} element
  5. * @param {Array} options
  6. */
  7. function Dropify(element, options) {
  8. if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
  9. return;
  10. }
  11. var defaults = {
  12. defaultFile: '',
  13. maxFileSize: 0,
  14. messages: {
  15. 'default': 'Drag and drop a file here or click',
  16. 'replace': 'Drag and drop or click to replace',
  17. 'remove': '删除',
  18. 'error': 'Sorry, this file is too large'
  19. },
  20. tpl: {
  21. wrap: '<div class="dropify-wrapper"></div>',
  22. message: '<div class="dropify-message"><span class="file-icon" /> <p>{{ default }}</p></div>',
  23. preview: '<div class="dropify-preview"><span class="dropify-render"></span><div class="dropify-infos"><div class="dropify-infos-inner"><p class="dropify-infos-message">{{ replace }}</p></div></div></div>',
  24. filename: '<p class="dropify-filename"><span class="file-icon"></span> <span class="dropify-filename-inner"></span></p>',
  25. clearButton: '<button type="button" class="dropify-clear">{{ remove }}</button>',
  26. error: '<p class="dropify-error">{{ error }}</p>'
  27. }
  28. };
  29. this.element = element;
  30. this.input = $(this.element);
  31. this.wrapper = null;
  32. this.preview = null;
  33. this.filenameWrapper = null;
  34. this.settings = $.extend(true, defaults, options, this.input.data());
  35. this.imgFileFormats = ['png', 'jpg', 'jpeg', 'gif', 'bmp'];
  36. this.file = null;
  37. this.filename = null;
  38. this.isDisabled = false;
  39. this.onChange = this.onChange.bind(this);
  40. this.clearElement = this.clearElement.bind(this);
  41. this.translate();
  42. this.createElements();
  43. this.setSize();
  44. this.input.on('change', this.onChange);
  45. }
  46. /**
  47. * On change event
  48. */
  49. Dropify.prototype.onChange = function () {
  50. this.resetPreview();
  51. this.setFilename(this.input.val());
  52. this.readUrl(this.element);
  53. };
  54. /**
  55. * Create dom elements
  56. */
  57. Dropify.prototype.createElements = function () {
  58. this.input.wrap($(this.settings.tpl.wrap));
  59. this.wrapper = this.input.parent();
  60. var messageWrapper = $(this.settings.tpl.message).insertBefore(this.input);
  61. $(this.settings.tpl.error).appendTo(messageWrapper);
  62. if (this.isTouchDevice() === true) {
  63. this.wrapper.addClass('touch-fallback');
  64. }
  65. if (this.input.attr('disabled')) {
  66. this.isDisabled = true;
  67. this.wrapper.addClass('disabled');
  68. }
  69. this.preview = $(this.settings.tpl.preview);
  70. this.preview.insertAfter(this.input);
  71. if (this.isDisabled === false && this.settings.disableRemove !== true) {
  72. this.clearButton = $(this.settings.tpl.clearButton);
  73. this.clearButton.insertAfter(this.input);
  74. this.clearButton.on('click', this.clearElement);
  75. }
  76. this.filenameWrapper = $(this.settings.tpl.filename);
  77. this.filenameWrapper.prependTo(this.preview.find('.dropify-infos-inner'));
  78. var defaultFile = this.settings.defaultFile || '';
  79. if (defaultFile.trim() != '') {
  80. this.setFilename(defaultFile);
  81. this.setPreview(defaultFile);
  82. }
  83. };
  84. /**
  85. * Read the file url using FileReader
  86. *
  87. * @param {Object} input
  88. */
  89. Dropify.prototype.readUrl = function (input) {
  90. if (input.files && input.files[0]) {
  91. var reader = new FileReader();
  92. this.file = input.files[0];
  93. if (this.checkFileSize()) {
  94. reader.onload = function (e) {
  95. this.setPreview(e.target.result, this.file.name);
  96. }.bind(this);
  97. reader.readAsDataURL(this.file);
  98. } else {
  99. this.wrapper.addClass('has-error');
  100. this.resetPreview();
  101. this.clearElement();
  102. }
  103. }
  104. };
  105. /**
  106. * Set the preview and animate it
  107. *
  108. * @param {String} src
  109. */
  110. Dropify.prototype.setPreview = function (src) {
  111. this.wrapper.removeClass('has-error').addClass('has-preview');
  112. var render = this.preview.children('.dropify-render');
  113. if (this.isImage() === true) {
  114. $('<img />').attr('src', src).appendTo(render);
  115. } else {
  116. $('<i />').attr('class', 'dropify-font-file').appendTo(render);
  117. $('<span class="dropify-extension" />').html(this.getFileType()).appendTo(render);
  118. }
  119. this.preview.fadeIn();
  120. };
  121. /**
  122. * Reset the preview
  123. */
  124. Dropify.prototype.resetPreview = function () {
  125. this.wrapper.removeClass('has-preview');
  126. var render = this.preview.children('.dropify-render');
  127. render.find('.dropify-extension').remove();
  128. render.find('i').remove();
  129. render.find('img').remove();
  130. this.preview.hide();
  131. };
  132. /**
  133. * Get the filename
  134. *
  135. * @param {String} src with path
  136. *
  137. * @return {String} clean filename
  138. */
  139. Dropify.prototype.getFilename = function (src) {
  140. var filename = src.split('\\').pop();
  141. if (filename == src) {
  142. filename = src.split('/').pop();
  143. }
  144. return src != "" ? filename : '';
  145. };
  146. /**
  147. * Set the filename in the object and in the dom
  148. *
  149. * @param {String} filename
  150. */
  151. Dropify.prototype.setFilename = function (filename) {
  152. var filename = this.getFilename(filename);
  153. this.filename = filename;
  154. this.filenameWrapper.children('.dropify-filename-inner').html(filename);
  155. };
  156. /**
  157. * Clear the element, events are available
  158. */
  159. Dropify.prototype.clearElement = function () {
  160. var eventBefore = $.Event("dropify.beforeClear");
  161. this.input.trigger(eventBefore, [this]);
  162. if (eventBefore.result !== false) {
  163. this.file = null;
  164. this.input.val('');
  165. this.resetPreview();
  166. var eventAfter = $.Event("dropify.afterClear");
  167. this.input.trigger(eventAfter, [this]);
  168. }
  169. };
  170. /**
  171. * Set the wrapper height
  172. */
  173. Dropify.prototype.setSize = function () {
  174. if (this.settings.height) {
  175. this.wrapper.height(this.settings.height);
  176. }
  177. };
  178. /**
  179. * Test if it's touch screen
  180. *
  181. * @return {Boolean}
  182. */
  183. Dropify.prototype.isTouchDevice = function () {
  184. return (('ontouchstart' in window)
  185. || (navigator.MaxTouchPoints > 0)
  186. || (navigator.msMaxTouchPoints > 0));
  187. };
  188. /**
  189. * Get the file type.
  190. * @return {String}
  191. */
  192. Dropify.prototype.getFileType = function () {
  193. return this.filename.split('.').pop().toLowerCase();
  194. };
  195. /**
  196. * Test if the file is an image
  197. *
  198. * @return {Boolean}
  199. */
  200. Dropify.prototype.isImage = function () {
  201. if (this.imgFileFormats.indexOf(this.getFileType()) != "-1") {
  202. return true;
  203. }
  204. return false;
  205. };
  206. /**
  207. * Translate text if needed.
  208. */
  209. Dropify.prototype.translate = function () {
  210. for (var name in this.settings.tpl) {
  211. for (var key in this.settings.messages) {
  212. this.settings.tpl[name] = this.settings.tpl[name].replace('{{ ' + key + ' }}', this.settings.messages[key]);
  213. }
  214. }
  215. };
  216. /**
  217. * Check the limit filesize.
  218. *
  219. * @return {Boolean}
  220. */
  221. Dropify.prototype.checkFileSize = function () {
  222. if (this.maxFileSizeToByte() === 0 || this.file.size <= this.maxFileSizeToByte()) {
  223. return true;
  224. }
  225. return false;
  226. };
  227. /**
  228. * Convert filesize to byte.
  229. *
  230. * @return {Int} value
  231. */
  232. Dropify.prototype.maxFileSizeToByte = function () {
  233. var value = 0;
  234. if (this.settings.maxFileSize !== 0) {
  235. var unit = this.settings.maxFileSize.slice(-1).toUpperCase(),
  236. kb = 1024,
  237. mb = kb * 1024,
  238. gb = mb * 1024;
  239. if (unit === 'K') {
  240. value = parseFloat(this.settings.maxFileSize) * kb;
  241. } else if (unit === 'M') {
  242. value = parseFloat(this.settings.maxFileSize) * mb;
  243. } else if (unit === 'G') {
  244. value = parseFloat(this.settings.maxFileSize) * gb;
  245. }
  246. }
  247. return value;
  248. };
  249. $.fn[pluginName] = function (options) {
  250. this.each(function () {
  251. if (!$.data(this, "plugin_" + pluginName)) {
  252. $.data(this, "plugin_" + pluginName, new Dropify(this, options));
  253. }
  254. });
  255. return this;
  256. };