126 lines
5.6 KiB
JavaScript
126 lines
5.6 KiB
JavaScript
/**
|
|
* A view for uploading a file.
|
|
*
|
|
* Currently only single-file upload is supported (to support multiple-file uploads, the HTML
|
|
* input must be changed to specify "multiple" and the notification messaging needs to be changed
|
|
* to support the display of multiple status messages).
|
|
*
|
|
* There is no associated model, but the view supports the following options:
|
|
*
|
|
* @param title, the title to display.
|
|
* @param inputLabel, a label that will be added for the file input field. Note that this label is only shown to
|
|
* screen readers.
|
|
* @param inputTip, a tooltip linked to the file input field. Can be used to state what sort of file can be uploaded.
|
|
* @param extensions, the allowed file extensions of the uploaded file, as a comma-separated string (ex, ".csv,.txt").
|
|
* Some browsers will enforce that only files with these extensions can be uploaded, but others
|
|
* (for instance, Firefox), will not. By default, no extensions are specified and any file can be uploaded.
|
|
* @param submitButtonText, text to display on the submit button to upload the file. The default value for this is
|
|
* "Upload File".
|
|
* @param url, the url for posting the uploaded file.
|
|
* @param successNotification, optional callback that can return a success NotificationModel for display
|
|
* after a file was successfully uploaded. This method will be passed the uploaded file, event, and data.
|
|
* @param errorNotification, optional callback that can return a success NotificationModel for display
|
|
* after a file failed to upload. This method will be passed the attempted file, event, and data.
|
|
*/
|
|
(function(Backbone, $, _, gettext, interpolate_text, NotificationModel, NotificationView) {
|
|
// Requires JQuery-File-Upload.
|
|
var FileUploaderView = Backbone.View.extend({
|
|
|
|
initialize: function(options) {
|
|
this.template = _.template($('#file-upload-tpl').text());
|
|
this.options = options;
|
|
},
|
|
|
|
render: function() {
|
|
var options = this.options,
|
|
get_option_with_default = function(option, default_value) {
|
|
var optionVal = options[option];
|
|
return optionVal || default_value;
|
|
},
|
|
submitButton, resultNotification;
|
|
// xss-lint: disable=javascript-jquery-html
|
|
this.$el.html(this.template({
|
|
title: get_option_with_default('title', ''),
|
|
inputLabel: get_option_with_default('inputLabel', ''),
|
|
inputTip: get_option_with_default('inputTip', ''),
|
|
extensions: get_option_with_default('extensions', ''),
|
|
submitButtonText: get_option_with_default('submitButtonText', gettext('Upload File')),
|
|
url: get_option_with_default('url', '')
|
|
}));
|
|
|
|
submitButton = this.$el.find('.submit-file-button');
|
|
resultNotification = this.$el.find('.result'),
|
|
|
|
this.$el.find('#file-upload-form').fileupload({
|
|
dataType: 'json',
|
|
type: 'POST',
|
|
done: this.successHandler.bind(this),
|
|
fail: this.errorHandler.bind(this),
|
|
autoUpload: false,
|
|
replaceFileInput: false,
|
|
add: function(e, data) {
|
|
var file = data.files[0];
|
|
submitButton.removeClass('is-disabled').attr('aria-disabled', false);
|
|
submitButton.unbind('click');
|
|
submitButton.click(function(event) {
|
|
event.preventDefault();
|
|
data.submit();
|
|
});
|
|
resultNotification.html('');
|
|
}
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
successHandler: function(event, data) {
|
|
var file = data.files[0].name;
|
|
var notificationModel;
|
|
if (this.options.successNotification) {
|
|
notificationModel = this.options.successNotification(file, event, data);
|
|
} else {
|
|
notificationModel = new NotificationModel({
|
|
type: 'confirmation',
|
|
title: interpolate_text(gettext("Your upload of '{file}' succeeded."), {file: file})
|
|
});
|
|
}
|
|
var notification = new NotificationView({
|
|
el: this.$('.result'),
|
|
model: notificationModel
|
|
});
|
|
notification.render();
|
|
},
|
|
|
|
errorHandler: function(event, data) {
|
|
var file = data.files[0].name,
|
|
message = null,
|
|
jqXHR = data.response().jqXHR;
|
|
var notificationModel;
|
|
if (this.options.errorNotification) {
|
|
notificationModel = this.options.errorNotification(file, event, data);
|
|
} else {
|
|
if (jqXHR.responseText) {
|
|
try {
|
|
message = JSON.parse(jqXHR.responseText).error;
|
|
} catch (err) {
|
|
}
|
|
}
|
|
if (!message) {
|
|
message = interpolate_text(gettext("Your upload of '{file}' failed."), {file: file});
|
|
}
|
|
notificationModel = new NotificationModel({
|
|
type: 'error',
|
|
title: message
|
|
});
|
|
}
|
|
var notification = new NotificationView({
|
|
el: this.$('.result'),
|
|
model: notificationModel
|
|
});
|
|
notification.render();
|
|
}
|
|
});
|
|
|
|
this.FileUploaderView = FileUploaderView;
|
|
}).call(this, Backbone, $, _, gettext, interpolate_text, NotificationModel, NotificationView);
|