Skip to content
This repository has been archived by the owner on Sep 23, 2020. It is now read-only.

Slightly altered the function: getError() and sizeToByte() #39

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

zhivulinal
Copy link

@zhivulinal zhivulinal commented Jun 23, 2016

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 appended.'
    },
    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: '

    ',
    loader: '
    ',
    message: '

    {{ default }}

    ',
    preview: '

    {{ replace }}

    ',
    filename: '

    ',
    clearButton: '{{ remove }}',
    errorLine: '

    {{ error }}

    ',
    errorsContainer: '
      '
      }
      };

      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 = $('').attr('src', src);

      if (this.settings.height) {
          imgTag.css("max-height", this.settings.height);
      }
      
      imgTag.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();
      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();

    value = 1024;

    switch(unit) {
    case 'T':
    value *= value;
    case 'G':
    value *= value;
    case 'M':
    value *= value;
    case 'K':
    value;
    }
    }

    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('
    • ' + this.getError(errorKey) + '
    • ');
      }
      };

    /**

    • Get error message
      *

    • @return {String} message
      */
      Dropify.prototype.getError = function(errorKey)
      {
      var error = this.settings.error[errorKey],
      value = '';

      switch (errorKey) {
      case 'fileSize':
      value = this.settings.maxFileSize;
      break;
      case 'minWidth':
      value = this.settings.minWidth;
      break;
      case 'maxWidth':
      value = this.settings.maxWidth;
      break;
      case 'minHeight':
      value = this.settings.minHeight;
      break;
      case 'maxHeight':
      value = this.settings.maxHeight;
      break;
      case 'imageFormat':
      value = this.settings.allowedFormats.join(', ');
      break;
      case 'fileExtension':
      value = this.settings.allowedFileExtensions.join(', ');
      break;
      }

      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;
    

    };

    It may be useful, it did validate the file format.
    Attr: data-allowed-files="pdf doc docs"
    error: {
        'fileFormat': 'The file format is not allowed ({{ value }} only).'
    }
    Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
    Labels
    None yet
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    1 participant