123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658 |
- /*!
- * =============================================================
- * dropify v0.2.2 - Override your input files with style.
- * https://github.com/JeremyFagis/dropify
- *
- * (c) 2017 - Jeremy FAGIS <jeremy@fagis.fr> (http://fagis.fr)
- * =============================================================
- */
- ;(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- module.exports = factory(require('jquery'));
- } else {
- root.Dropify = factory(root.jQuery);
- }
- }(this, function($) {
- var pluginName = "dropify";
-
- /**
- * Dropify plugin
- *
- * @param {Object} element
- * @param {Array} options
- */
- function Dropify(element, options) {
- if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
- return;
- }
-
- var defaults = {
- defaultFile: '',
- maxFileSize: 0,
- minWidth: 0,
- maxWidth: 0,
- minHeight: 0,
- maxHeight: 0,
- showRemove: true,
- showLoader: true,
- showErrors: true,
- errorTimeout: 3000,
- errorsPosition: 'overlay',
- imgFileExtensions: ['png', 'jpg', 'jpeg', 'gif', 'bmp'],
- maxFileSizePreview: "5M",
- allowedFormats: ['portrait', 'square', 'landscape'],
- allowedFileExtensions: ['*'],
- messages: {
- 'default': 'Drag and drop a file here or click',
- 'replace': 'Drag and drop or click to replace',
- 'remove': 'Remove',
- 'error': 'Ooops, something wrong happended.'
- },
- error: {
- 'fileSize': 'The file size is too big ({{ value }} max).',
- 'minWidth': 'The image width is too small ({{ value }}}px min).',
- 'maxWidth': 'The image width is too big ({{ value }}}px max).',
- 'minHeight': 'The image height is too small ({{ value }}}px min).',
- 'maxHeight': 'The image height is too big ({{ value }}px max).',
- 'imageFormat': 'The image format is not allowed ({{ value }} only).',
- 'fileExtension': 'The file is not allowed ({{ value }} only).'
- },
- tpl: {
- wrap: '<div class="dropify-wrapper"></div>',
- loader: '<div class="dropify-loader"></div>',
- message: '<div class="dropify-message"><span class="file-icon" /> <p>{{ default }}</p></div>',
- 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>',
- filename: '<p class="dropify-filename"><span class="dropify-filename-inner"></span></p>',
- clearButton: '<button type="button" class="dropify-clear">{{ remove }}</button>',
- errorLine: '<p class="dropify-error">{{ error }}</p>',
- errorsContainer: '<div class="dropify-errors-container"><ul></ul></div>'
- }
- };
-
- this.element = element;
- this.input = $(this.element);
- this.wrapper = null;
- this.preview = null;
- this.filenameWrapper = null;
- this.settings = $.extend(true, defaults, options, this.input.data());
- this.errorsEvent = $.Event('dropify.errors');
- this.isDisabled = false;
- this.isInit = false;
- this.file = {
- object: null,
- name: null,
- size: null,
- width: null,
- height: null,
- type: null
- };
-
- if (!Array.isArray(this.settings.allowedFormats)) {
- this.settings.allowedFormats = this.settings.allowedFormats.split(' ');
- }
-
- if (!Array.isArray(this.settings.allowedFileExtensions)) {
- this.settings.allowedFileExtensions = this.settings.allowedFileExtensions.split(' ');
- }
-
- this.onChange = this.onChange.bind(this);
- this.clearElement = this.clearElement.bind(this);
- this.onFileReady = this.onFileReady.bind(this);
-
- this.translateMessages();
- this.createElements();
- this.setContainerSize();
-
- this.errorsEvent.errors = [];
-
- this.input.on('change', this.onChange);
- }
-
- /**
- * On change event
- */
- Dropify.prototype.onChange = function()
- {
- this.resetPreview();
- this.readFile(this.element);
- };
-
- /**
- * Create dom elements
- */
- Dropify.prototype.createElements = function()
- {
- this.isInit = true;
- this.input.wrap($(this.settings.tpl.wrap));
- this.wrapper = this.input.parent();
-
- var messageWrapper = $(this.settings.tpl.message).insertBefore(this.input);
- $(this.settings.tpl.errorLine).appendTo(messageWrapper);
-
- if (this.isTouchDevice() === true) {
- this.wrapper.addClass('touch-fallback');
- }
-
- if (this.input.attr('disabled')) {
- this.isDisabled = true;
- this.wrapper.addClass('disabled');
- }
-
- if (this.settings.showLoader === true) {
- this.loader = $(this.settings.tpl.loader);
- this.loader.insertBefore(this.input);
- }
-
- this.preview = $(this.settings.tpl.preview);
- this.preview.insertAfter(this.input);
-
- if (this.isDisabled === false && this.settings.showRemove === true) {
- this.clearButton = $(this.settings.tpl.clearButton);
- this.clearButton.insertAfter(this.input);
- this.clearButton.on('click', this.clearElement);
- }
-
- this.filenameWrapper = $(this.settings.tpl.filename);
- this.filenameWrapper.prependTo(this.preview.find('.dropify-infos-inner'));
-
- if (this.settings.showErrors === true) {
- this.errorsContainer = $(this.settings.tpl.errorsContainer);
-
- if (this.settings.errorsPosition === 'outside') {
- this.errorsContainer.insertAfter(this.wrapper);
- } else {
- this.errorsContainer.insertBefore(this.input);
- }
- }
-
- var defaultFile = this.settings.defaultFile || '';
-
- if (defaultFile.trim() !== '') {
- this.file.name = this.cleanFilename(defaultFile);
- this.setPreview(this.isImage(), defaultFile);
- }
- };
-
- /**
- * Read the file using FileReader
- *
- * @param {Object} input
- */
- Dropify.prototype.readFile = function(input)
- {
- if (input.files && input.files[0]) {
- var reader = new FileReader();
- var image = new Image();
- var file = input.files[0];
- var srcBase64 = null;
- var _this = this;
- var eventFileReady = $.Event("dropify.fileReady");
-
- this.clearErrors();
- this.showLoader();
- this.setFileInformations(file);
- this.errorsEvent.errors = [];
- this.checkFileSize();
- this.isFileExtensionAllowed();
-
- if (this.isImage() && this.file.size < this.sizeToByte(this.settings.maxFileSizePreview)) {
- this.input.on('dropify.fileReady', this.onFileReady);
- reader.readAsDataURL(file);
- reader.onload = function(_file) {
- srcBase64 = _file.target.result;
- image.src = _file.target.result;
- image.onload = function() {
- _this.setFileDimensions(this.width, this.height);
- _this.validateImage();
- _this.input.trigger(eventFileReady, [true, srcBase64]);
- };
-
- }.bind(this);
- } else {
- this.onFileReady(false);
- }
- }
- };
-
- /**
- * On file ready to show
- *
- * @param {Event} event
- * @param {Bool} previewable
- * @param {String} src
- */
- Dropify.prototype.onFileReady = function(event, previewable, src)
- {
- this.input.off('dropify.fileReady', this.onFileReady);
-
- if (this.errorsEvent.errors.length === 0) {
- this.setPreview(previewable, src);
- } else {
- this.input.trigger(this.errorsEvent, [this]);
- for (var i = this.errorsEvent.errors.length - 1; i >= 0; i--) {
- var errorNamespace = this.errorsEvent.errors[i].namespace;
- var errorKey = errorNamespace.split('.').pop();
- this.showError(errorKey);
- }
-
- if (typeof this.errorsContainer !== "undefined") {
- this.errorsContainer.addClass('visible');
-
- var errorsContainer = this.errorsContainer;
- setTimeout(function(){ errorsContainer.removeClass('visible'); }, this.settings.errorTimeout);
- }
-
- this.wrapper.addClass('has-error');
- this.resetPreview();
- this.clearElement();
- }
- };
-
- /**
- * Set file informations
- *
- * @param {File} file
- */
- Dropify.prototype.setFileInformations = function(file)
- {
- this.file.object = file;
- this.file.name = file.name;
- this.file.size = file.size;
- this.file.type = file.type;
- this.file.width = null;
- this.file.height = null;
- };
-
- /**
- * Set file dimensions
- *
- * @param {Int} width
- * @param {Int} height
- */
- Dropify.prototype.setFileDimensions = function(width, height)
- {
- this.file.width = width;
- this.file.height = height;
- };
-
- /**
- * Set the preview and animate it
- *
- * @param {String} src
- */
- Dropify.prototype.setPreview = function(previewable, src)
- {
- this.wrapper.removeClass('has-error').addClass('has-preview');
- this.filenameWrapper.children('.dropify-filename-inner').html(this.file.name);
- var render = this.preview.children('.dropify-render');
-
- this.hideLoader();
-
- if (previewable === true) {
- var imgTag = $('<img />').attr('src', src);
-
- if (this.settings.height) {
- imgTag.css("max-height", this.settings.height);
- }
-
- imgTag.appendTo(render);
- } else {
- $('<i />').attr('class', 'dropify-font-file').appendTo(render);
- $('<span class="dropify-extension" />').html(this.getFileType()).appendTo(render);
- }
- this.preview.fadeIn();
- };
-
- /**
- * Reset the preview
- */
- Dropify.prototype.resetPreview = function()
- {
- this.wrapper.removeClass('has-preview');
- var render = this.preview.children('.dropify-render');
- render.find('.dropify-extension').remove();
- render.find('i').remove();
- render.find('img').remove();
- this.preview.hide();
- this.hideLoader();
- };
-
- /**
- * Clean the src and get the filename
- *
- * @param {String} src
- *
- * @return {String} filename
- */
- Dropify.prototype.cleanFilename = function(src)
- {
- var filename = src.split('\\').pop();
- if (filename == src) {
- filename = src.split('/').pop();
- }
-
- return src !== "" ? filename : '';
- };
-
- /**
- * Clear the element, events are available
- */
- Dropify.prototype.clearElement = function()
- {
- if (this.errorsEvent.errors.length === 0) {
- var eventBefore = $.Event("dropify.beforeClear");
- this.input.trigger(eventBefore, [this]);
-
- if (eventBefore.result !== false) {
- this.resetFile();
- this.input.val('');
- this.resetPreview();
-
- this.input.trigger($.Event("dropify.afterClear"), [this]);
- }
- } else {
- this.resetFile();
- this.input.val('');
- this.resetPreview();
- }
- };
-
- /**
- * Reset file informations
- */
- Dropify.prototype.resetFile = function()
- {
- this.file.object = null;
- this.file.name = null;
- this.file.size = null;
- this.file.type = null;
- this.file.width = null;
- this.file.height = null;
- };
-
- /**
- * Set the container height
- */
- Dropify.prototype.setContainerSize = function()
- {
- if (this.settings.height) {
- this.wrapper.height(this.settings.height);
- }
- };
-
- /**
- * Test if it's touch screen
- *
- * @return {Boolean}
- */
- Dropify.prototype.isTouchDevice = function()
- {
- return (('ontouchstart' in window) ||
- (navigator.MaxTouchPoints > 0) ||
- (navigator.msMaxTouchPoints > 0));
- };
-
- /**
- * Get the file type.
- *
- * @return {String}
- */
- Dropify.prototype.getFileType = function()
- {
- return this.file.name.split('.').pop().toLowerCase();
- };
-
- /**
- * Test if the file is an image
- *
- * @return {Boolean}
- */
- Dropify.prototype.isImage = function()
- {
- if (this.settings.imgFileExtensions.indexOf(this.getFileType()) != "-1") {
- return true;
- }
-
- return false;
- };
-
- /**
- * Test if the file extension is allowed
- *
- * @return {Boolean}
- */
- Dropify.prototype.isFileExtensionAllowed = function () {
-
- if (this.settings.allowedFileExtensions.indexOf('*') != "-1" ||
- this.settings.allowedFileExtensions.indexOf(this.getFileType()) != "-1") {
- return true;
- }
- this.pushError("fileExtension");
-
- return false;
- };
-
- /**
- * Translate messages if needed.
- */
- Dropify.prototype.translateMessages = function()
- {
- for (var name in this.settings.tpl) {
- for (var key in this.settings.messages) {
- this.settings.tpl[name] = this.settings.tpl[name].replace('{{ ' + key + ' }}', this.settings.messages[key]);
- }
- }
- };
-
- /**
- * Check the limit filesize.
- */
- Dropify.prototype.checkFileSize = function()
- {
- if (this.sizeToByte(this.settings.maxFileSize) !== 0 && this.file.size > this.sizeToByte(this.settings.maxFileSize)) {
- this.pushError("fileSize");
- }
- };
-
- /**
- * Convert filesize to byte.
- *
- * @return {Int} value
- */
- Dropify.prototype.sizeToByte = function(size)
- {
- var value = 0;
-
- if (size !== 0) {
- var unit = size.slice(-1).toUpperCase(),
- kb = 1024,
- mb = kb * 1024,
- gb = mb * 1024;
-
- if (unit === 'K') {
- value = parseFloat(size) * kb;
- } else if (unit === 'M') {
- value = parseFloat(size) * mb;
- } else if (unit === 'G') {
- value = parseFloat(size) * gb;
- }
- }
-
- return value;
- };
-
- /**
- * Validate image dimensions and format
- */
- Dropify.prototype.validateImage = function()
- {
- if (this.settings.minWidth !== 0 && this.settings.minWidth >= this.file.width) {
- this.pushError("minWidth");
- }
-
- if (this.settings.maxWidth !== 0 && this.settings.maxWidth <= this.file.width) {
- this.pushError("maxWidth");
- }
-
- if (this.settings.minHeight !== 0 && this.settings.minHeight >= this.file.height) {
- this.pushError("minHeight");
- }
-
- if (this.settings.maxHeight !== 0 && this.settings.maxHeight <= this.file.height) {
- this.pushError("maxHeight");
- }
-
- if (this.settings.allowedFormats.indexOf(this.getImageFormat()) == "-1") {
- this.pushError("imageFormat");
- }
- };
-
- /**
- * Get image format.
- *
- * @return {String}
- */
- Dropify.prototype.getImageFormat = function()
- {
- if (this.file.width == this.file.height) {
- return "square";
- }
-
- if (this.file.width < this.file.height) {
- return "portrait";
- }
-
- if (this.file.width > this.file.height) {
- return "landscape";
- }
- };
-
- /**
- * Push error
- *
- * @param {String} errorKey
- */
- Dropify.prototype.pushError = function(errorKey) {
- var e = $.Event("dropify.error." + errorKey);
- this.errorsEvent.errors.push(e);
- this.input.trigger(e, [this]);
- };
-
- /**
- * Clear errors
- */
- Dropify.prototype.clearErrors = function()
- {
- if (typeof this.errorsContainer !== "undefined") {
- this.errorsContainer.children('ul').html('');
- }
- };
-
- /**
- * Show error in DOM
- *
- * @param {String} errorKey
- */
- Dropify.prototype.showError = function(errorKey)
- {
- if (typeof this.errorsContainer !== "undefined") {
- this.errorsContainer.children('ul').append('<li>' + this.getError(errorKey) + '</li>');
- }
- };
-
- /**
- * Get error message
- *
- * @return {String} message
- */
- Dropify.prototype.getError = function(errorKey)
- {
- var error = this.settings.error[errorKey],
- value = '';
-
- if (errorKey === 'fileSize') {
- value = this.settings.maxFileSize;
- } else if (errorKey === 'minWidth') {
- value = this.settings.minWidth;
- } else if (errorKey === 'maxWidth') {
- value = this.settings.maxWidth;
- } else if (errorKey === 'minHeight') {
- value = this.settings.minHeight;
- } else if (errorKey === 'maxHeight') {
- value = this.settings.maxHeight;
- } else if (errorKey === 'imageFormat') {
- value = this.settings.allowedFormats.join(', ');
- } else if (errorKey === 'fileExtension') {
- value = this.settings.allowedFileExtensions.join(', ');
- }
-
- if (value !== '') {
- return error.replace('{{ value }}', value);
- }
-
- return error;
- };
-
- /**
- * Show the loader
- */
- Dropify.prototype.showLoader = function()
- {
- if (typeof this.loader !== "undefined") {
- this.loader.show();
- }
- };
-
- /**
- * Hide the loader
- */
- Dropify.prototype.hideLoader = function()
- {
- if (typeof this.loader !== "undefined") {
- this.loader.hide();
- }
- };
-
- /**
- * Destroy dropify
- */
- Dropify.prototype.destroy = function()
- {
- this.input.siblings().remove();
- this.input.unwrap();
- this.isInit = false;
- };
-
- /**
- * Init dropify
- */
- Dropify.prototype.init = function()
- {
- this.createElements();
- };
-
- /**
- * Test if element is init
- */
- Dropify.prototype.isDropified = function()
- {
- return this.isInit;
- };
-
- $.fn[pluginName] = function(options) {
- this.each(function() {
- if (!$.data(this, pluginName)) {
- $.data(this, pluginName, new Dropify(this, options));
- }
- });
-
- return this;
- };
-
-
- return Dropify;
- }));
-
|