/*!
* 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 {
var item = that.content.find('li');
console.log(item.length);
if (!item.length) {
item = $('', { html: link + remove, 'class': 'attachy__node' }).appendTo(that.content);
}
item.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);