110 lines
4.0 KiB
JavaScript
110 lines
4.0 KiB
JavaScript
define(["js/views/baseview", "underscore", "jquery", "jquery.form"],
|
|
function(BaseView, _, $) {
|
|
var UploadDialog = BaseView.extend({
|
|
options: {
|
|
shown: true,
|
|
successMessageTimeout: 2000 // 2 seconds
|
|
},
|
|
initialize: function() {
|
|
this.template = _.template($("#upload-dialog-tpl").text());
|
|
this.listenTo(this.model, "change", this.render);
|
|
},
|
|
render: function() {
|
|
var isValid = this.model.isValid();
|
|
var selectedFile = this.model.get('selectedFile');
|
|
var oldInput = this.$("input[type=file]").get(0);
|
|
this.$el.html(this.template({
|
|
shown: this.options.shown,
|
|
url: CMS.URL.UPLOAD_ASSET,
|
|
title: this.model.escape('title'),
|
|
message: this.model.escape('message'),
|
|
selectedFile: selectedFile,
|
|
uploading: this.model.get('uploading'),
|
|
uploadedBytes: this.model.get('uploadedBytes'),
|
|
totalBytes: this.model.get('totalBytes'),
|
|
finished: this.model.get('finished'),
|
|
error: this.model.validationError
|
|
}));
|
|
// Ideally, we'd like to tell the browser to pre-populate the
|
|
// <input type="file"> with the selectedFile if we have one -- but
|
|
// browser security prohibits that. So instead, we'll swap out the
|
|
// new input (that has no file selected) with the old input (that
|
|
// already has the selectedFile selected). However, we only want to do
|
|
// this if the selected file is valid: if it isn't, we want to render
|
|
// a blank input to prompt the user to upload a different (valid) file.
|
|
if (selectedFile && isValid) {
|
|
$(oldInput).removeClass("error");
|
|
this.$('input[type=file]').replaceWith(oldInput);
|
|
}
|
|
return this;
|
|
},
|
|
events: {
|
|
"change input[type=file]": "selectFile",
|
|
"click .action-cancel": "hideAndRemove",
|
|
"click .action-upload": "upload"
|
|
},
|
|
selectFile: function(e) {
|
|
this.model.set({
|
|
selectedFile: e.target.files[0] || null
|
|
});
|
|
},
|
|
show: function(e) {
|
|
if(e && e.preventDefault) { e.preventDefault(); }
|
|
this.options.shown = true;
|
|
$("body").addClass('dialog-is-shown');
|
|
return this.render();
|
|
},
|
|
hide: function(e) {
|
|
if(e && e.preventDefault) { e.preventDefault(); }
|
|
this.options.shown = false;
|
|
$("body").removeClass('dialog-is-shown');
|
|
return this.render();
|
|
},
|
|
hideAndRemove: function(e) {
|
|
if(e && e.preventDefault) { e.preventDefault(); }
|
|
return this.hide().remove();
|
|
},
|
|
upload: function(e) {
|
|
if(e && e.preventDefault) { e.preventDefault(); }
|
|
this.model.set('uploading', true);
|
|
this.$("form").ajaxSubmit({
|
|
success: _.bind(this.success, this),
|
|
error: _.bind(this.error, this),
|
|
uploadProgress: _.bind(this.progress, this),
|
|
data: {
|
|
// don't show the generic error notification; we're in a modal,
|
|
// and we're better off modifying it instead.
|
|
notifyOnError: false
|
|
}
|
|
});
|
|
},
|
|
progress: function(event, position, total, percentComplete) {
|
|
this.model.set({
|
|
"uploadedBytes": position,
|
|
"totalBytes": total
|
|
});
|
|
},
|
|
success: function(response, statusText, xhr, form) {
|
|
this.model.set({
|
|
uploading: false,
|
|
finished: true
|
|
});
|
|
if(this.options.onSuccess) {
|
|
this.options.onSuccess(response, statusText, xhr, form);
|
|
}
|
|
var that = this;
|
|
this.removalTimeout = setTimeout(function() {
|
|
that.hide().remove();
|
|
}, this.options.successMessageTimeout);
|
|
},
|
|
error: function() {
|
|
this.model.set({
|
|
"uploading": false,
|
|
"uploadedBytes": 0,
|
|
"title": gettext("We're sorry, there was an error")
|
|
});
|
|
}
|
|
});
|
|
return UploadDialog;
|
|
}); // end define()
|