svoydom/public/assets/plugins/dropify/js/dropify.js
2023-05-17 09:57:20 +03:00

658 lines
17 KiB
JavaScript
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* =============================================================
* dropify v0.2.1 - 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;
}));