Files
edx-platform/lms/static/js/views/file_uploader.js
2020-07-22 02:40:19 +05:00

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);