Files
edx-platform/lms/static/js/views/image_field.js
2015-08-08 09:43:20 -04:00

231 lines
8.7 KiB
JavaScript

;(function (define) {
'use strict';
define([
'gettext', 'jquery', 'underscore', 'backbone', 'js/views/fields',
'text!templates/fields/field_image.underscore',
'backbone-super', 'jquery.fileupload'
], function (gettext, $, _, Backbone, FieldViews, field_image_template) {
var ImageFieldView = FieldViews.FieldView.extend({
fieldType: 'image',
fieldTemplate: field_image_template,
uploadButtonSelector: '.upload-button-input',
titleAdd: gettext("Upload an image"),
titleEdit: gettext("Change image"),
titleRemove: gettext("Remove"),
titleUploading: gettext("Uploading"),
titleRemoving: gettext("Removing"),
titleImageAlt: '',
screenReaderTitle: gettext("Image"),
iconUpload: '<i class="icon fa fa-camera" aria-hidden="true"></i>',
iconRemove: '<i class="icon fa fa-remove" aria-hidden="true"></i>',
iconProgress: '<i class="icon fa fa-spinner fa-pulse fa-spin" aria-hidden="true"></i>',
errorMessage: gettext("An error has occurred. Refresh the page, and then try again."),
events: {
'click .u-field-upload-button': 'clickedUploadButton',
'click .u-field-remove-button': 'clickedRemoveButton',
'click .upload-submit': 'clickedUploadButton',
'focus .upload-button-input': 'showHoverState',
'blur .upload-button-input': 'hideHoverState'
},
initialize: function (options) {
this._super(options);
_.bindAll(this, 'render', 'imageChangeSucceeded', 'imageChangeFailed', 'fileSelected',
'watchForPageUnload', 'onBeforeUnload');
},
render: function () {
this.$el.html(this.template({
id: this.options.valueAttribute,
inputName: (this.options.inputName || 'file'),
imageUrl: _.result(this, 'imageUrl'),
imageAltText: _.result(this, 'imageAltText'),
uploadButtonIcon: _.result(this, 'iconUpload'),
uploadButtonTitle: _.result(this, 'uploadButtonTitle'),
removeButtonIcon: _.result(this, 'iconRemove'),
removeButtonTitle: _.result(this, 'removeButtonTitle'),
screenReaderTitle: _.result(this, 'screenReaderTitle')
}));
this.delegateEvents();
this.updateButtonsVisibility();
this.watchForPageUnload();
return this;
},
showHoverState: function () {
this.$('.u-field-upload-button').addClass('button-visible');
},
hideHoverState: function () {
this.$('.u-field-upload-button').removeClass('button-visible');
},
showErrorMessage: function (message) {
return message;
},
imageUrl: function () {
return '';
},
uploadButtonTitle: function () {
if (this.isShowingPlaceholder()) {
return _.result(this, 'titleAdd');
} else {
return _.result(this, 'titleEdit');
}
},
removeButtonTitle: function () {
return this.titleRemove;
},
isEditingAllowed: function () {
return true;
},
isShowingPlaceholder: function () {
return false;
},
setUploadButtonVisibility: function (state) {
this.$('.u-field-upload-button').css('display', state);
},
setRemoveButtonVisibility: function (state) {
this.$('.u-field-remove-button').css('display', state);
},
updateButtonsVisibility: function () {
if (!this.isEditingAllowed() || !this.options.editable) {
this.setUploadButtonVisibility('none');
}
if (this.isShowingPlaceholder() || !this.options.editable) {
this.setRemoveButtonVisibility('none');
}
},
clickedUploadButton: function () {
$(this.uploadButtonSelector).fileupload({
url: this.options.imageUploadUrl,
type: 'POST',
add: this.fileSelected,
done: this.imageChangeSucceeded,
fail: this.imageChangeFailed
});
},
clickedRemoveButton: function () {
var view = this;
this.setCurrentStatus('removing');
this.setUploadButtonVisibility('none');
this.showRemovalInProgressMessage();
$.ajax({
type: 'POST',
url: this.options.imageRemoveUrl
}).done(function () {
view.imageChangeSucceeded();
}).fail(function (jqXHR) {
view.showImageChangeFailedMessage(jqXHR.status, jqXHR.responseText);
});
},
imageChangeSucceeded: function () {
this.render();
},
imageChangeFailed: function (e, data) {
},
showImageChangeFailedMessage: function (status, responseText) {
},
fileSelected: function (e, data) {
if (_.isUndefined(data.files[0].size) || this.validateImageSize(data.files[0].size)) {
this.setCurrentStatus('uploading');
this.setRemoveButtonVisibility('none');
this.showUploadInProgressMessage();
data.submit();
}
},
validateImageSize: function (imageBytes) {
var humanReadableSize;
if (imageBytes < this.options.imageMinBytes) {
humanReadableSize = this.bytesToHumanReadable(this.options.imageMinBytes);
this.showErrorMessage(
interpolate_text(
gettext("The file must be at least {size} in size."), {size: humanReadableSize}
)
);
return false;
} else if (imageBytes > this.options.imageMaxBytes) {
humanReadableSize = this.bytesToHumanReadable(this.options.imageMaxBytes);
this.showErrorMessage(
interpolate_text(
gettext("The file must be smaller than {size} in size."), {size: humanReadableSize}
)
);
return false;
}
return true;
},
showUploadInProgressMessage: function () {
this.$('.u-field-upload-button').css('opacity', 1);
this.$('.upload-button-icon').html(this.iconProgress);
this.$('.upload-button-title').html(this.titleUploading);
},
showRemovalInProgressMessage: function () {
this.$('.u-field-remove-button').css('opacity', 1);
this.$('.remove-button-icon').html(this.iconProgress);
this.$('.remove-button-title').html(this.titleRemoving);
},
setCurrentStatus: function (status) {
this.$('.image-wrapper').attr('data-status', status);
},
getCurrentStatus: function () {
return this.$('.image-wrapper').attr('data-status');
},
watchForPageUnload: function () {
$(window).on('beforeunload', this.onBeforeUnload);
},
onBeforeUnload: function () {
var status = this.getCurrentStatus();
if (status === 'uploading') {
return gettext("Upload is in progress. To avoid errors, stay on this page until the process is complete.");
} else if (status === 'removing') {
return gettext("Removal is in progress. To avoid errors, stay on this page until the process is complete.");
}
},
bytesToHumanReadable: function (size) {
var units = [gettext('bytes'), gettext('KB'), gettext('MB')];
var i = 0;
while(size >= 1024) {
size /= 1024;
++i;
}
return size.toFixed(1)*1 + ' ' + units[i];
}
});
return ImageFieldView;
});
}).call(this, define || RequireJS.define);