// this version uses the filepicker.io service
editors.FilepickerIO = editors.Text.extend({
tagName: 'div',
events: {
'change input[type=file]': 'uploadFile',
'click .remove': 'removeFile'
},
initialize: function(options) {
_.bindAll(this, 'filepickerSuccess', 'filepickerError', 'filepickerProgress');
editors.Text.prototype.initialize.call(this, options);
this.$input = $('');
this.$uploadInput = $('');
this.$loader = $('
Uploading…
');
this.$error = $('Error
');
this.$list = $('');
},
// return an array of file dicts
getValue: function() {
var val = this.$input.val();
return val ? JSON.parse(val) : [];
},
setValue: function(value) {
var str, files = value;
if (_(value).isObject()) {
str = JSON.stringify(value);
} else {
files = value ? JSON.parse(value) : [];
}
this.$input.val(str);
this.updateList(files);
},
render: function(options) {
editors.Text.prototype.render.apply(this, arguments);
this.$el.append(this.$input);
this.$el.append(this.$uploadInput);
this.$el.append(this.$loader.hide());
this.$el.append(this.$error.hide());
this.$el.append(this.$list);
return this;
},
uploadFile: function() {
filepicker = require('filepicker-io');
// https://developers.filepicker.io/docs/web/#local-upload
filepicker.uploadFile(this.$uploadInput.get(0), this.filepickerSuccess, this.filepickerError, this.filepickerProgress);
},
filepickerSuccess: function(files) {
console.log('Filepicker (raw)', files);
this.$loader.hide();
this.$error.hide();
this.$uploadInput.val('');
// when uploading one file, it returns just an object
if (!_(files).isArray()) { files = [files]; }
// turn response array into a flatter array of objects
var newFiles = _(files).map(function(one) {
return {
url: one.url,
filename: one.data.filename,
s3_key: one.data.key,
size: one.data.size,
content_type: one.data.type
};
});
console.log('Filepicker (processed)', newFiles);
this.setValue(this.getValue().concat(newFiles));
},
filepickerError: function(msg) {
console.debug('Filepicker error', msg);
this.$loader.hide();
this.$error.show();
},
filepickerProgress: function(percent) {
this.$loader.show();
this.$error.hide();
},
updateList: function(files) {
// this code is currently duplicated as a handlebar helper (I wanted to let this
// backbone-forms field stand on its own)
var displayFilesize = function(bytes) {
// TODO improve this function
return Math.floor(bytes / 1024) + 'K';
};
this.$list.empty();
_(files).each(function(file) {
var a = $('', {
target: '_blank',
href: file.url,
text: file.filename + ' (' + file.content_type + ') ' + displayFilesize(file.size)
});
var li = $('- ').append(a);
li.append(a, ' ', $('').data('s3_key', file.s3_key));
this.$list.append(li);
}, this);
this.$list[files.length ? 'show' : 'hide']();
},
removeFile: function(ev) {
if (ev) ev.preventDefault();
var s3_key = $(ev.currentTarget).data('s3_key');
var files = this.getValue();
this.setValue(_(files).reject(function(one) {
return one.s3_key === s3_key;
}));
}
});