/*! * Attachy - Attachments handler for Rails via Cloudinary * * The MIT License * * @author : Washington Botelho * @doc : http://wbotelhos.com/attachy * @version : 0.2.0 * */ ; (function($) { 'use strict'; $.attachy = { crop: undefined, disableWith: ' %', dropZone: undefined, fieldName: 'avatar', height: undefined, progress: true, secure: true, sequential: true, sign_url: true, url: '/attachy/url', width: undefined, link: { crop: undefined, height: undefined, width: undefined } } $.fn.attachy = function(options) { var settings = $.extend({}, $.attachy, options); return this.each(function() { return (new $.attachy.Attachy(this, settings)).create(); }); } $.attachy.Attachy = (function() { var Attachy = function(field, options) { this.field = $(field); this.options = options; } Attachy.prototype = { add: function(file) { if (this.multiple) { this.files.push(file); } else { this.files = [file]; } this.draw(file); }, backupStatus: function() { this.submit.data('label', this.submit.text()); this.button.data('label', this.button.text()); }, binds: function() { this.field.on('fileuploadsend', this.onUploading.bind(this)); this.field.on('fileuploaddone', this.onDone.bind(this)); this.field.on('fileuploadprogressall', this.onProgress.bind(this)); this.field.on('fileuploadalways', this.onAlways.bind(this)); this.content.on('click', '.attachy__remove', this.onRemove.bind(this)); }, configure: function() { var json = JSON.parse(this.hidden.val()); if (!$.isArray(json)) { json = [json]; } this.files = json; this.multiple = this.content.data('multiple'); }, create: function() { this.scan(); this.configure(); this.init(); this.backupStatus(); this.binds(); return this; }, changeStatus: function(progress) { var label = progress + this.options.disableWith; this.submit.text(label); this.button.text(label); }, draw: function(file) { var that = this; this.render(file, function(json) { var image = that.image(file, json), link = that.link(file, image, json), remove = that.removeButton(); that.hideEmpty(); if (that.multiple) { var node = $('
', { html: link, 'class': 'attachy__node' }).append(remove); that.content.append(node); } else { that.content.find('li').empty().append(link, remove); } }); }, hideEmpty: function() { this.empty.hide(); }, image: function(file, json) { var config = this.imageConfig(file), attributes = { alt: config.alt, height: config.height, width: config.width }; $.extend({}, attributes, config); if (this.options.sign_url) { attributes.src = json.image; } else { attributes.src = $.cloudinary.url(file.public_id, config); } return $('', attributes); }, imageConfig: function(file) { return { crop: this.content.data('crop') || this.options.crop, format: file.format, height: this.content.data('height') || this.options.height, publicId: file.public_id, version: file.version, width: this.content.data('width') || this.options.width }; }, init: function() { this.field.fileupload({ dataType: 'json', dropZone: this.options.dropZone, headers: { 'X-Requested-With': 'XMLHttpRequest' }, sequentialUploads: this.options.sequential }); this.field.cloudinary_fileupload(); }, link: function(file, image, json) { var attributes = { html: image, 'class': 'attachy__link' }; if (this.options.sign_url) { attributes.href = json.link; } else { attributes.href = $.cloudinary.url(file.public_id, this.linkConfig(file)); } return $('', attributes); }, linkConfig: function(file) { return { crop: this.content.data('link-crop') || this.options.link.crop, format: file.format, height: this.content.data('link-height') || this.options.link.height, version: file.version, width: this.content.data('link-width') || this.options.link.width } }, onAlways: function() { this.wrapper.removeClass('attachy__uploading'); this.restoreStatus(); }, onDone: function(_evt, data) { var file = data.result; this.add(file); this.updateHidden(); }, onProgress: function(_evt, data) { var progress = parseInt(data.loaded / data.total * 100, 10); if (this.options.progress && this.options.disableWith) { this.changeStatus(progress); } }, onRemove: function(e) { var file, files = [], node = $(e.currentTarget).closest('.attachy__node'), image = node.find('img'); for (var i = 0; i < this.files.length; i++) { file = this.files[i]; if (file.public_id !== image.data('publicId')) { files.push(file); } } node.remove(); this.files = files; this.updateHidden(); if (!this.files.length) { this.showEmpty(); } }, onUploading: function() { this.wrapper.addClass('attachy__uploading'); }, removeButton: function() { return $('', { html: '×', 'class': 'attachy__remove' }); }, render: function(file, callback) { if (this.options.sign_url) { var linkConfig = this.linkConfig(file), options = $.extend({}, { format: file.format, public_id: file.public_id, secure: this.options.secure, sign_url: this.options.sign_url }, this.imageConfig(file)); for (var key in linkConfig) { if (linkConfig.hasOwnProperty(key)) { options['link_' + key] = linkConfig[key]; } } var ajax = $.ajax({ data: options, url: this.options.url }); ajax.done(callback); ajax.fail(function(response) { alert(response.responseText); }); } else { callback(); } }, restoreStatus: function() { this.submit.text(this.submit.data('label')); this.button.text(this.button.data('label')); }, scan: function() { this.wrapper = this.field.closest('.attachy'); this.button = this.wrapper.find('.attachy__button span'); this.content = this.wrapper.find('.attachy__content'); this.empty = this.wrapper.find('.attachy__empty'); this.hidden = this.wrapper.find('input[type="hidden"]'); this.remove = this.wrapper.find('.attachy__remove'); this.submit = this.wrapper.closest('form').find(':submit'); }, showEmpty: function() { this.empty.show(); }, updateHidden: function() { this.hidden.val(JSON.stringify(this.files)); } }; return Attachy; })(); })(jQuery);