The access settings modal should not have an editable title. Also, the title of the modal was not being interpolated correctly.
242 lines
9.8 KiB
JavaScript
242 lines
9.8 KiB
JavaScript
/**
|
|
* The EditXBlockModal is a Backbone view that shows an xblock editor in a modal window.
|
|
* It is invoked using the edit method which is passed an existing rendered xblock,
|
|
* and upon save an optional refresh function can be invoked to update the display.
|
|
*/
|
|
define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_modal',
|
|
'common/js/components/utils/view_utils', 'js/views/utils/xblock_utils', 'js/views/xblock_editor'],
|
|
function($, _, Backbone, gettext, BaseModal, ViewUtils, XBlockViewUtils, XBlockEditorView) {
|
|
'use strict';
|
|
|
|
var EditXBlockModal = BaseModal.extend({
|
|
events: _.extend({}, BaseModal.prototype.events, {
|
|
'click .action-save': 'save',
|
|
'click .action-modes a': 'changeMode',
|
|
'click .title-edit-button': 'clickTitleButton'
|
|
}),
|
|
|
|
options: $.extend({}, BaseModal.prototype.options, {
|
|
modalName: 'edit-xblock',
|
|
view: 'studio_view',
|
|
viewSpecificClasses: 'modal-editor confirm',
|
|
// Translators: "title" is the name of the current component being edited.
|
|
titleFormat: gettext('Editing: {title}'),
|
|
addPrimaryActionButton: true
|
|
}),
|
|
|
|
initialize: function() {
|
|
BaseModal.prototype.initialize.call(this);
|
|
this.template = this.loadTemplate('edit-xblock-modal');
|
|
this.editorModeButtonTemplate = this.loadTemplate('editor-mode-button');
|
|
},
|
|
|
|
/**
|
|
* Show an edit modal for the specified xblock
|
|
* @param xblockElement The element that contains the xblock to be edited.
|
|
* @param rootXBlockInfo An XBlockInfo model that describes the root xblock on the page.
|
|
* @param options A standard options object.
|
|
*/
|
|
edit: function(xblockElement, rootXBlockInfo, options) {
|
|
this.xblockElement = xblockElement;
|
|
this.xblockInfo = XBlockViewUtils.findXBlockInfo(xblockElement, rootXBlockInfo);
|
|
this.options.modalType = this.xblockInfo.get('category');
|
|
this.editOptions = options;
|
|
|
|
this.render();
|
|
this.show();
|
|
|
|
// Hide the action bar until we know which buttons we want
|
|
this.getActionBar().hide();
|
|
|
|
// Display the xblock after the modal is shown as there are some xblocks
|
|
// that depend upon being visible when they initialize, e.g. the problem xmodule.
|
|
this.displayXBlock();
|
|
},
|
|
|
|
getContentHtml: function() {
|
|
return this.template({
|
|
xblockInfo: this.xblockInfo
|
|
});
|
|
},
|
|
|
|
displayXBlock: function() {
|
|
this.editorView = new XBlockEditorView({
|
|
el: this.$('.xblock-editor'),
|
|
model: this.xblockInfo,
|
|
view: this.options.view
|
|
});
|
|
this.editorView.render({
|
|
success: _.bind(this.onDisplayXBlock, this)
|
|
});
|
|
},
|
|
|
|
createTitleEditor: function(title) {
|
|
// xss-lint: disable=javascript-jquery-html
|
|
this.$('.modal-window-title').html(this.loadTemplate('edit-title-button')({title: title}));
|
|
},
|
|
|
|
onDisplayXBlock: function() {
|
|
var editorView = this.editorView,
|
|
title = this.getTitle(),
|
|
readOnlyView = (this.editOptions && this.editOptions.readOnlyView) || !this.canSave();
|
|
|
|
// Notify the runtime that the modal has been shown
|
|
editorView.notifyRuntime('modal-shown', this);
|
|
|
|
// Update the modal's header
|
|
if (editorView.hasCustomTabs()) {
|
|
// Hide the modal's header as the custom editor provides its own
|
|
this.$('.modal-header').hide();
|
|
|
|
// Update the custom editor's title
|
|
editorView.$('.component-name').text(title);
|
|
} else if (editorView.getDataEditor() && editorView.getMetadataEditor()) {
|
|
this.createTitleEditor(title);
|
|
this.addDefaultModes();
|
|
// If the plugins content element exists, add a button to reveal it.
|
|
if (this.$('.wrapper-comp-plugins').length > 0) {
|
|
this.addModeButton('plugins', gettext('Plugins'));
|
|
}
|
|
this.selectMode(editorView.mode);
|
|
} else {
|
|
this.$('.modal-window-title').text(title);
|
|
}
|
|
|
|
// If the xblock is not using custom buttons then choose which buttons to show
|
|
if (!editorView.hasCustomButtons()) {
|
|
// If the xblock does not support save then disable the save button
|
|
if (readOnlyView) {
|
|
this.disableSave();
|
|
}
|
|
this.getActionBar().show();
|
|
}
|
|
this.resize();
|
|
},
|
|
|
|
canSave: function() {
|
|
return this.editorView.xblock.save || this.editorView.xblock.collectFieldData;
|
|
},
|
|
|
|
disableSave: function() {
|
|
var saveButton = this.getActionButton('save'),
|
|
cancelButton = this.getActionButton('cancel');
|
|
saveButton.parent().hide();
|
|
cancelButton.text(gettext('Close'));
|
|
cancelButton.addClass('action-primary');
|
|
},
|
|
|
|
getTitle: function() {
|
|
var displayName = this.xblockInfo.get('display_name');
|
|
if (!displayName) {
|
|
if (this.xblockInfo.isVertical()) {
|
|
displayName = gettext('Unit');
|
|
} else {
|
|
displayName = gettext('Component');
|
|
}
|
|
}
|
|
return edx.StringUtils.interpolate(
|
|
this.options.titleFormat, {
|
|
title: displayName
|
|
}
|
|
);
|
|
},
|
|
|
|
addDefaultModes: function() {
|
|
var defaultModes, i, mode;
|
|
defaultModes = this.editorView.getDefaultModes();
|
|
for (i = 0; i < defaultModes.length; i++) {
|
|
mode = defaultModes[i];
|
|
this.addModeButton(mode.id, mode.name);
|
|
}
|
|
},
|
|
|
|
changeMode: function(event) {
|
|
var $parent = $(event.target.parentElement),
|
|
mode = $parent.data('mode');
|
|
event.preventDefault();
|
|
this.selectMode(mode);
|
|
},
|
|
|
|
selectMode: function(mode) {
|
|
var editorView = this.editorView,
|
|
buttonSelector;
|
|
editorView.selectMode(mode);
|
|
this.$('.editor-modes a').removeClass('is-set');
|
|
if (mode) {
|
|
buttonSelector = '.' + mode + '-button';
|
|
this.$(buttonSelector).addClass('is-set');
|
|
}
|
|
},
|
|
|
|
save: function(event) {
|
|
var self = this,
|
|
editorView = this.editorView,
|
|
xblockInfo = this.xblockInfo,
|
|
data = editorView.getXBlockFieldData();
|
|
event.preventDefault();
|
|
if (data) {
|
|
ViewUtils.runOperationShowingMessage(gettext('Saving'),
|
|
function() {
|
|
return xblockInfo.save(data);
|
|
}).done(function() {
|
|
self.onSave();
|
|
});
|
|
}
|
|
},
|
|
|
|
onSave: function() {
|
|
var refresh = this.editOptions.refresh;
|
|
this.hide();
|
|
if (refresh) {
|
|
refresh(this.xblockInfo);
|
|
}
|
|
},
|
|
|
|
hide: function() {
|
|
// Notify child views to stop listening events
|
|
Backbone.trigger('xblock:editorModalHidden');
|
|
|
|
BaseModal.prototype.hide.call(this);
|
|
|
|
// Notify the runtime that the modal has been hidden
|
|
this.editorView.notifyRuntime('modal-hidden');
|
|
},
|
|
|
|
addModeButton: function(mode, displayName) {
|
|
var buttonPanel = this.$('.editor-modes');
|
|
// xss-lint: disable=javascript-jquery-append
|
|
buttonPanel.append(this.editorModeButtonTemplate({
|
|
mode: mode,
|
|
displayName: displayName
|
|
}));
|
|
},
|
|
|
|
clickTitleButton: function(event) {
|
|
var self = this,
|
|
oldTitle = this.xblockInfo.get('display_name'),
|
|
titleElt = this.$('.modal-window-title'),
|
|
$input = $('<input type="text" size="40" />'),
|
|
changeFunc = function(evt) {
|
|
var newTitle = $(evt.target).val();
|
|
if (oldTitle !== newTitle) {
|
|
self.xblockInfo.set('display_name', newTitle);
|
|
self.xblockInfo.save({metadata: {display_name: newTitle}});
|
|
}
|
|
self.createTitleEditor(self.getTitle());
|
|
return true;
|
|
};
|
|
event.preventDefault();
|
|
|
|
$input.val(oldTitle);
|
|
$input.change(changeFunc).blur(changeFunc);
|
|
titleElt.html($input); // xss-lint: disable=javascript-jquery-html
|
|
$input.focus().select();
|
|
$(event.target).remove();
|
|
return true;
|
|
}
|
|
|
|
});
|
|
|
|
return EditXBlockModal;
|
|
});
|