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,
messages: {
'default': 'Drag and drop a file here or click',
'replace': 'Drag and drop or click to replace',
'remove': '删除',
'error': 'Sorry, this file is too large'
},
tpl: {
wrap: '
',
message: '
{{ default }}
',
preview: '
{{ replace }}
',
filename: '
',
clearButton: '',
error: '
{{ error }}
'
}
};
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.imgFileFormats = ['png', 'jpg', 'jpeg', 'gif', 'bmp'];
this.file = null;
this.filename = null;
this.isDisabled = false;
this.onChange = this.onChange.bind(this);
this.clearElement = this.clearElement.bind(this);
this.translate();
this.createElements();
this.setSize();
this.input.on('change', this.onChange);
}
/**
* On change event
*/
Dropify.prototype.onChange = function () {
this.resetPreview();
this.setFilename(this.input.val());
this.readUrl(this.element);
};
/**
* Create dom elements
*/
Dropify.prototype.createElements = function () {
this.input.wrap($(this.settings.tpl.wrap));
this.wrapper = this.input.parent();
var messageWrapper = $(this.settings.tpl.message).insertBefore(this.input);
$(this.settings.tpl.error).appendTo(messageWrapper);
if (this.isTouchDevice() === true) {
this.wrapper.addClass('touch-fallback');
}
if (this.input.attr('disabled')) {
this.isDisabled = true;
this.wrapper.addClass('disabled');
}
this.preview = $(this.settings.tpl.preview);
this.preview.insertAfter(this.input);
if (this.isDisabled === false && this.settings.disableRemove !== 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'));
var defaultFile = this.settings.defaultFile || '';
if (defaultFile.trim() != '') {
this.setFilename(defaultFile);
this.setPreview(defaultFile);
}
};
/**
* Read the file url using FileReader
*
* @param {Object} input
*/
Dropify.prototype.readUrl = function (input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
this.file = input.files[0];
if (this.checkFileSize()) {
reader.onload = function (e) {
this.setPreview(e.target.result, this.file.name);
}.bind(this);
reader.readAsDataURL(this.file);
} else {
this.wrapper.addClass('has-error');
this.resetPreview();
this.clearElement();
}
}
};
/**
* Set the preview and animate it
*
* @param {String} src
*/
Dropify.prototype.setPreview = function (src) {
this.wrapper.removeClass('has-error').addClass('has-preview');
var render = this.preview.children('.dropify-render');
if (this.isImage() === true) {
$('').attr('src', src).appendTo(render);
} else {
$('').attr('class', 'dropify-font-file').appendTo(render);
$('').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();
};
/**
* Get the filename
*
* @param {String} src with path
*
* @return {String} clean filename
*/
Dropify.prototype.getFilename = function (src) {
var filename = src.split('\\').pop();
if (filename == src) {
filename = src.split('/').pop();
}
return src != "" ? filename : '';
};
/**
* Set the filename in the object and in the dom
*
* @param {String} filename
*/
Dropify.prototype.setFilename = function (filename) {
var filename = this.getFilename(filename);
this.filename = filename;
this.filenameWrapper.children('.dropify-filename-inner').html(filename);
};
/**
* Clear the element, events are available
*/
Dropify.prototype.clearElement = function () {
var eventBefore = $.Event("dropify.beforeClear");
this.input.trigger(eventBefore, [this]);
if (eventBefore.result !== false) {
this.file = null;
this.input.val('');
this.resetPreview();
var eventAfter = $.Event("dropify.afterClear");
this.input.trigger(eventAfter, [this]);
}
};
/**
* Set the wrapper height
*/
Dropify.prototype.setSize = 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.filename.split('.').pop().toLowerCase();
};
/**
* Test if the file is an image
*
* @return {Boolean}
*/
Dropify.prototype.isImage = function () {
if (this.imgFileFormats.indexOf(this.getFileType()) != "-1") {
return true;
}
return false;
};
/**
* Translate text if needed.
*/
Dropify.prototype.translate = 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.
*
* @return {Boolean}
*/
Dropify.prototype.checkFileSize = function () {
if (this.maxFileSizeToByte() === 0 || this.file.size <= this.maxFileSizeToByte()) {
return true;
}
return false;
};
/**
* Convert filesize to byte.
*
* @return {Int} value
*/
Dropify.prototype.maxFileSizeToByte = function () {
var value = 0;
if (this.settings.maxFileSize !== 0) {
var unit = this.settings.maxFileSize.slice(-1).toUpperCase(),
kb = 1024,
mb = kb * 1024,
gb = mb * 1024;
if (unit === 'K') {
value = parseFloat(this.settings.maxFileSize) * kb;
} else if (unit === 'M') {
value = parseFloat(this.settings.maxFileSize) * mb;
} else if (unit === 'G') {
value = parseFloat(this.settings.maxFileSize) * gb;
}
}
return value;
};
$.fn[pluginName] = function (options) {
this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Dropify(this, options));
}
});
return this;
};