Merge pull request #24246 from edx/private_to_public_edd9b02
Mergeback PR from private to public.
This commit is contained in:
@@ -8,10 +8,11 @@ define([
|
||||
'js/views/list_item_editor',
|
||||
'js/certificates/models/signatory',
|
||||
'js/certificates/views/signatory_editor',
|
||||
'text!templates/certificate-editor.underscore'
|
||||
'text!templates/certificate-editor.underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function($, _, Backbone, gettext,
|
||||
ListItemEditorView, SignatoryModel, SignatoryEditorView, certificateEditorTemplate) {
|
||||
ListItemEditorView, SignatoryModel, SignatoryEditorView, certificateEditorTemplate, HtmlUtils) {
|
||||
'use strict';
|
||||
|
||||
// If signatories limit is required to specific value then we can change it.
|
||||
@@ -75,7 +76,7 @@ function($, _, Backbone, gettext,
|
||||
isEditingAllCollections: true,
|
||||
eventAgg: self.eventAgg
|
||||
});
|
||||
self.$('div.signatory-edit-list').append($(signatory_view.render()));
|
||||
self.$('div.signatory-edit-list').append(HtmlUtils.HTML((signatory_view.render())).toString());
|
||||
});
|
||||
this.disableAddSignatoryButton();
|
||||
return this;
|
||||
|
||||
@@ -8,9 +8,10 @@ define([
|
||||
'js/views/baseview',
|
||||
'common/js/components/utils/view_utils',
|
||||
'common/js/components/views/feedback_notification',
|
||||
'text!templates/certificate-web-preview.underscore'
|
||||
'text!templates/certificate-web-preview.underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPreviewTemplate) {
|
||||
function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPreviewTemplate, HtmlUtils) {
|
||||
'use strict';
|
||||
var CertificateWebPreview = BaseView.extend({
|
||||
el: $('.preview-certificate'),
|
||||
@@ -27,7 +28,7 @@ function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPrevie
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(_.template(certificateWebPreviewTemplate)({
|
||||
HtmlUtils.setHtml(this.$el, HtmlUtils.template(certificateWebPreviewTemplate)({
|
||||
course_modes: this.course_modes,
|
||||
certificate_web_view_url: this.certificate_web_view_url,
|
||||
is_active: this.is_active
|
||||
@@ -36,13 +37,8 @@ function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPrevie
|
||||
},
|
||||
|
||||
toggleCertificateActivation: function() {
|
||||
var msg = 'Activating';
|
||||
if (this.is_active) {
|
||||
msg = 'Deactivating';
|
||||
}
|
||||
|
||||
var notification = new NotificationView.Mini({
|
||||
title: gettext(msg)
|
||||
title: gettext(this.is_active ? 'Deactivating' : 'Activating')
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
|
||||
@@ -11,10 +11,11 @@ define([
|
||||
'js/views/baseview',
|
||||
'js/certificates/views/signatory_editor',
|
||||
'text!templates/signatory-details.underscore',
|
||||
'text!templates/signatory-actions.underscore'
|
||||
'text!templates/signatory-actions.underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, SignatoryEditorView,
|
||||
signatoryDetailsTemplate, signatoryActionsTemplate) {
|
||||
signatoryDetailsTemplate, signatoryActionsTemplate, HtmlUtils) {
|
||||
'use strict';
|
||||
var SignatoryDetailsView = BaseView.extend({
|
||||
tagName: 'div',
|
||||
@@ -52,20 +53,20 @@ function($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Signa
|
||||
editSignatory: function(event) {
|
||||
// Retrieve the edit view for this model
|
||||
if (event && event.preventDefault) { event.preventDefault(); }
|
||||
this.$el.html(this.edit_view.render());
|
||||
$(_.template(signatoryActionsTemplate)()).appendTo(this.el);
|
||||
this.$el.html(HtmlUtils.HTML(this.edit_view.render()).toString());
|
||||
this.$el.append(HtmlUtils.template(signatoryActionsTemplate)().toString());
|
||||
this.edit_view.delegateEvents();
|
||||
this.delegateEvents();
|
||||
},
|
||||
|
||||
saveSignatoryData: function(event) {
|
||||
// Persist the data for this model
|
||||
if (event && event.preventDefault) { event.preventDefault(); }
|
||||
var certificate = this.model.get('certificate');
|
||||
var self = this;
|
||||
if (event && event.preventDefault) { event.preventDefault(); }
|
||||
if (!certificate.isValid()) {
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
ViewUtils.runOperationShowingMessage(
|
||||
gettext('Saving'),
|
||||
function() {
|
||||
@@ -94,7 +95,7 @@ function($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Signa
|
||||
var attributes = $.extend({}, this.model.attributes, {
|
||||
signatory_number: this.model.collection.indexOf(this.model) + 1
|
||||
});
|
||||
return $(this.el).html(_.template(signatoryDetailsTemplate)(attributes));
|
||||
return HtmlUtils.setHtml(this.$el, HtmlUtils.template(signatoryDetailsTemplate)(attributes));
|
||||
}
|
||||
});
|
||||
return SignatoryDetailsView;
|
||||
|
||||
@@ -11,11 +11,12 @@ define([
|
||||
'common/js/components/views/feedback_notification',
|
||||
'js/models/uploads',
|
||||
'js/views/uploads',
|
||||
'text!templates/signatory-editor.underscore'
|
||||
'text!templates/signatory-editor.underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function($, _, Backbone, gettext,
|
||||
TemplateUtils, ViewUtils, PromptView, NotificationView, FileUploadModel, FileUploadDialog,
|
||||
signatoryEditorTemplate) {
|
||||
signatoryEditorTemplate, HtmlUtils) {
|
||||
'use strict';
|
||||
var SignatoryEditorView = Backbone.View.extend({
|
||||
tagName: 'div',
|
||||
@@ -78,7 +79,7 @@ function($, _, Backbone, gettext,
|
||||
is_editing_all_collections: this.isEditingAllCollections,
|
||||
total_saved_signatories: this.getTotalSignatoriesOnServer()
|
||||
});
|
||||
return $(this.el).html(_.template(signatoryEditorTemplate)(attributes));
|
||||
return HtmlUtils.setHtml(this.$el, HtmlUtils.template(signatoryEditorTemplate)(attributes));
|
||||
},
|
||||
|
||||
setSignatoryName: function(event) {
|
||||
@@ -127,10 +128,9 @@ function($, _, Backbone, gettext,
|
||||
|
||||
deleteItem: function(event) {
|
||||
// Remove the specified model from the collection
|
||||
if (event && event.preventDefault) { event.preventDefault(); }
|
||||
var model = this.model;
|
||||
var self = this;
|
||||
var titleTextTemplate = _.template(gettext('Delete "<%= signatoryName %>" from the list of signatories?'));
|
||||
var titleTextTemplate = _.template(gettext('Delete "<%- signatoryName %>" from the list of signatories?'));
|
||||
var confirm = new PromptView.Warning({
|
||||
title: titleTextTemplate({signatoryName: model.get('name')}),
|
||||
message: gettext('This action cannot be undone.'),
|
||||
@@ -148,9 +148,9 @@ function($, _, Backbone, gettext,
|
||||
deleting.show();
|
||||
model.destroy({
|
||||
wait: true,
|
||||
success: function(model) {
|
||||
success: function(model2) {
|
||||
deleting.hide();
|
||||
self.eventAgg.trigger('onSignatoryRemoved', model);
|
||||
self.eventAgg.trigger('onSignatoryRemoved', model2);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -165,18 +165,20 @@ function($, _, Backbone, gettext,
|
||||
}
|
||||
}
|
||||
});
|
||||
if (event && event.preventDefault) { event.preventDefault(); }
|
||||
confirm.show();
|
||||
},
|
||||
|
||||
uploadSignatureImage: function(event) {
|
||||
var upload, self, modal;
|
||||
event.preventDefault();
|
||||
var upload = new FileUploadModel({
|
||||
upload = new FileUploadModel({
|
||||
title: gettext('Upload signature image.'),
|
||||
message: gettext('Image must be in PNG format.'),
|
||||
mimeTypes: ['image/png']
|
||||
});
|
||||
var self = this;
|
||||
var modal = new FileUploadDialog({
|
||||
self = this;
|
||||
modal = new FileUploadDialog({
|
||||
model: upload,
|
||||
onSuccess: function(response) {
|
||||
self.model.set('signature_image_path', response.asset.url);
|
||||
@@ -192,12 +194,13 @@ function($, _, Backbone, gettext,
|
||||
*/
|
||||
toggleValidationErrorMessage: function(modelAttribute) {
|
||||
var selector = 'div.add-signatory-' + modelAttribute;
|
||||
var errorMessage;
|
||||
if (!this.model.isValid() && _.has(this.model.validationError, modelAttribute)) {
|
||||
// Show the error message if it is not exist before.
|
||||
if (!$(selector).hasClass('error')) {
|
||||
var errorMessage = this.model.validationError[modelAttribute];
|
||||
errorMessage = this.model.validationError[modelAttribute];
|
||||
$(selector).addClass('error');
|
||||
$(selector).append("<span class='message-error'>" + errorMessage + '</span>');
|
||||
$(selector).append(HtmlUtils.joinHtml(HtmlUtils.HTML("<span class='message-error'>"), errorMessage, HtmlUtils.HTML('</span>')).toString()); // eslint-disable-line max-len
|
||||
}
|
||||
} else {
|
||||
// Remove the error message.
|
||||
|
||||
@@ -22,7 +22,11 @@ function($, _, gettext, ViewUtils, StringUtils, HtmlUtils) {
|
||||
showError = function(containerElSelector, error) {
|
||||
var errorWrapperElSelector, errorHtml;
|
||||
errorWrapperElSelector = containerElSelector + ' .wrapper-error';
|
||||
errorHtml = '<div class="error" aria-live="polite" id="course-id-error">' + error + '</div>';
|
||||
errorHtml = HtmlUtils.joinHtml(
|
||||
HtmlUtils.HTML('<div class="error" aria-live="polite" id="course-id-error">'),
|
||||
error,
|
||||
HtmlUtils.HTML('</div>')
|
||||
);
|
||||
HtmlUtils.setHtml($(errorWrapperElSelector), HtmlUtils.HTML(errorHtml));
|
||||
$(errorWrapperElSelector).css('display', 'inline-block');
|
||||
$(errorWrapperElSelector).fadeOut(5000);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js/utils/date_utils'],
|
||||
function(Backbone, _, gettext, ValidationHelpers, DateUtils) {
|
||||
define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js/utils/date_utils',
|
||||
'edx-ui-toolkit/js/utils/string-utils'
|
||||
],
|
||||
function(Backbone, _, gettext, ValidationHelpers, DateUtils, StringUtils) {
|
||||
'use strict';
|
||||
var CourseDetails = Backbone.Model.extend({
|
||||
defaults: {
|
||||
org: '',
|
||||
@@ -51,11 +54,17 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js
|
||||
if (newattrs.start_date && newattrs.end_date && newattrs.start_date >= newattrs.end_date) {
|
||||
errors.end_date = gettext('The course end date must be later than the course start date.');
|
||||
}
|
||||
if (newattrs.start_date && newattrs.enrollment_start && newattrs.start_date < newattrs.enrollment_start) {
|
||||
errors.enrollment_start = gettext('The course start date must be later than the enrollment start date.');
|
||||
if (newattrs.start_date && newattrs.enrollment_start &&
|
||||
newattrs.start_date < newattrs.enrollment_start) {
|
||||
errors.enrollment_start = gettext(
|
||||
'The course start date must be later than the enrollment start date.'
|
||||
);
|
||||
}
|
||||
if (newattrs.enrollment_start && newattrs.enrollment_end && newattrs.enrollment_start >= newattrs.enrollment_end) {
|
||||
errors.enrollment_end = gettext('The enrollment start date cannot be after the enrollment end date.');
|
||||
if (newattrs.enrollment_start && newattrs.enrollment_end &&
|
||||
newattrs.enrollment_start >= newattrs.enrollment_end) {
|
||||
errors.enrollment_end = gettext(
|
||||
'The enrollment start date cannot be after the enrollment end date.'
|
||||
);
|
||||
}
|
||||
if (newattrs.end_date && newattrs.enrollment_end && newattrs.end_date < newattrs.enrollment_end) {
|
||||
errors.enrollment_end = gettext('The enrollment end date cannot be after the course end date.');
|
||||
@@ -78,7 +87,9 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js
|
||||
max: 100
|
||||
};
|
||||
if (!ValidationHelpers.validateIntegerRange(newattrs.entrance_exam_minimum_score_pct, range)) {
|
||||
errors.entrance_exam_minimum_score_pct = interpolate(gettext('Please enter an integer between %(min)s and %(max)s.'), range, true);
|
||||
errors.entrance_exam_minimum_score_pct = StringUtils.interpolate(gettext(
|
||||
'Please enter an integer between %(min)s and %(max)s.'
|
||||
), range, true);
|
||||
}
|
||||
}
|
||||
if (!_.isEmpty(errors)) return errors;
|
||||
@@ -90,7 +101,8 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js
|
||||
set_videosource: function(newsource) {
|
||||
// newsource either is <video youtube="speed:key, *"/> or just the "speed:key, *" string
|
||||
// returns the videosource for the preview which iss the key whose speed is closest to 1
|
||||
if (_.isEmpty(newsource) && !_.isEmpty(this.get('intro_video'))) this.set({intro_video: null}, {validate: true});
|
||||
if (_.isEmpty(newsource) &&
|
||||
!_.isEmpty(this.get('intro_video'))) this.set({intro_video: null}, {validate: true});
|
||||
// TODO remove all whitespace w/in string
|
||||
else {
|
||||
if (this.get('intro_video') !== newsource) this.set('intro_video', newsource, {validate: true});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* globals _ */
|
||||
define(['backbone', 'js/models/location', 'js/collections/course_grader'],
|
||||
function(Backbone, Location, CourseGraderCollection) {
|
||||
define(['backbone', 'js/models/location', 'js/collections/course_grader', 'edx-ui-toolkit/js/utils/string-utils'],
|
||||
function(Backbone, Location, CourseGraderCollection, StringUtils) {
|
||||
'use strict';
|
||||
var CourseGradingPolicy = Backbone.Model.extend({
|
||||
defaults: {
|
||||
graders: null, // CourseGraderCollection
|
||||
@@ -37,9 +38,15 @@ define(['backbone', 'js/models/location', 'js/collections/course_grader'],
|
||||
},
|
||||
gracePeriodToDate: function() {
|
||||
var newDate = new Date();
|
||||
if (this.has('grace_period') && this.get('grace_period').hours) { newDate.setHours(this.get('grace_period').hours); } else newDate.setHours(0);
|
||||
if (this.has('grace_period') && this.get('grace_period').minutes) { newDate.setMinutes(this.get('grace_period').minutes); } else newDate.setMinutes(0);
|
||||
if (this.has('grace_period') && this.get('grace_period').seconds) { newDate.setSeconds(this.get('grace_period').seconds); } else newDate.setSeconds(0);
|
||||
if (this.has('grace_period') && this.get('grace_period').hours) {
|
||||
newDate.setHours(this.get('grace_period').hours);
|
||||
} else newDate.setHours(0);
|
||||
if (this.has('grace_period') && this.get('grace_period').minutes) {
|
||||
newDate.setMinutes(this.get('grace_period').minutes);
|
||||
} else newDate.setMinutes(0);
|
||||
if (this.has('grace_period') && this.get('grace_period').seconds) {
|
||||
newDate.setSeconds(this.get('grace_period').seconds);
|
||||
} else newDate.setSeconds(0);
|
||||
|
||||
return newDate;
|
||||
},
|
||||
@@ -62,6 +69,7 @@ define(['backbone', 'js/models/location', 'js/collections/course_grader'],
|
||||
return parseInt(minimum_grade_credit);
|
||||
},
|
||||
validate: function(attrs) {
|
||||
var minimumGradeCutoff;
|
||||
if (_.has(attrs, 'grace_period')) {
|
||||
if (attrs.grace_period === null) {
|
||||
return {
|
||||
@@ -71,12 +79,13 @@ define(['backbone', 'js/models/location', 'js/collections/course_grader'],
|
||||
}
|
||||
if (this.get('is_credit_course') && _.has(attrs, 'minimum_grade_credit')) {
|
||||
// Getting minimum grade cutoff value
|
||||
var minimum_grade_cutoff = _.min(_.values(attrs.grade_cutoffs));
|
||||
if (isNaN(attrs.minimum_grade_credit) || attrs.minimum_grade_credit === null || attrs.minimum_grade_credit < minimum_grade_cutoff) {
|
||||
minimumGradeCutoff = _.min(_.values(attrs.grade_cutoffs));
|
||||
if (isNaN(attrs.minimum_grade_credit) || attrs.minimum_grade_credit === null ||
|
||||
attrs.minimum_grade_credit < minimumGradeCutoff) {
|
||||
return {
|
||||
minimum_grade_credit: interpolate(
|
||||
minimum_grade_credit: StringUtils.interpolate(
|
||||
gettext('Not able to set passing grade to less than %(minimum_grade_cutoff)s%.'),
|
||||
{minimum_grade_cutoff: minimum_grade_cutoff * 100},
|
||||
{minimum_grade_cutoff: minimumGradeCutoff * 100},
|
||||
true
|
||||
)
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ define(['js/views/baseview', 'underscore'], function(BaseView, _) {
|
||||
// Backbone model cid is only unique within the collection.
|
||||
this.uniqueId = _.uniqueId(templateName + '_');
|
||||
this.template = this.loadTemplate(templateName);
|
||||
// xss-lint: disable=javascript-jquery-html
|
||||
this.$el.html(this.template({model: this.model, uniqueId: this.uniqueId}));
|
||||
this.listenTo(this.model, 'change', this.render);
|
||||
this.render();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/views/feedback_prompt',
|
||||
'common/js/components/views/feedback_notification'],
|
||||
function(BaseView, _, gettext, PromptView, NotificationView) {
|
||||
'common/js/components/views/feedback_notification', 'edx-ui-toolkit/js/utils/html-utils'],
|
||||
function(BaseView, _, gettext, PromptView, NotificationView, HtmlUtils) {
|
||||
'use strict';
|
||||
var AssetView = BaseView.extend({
|
||||
initialize: function() {
|
||||
this.template = this.loadTemplate('asset');
|
||||
@@ -14,7 +15,7 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
|
||||
|
||||
render: function() {
|
||||
var uniqueId = _.uniqueId('lock_asset_');
|
||||
this.$el.html(this.template({
|
||||
var attributes = {
|
||||
display_name: this.model.get('display_name'),
|
||||
thumbnail: this.model.get('thumbnail'),
|
||||
date_added: this.model.get('date_added'),
|
||||
@@ -23,32 +24,32 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
|
||||
portable_url: this.model.get('portable_url'),
|
||||
asset_type: this.model.get_extension(),
|
||||
uniqueId: uniqueId
|
||||
}));
|
||||
};
|
||||
this.$el.html(HtmlUtils.HTML(this.template(attributes)).toString());
|
||||
this.updateLockState();
|
||||
return this;
|
||||
},
|
||||
|
||||
updateLockState: function() {
|
||||
var locked_class = 'is-locked';
|
||||
var lockedClass = 'is-locked';
|
||||
|
||||
// Add a class of "locked" to the tr element if appropriate,
|
||||
// and toggle locked state of hidden checkbox.
|
||||
if (this.model.get('locked')) {
|
||||
this.$el.addClass(locked_class);
|
||||
this.$el.addClass(lockedClass);
|
||||
this.$el.find('.lock-checkbox').attr('checked', 'checked');
|
||||
} else {
|
||||
this.$el.removeClass(locked_class);
|
||||
this.$el.removeClass(lockedClass);
|
||||
this.$el.find('.lock-checkbox').removeAttr('checked');
|
||||
}
|
||||
},
|
||||
|
||||
confirmDelete: function(e) {
|
||||
var asset = this.model;
|
||||
if (e && e.preventDefault) { e.preventDefault(); }
|
||||
var asset = this.model,
|
||||
collection = this.model.collection;
|
||||
new PromptView.Warning({
|
||||
title: gettext('Delete File Confirmation'),
|
||||
message: gettext('Are you sure you wish to delete this item. It cannot be reversed!\n\nAlso any content that links/refers to this item will no longer work (e.g. broken images and/or links)'),
|
||||
message: gettext('Are you sure you wish to delete this item. It cannot be reversed!\n\nAlso any content that links/refers to this item will no longer work (e.g. broken images and/or links)'), // eslint-disable-line max-len
|
||||
actions: {
|
||||
primary: {
|
||||
text: gettext('Delete'),
|
||||
@@ -76,7 +77,7 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
|
||||
}).show();
|
||||
},
|
||||
|
||||
lockAsset: function(e) {
|
||||
lockAsset: function() {
|
||||
var asset = this.model;
|
||||
var saving = new NotificationView.Mini({
|
||||
title: gettext('Saving')
|
||||
|
||||
@@ -1,102 +1,105 @@
|
||||
define(['js/views/baseview', 'codemirror', 'common/js/components/views/feedback_notification', 'js/views/course_info_helper', 'js/utils/modal'],
|
||||
function(BaseView, CodeMirror, NotificationView, CourseInfoHelper, ModalUtils) {
|
||||
define([
|
||||
'js/views/baseview',
|
||||
'codemirror',
|
||||
'common/js/components/views/feedback_notification',
|
||||
'js/views/course_info_helper',
|
||||
'js/utils/modal',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function(BaseView, CodeMirror, NotificationView, CourseInfoHelper, ModalUtils, HtmlUtils) {
|
||||
'use strict';
|
||||
// the handouts view is dumb right now; it needs tied to a model and all that jazz
|
||||
var CourseInfoHandoutsView = BaseView.extend({
|
||||
// collection is CourseUpdateCollection
|
||||
events: {
|
||||
'click .save-button': 'onSave',
|
||||
'click .cancel-button': 'onCancel',
|
||||
'click .edit-button': 'onEdit'
|
||||
},
|
||||
var CourseInfoHandoutsView = BaseView.extend({
|
||||
// collection is CourseUpdateCollection
|
||||
events: {
|
||||
'click .save-button': 'onSave',
|
||||
'click .cancel-button': 'onCancel',
|
||||
'click .edit-button': 'onEdit'
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.template = this.loadTemplate('course_info_handouts');
|
||||
var self = this;
|
||||
this.model.fetch({
|
||||
complete: function() {
|
||||
self.render();
|
||||
},
|
||||
reset: true
|
||||
});
|
||||
},
|
||||
initialize: function() {
|
||||
var self = this;
|
||||
this.template = this.loadTemplate('course_info_handouts');
|
||||
this.model.fetch({
|
||||
complete: function() {
|
||||
self.render();
|
||||
},
|
||||
reset: true
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
CourseInfoHelper.changeContentToPreview(
|
||||
this.model, 'data', this.options.base_asset_url);
|
||||
render: function() {
|
||||
CourseInfoHelper.changeContentToPreview(
|
||||
this.model, 'data', this.options.base_asset_url);
|
||||
this.$el.html(HtmlUtils.HTML($(this.template({model: this.model}))).toString());
|
||||
HtmlUtils.setHtml($('.handouts-content'), HtmlUtils.HTML(this.model.get('data')));
|
||||
this.$preview = this.$el.find('.handouts-content');
|
||||
this.$form = this.$el.find('.edit-handouts-form');
|
||||
this.$editor = this.$form.find('.handouts-content-editor');
|
||||
this.$form.hide();
|
||||
|
||||
this.$el.html(
|
||||
$(this.template({
|
||||
model: this.model
|
||||
}))
|
||||
);
|
||||
$('.handouts-content').html(this.model.get('data'));
|
||||
this.$preview = this.$el.find('.handouts-content');
|
||||
this.$form = this.$el.find('.edit-handouts-form');
|
||||
this.$editor = this.$form.find('.handouts-content-editor');
|
||||
this.$form.hide();
|
||||
return this;
|
||||
},
|
||||
|
||||
return this;
|
||||
},
|
||||
onEdit: function() {
|
||||
var self = this;
|
||||
this.$editor.val(this.$preview.html());
|
||||
this.$form.show();
|
||||
|
||||
onEdit: function(event) {
|
||||
var self = this;
|
||||
this.$editor.val(this.$preview.html());
|
||||
this.$form.show();
|
||||
this.$codeMirror = CourseInfoHelper.editWithCodeMirror(
|
||||
self.model, 'data', self.options.base_asset_url, this.$editor.get(0));
|
||||
|
||||
this.$codeMirror = CourseInfoHelper.editWithCodeMirror(
|
||||
self.model, 'data', self.options.base_asset_url, this.$editor.get(0));
|
||||
ModalUtils.showModalCover(false, function() { self.closeEditor(); });
|
||||
},
|
||||
|
||||
ModalUtils.showModalCover(false, function() { self.closeEditor(); });
|
||||
},
|
||||
|
||||
onSave: function(event) {
|
||||
var handoutsContent = this.$codeMirror.getValue();
|
||||
$('#handout_error').removeClass('is-shown');
|
||||
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
|
||||
if ($('.CodeMirror-lines').find('.cm-error').length == 0) {
|
||||
if (handoutsContent === '') {
|
||||
handoutsContent = '<ol></ol>';
|
||||
}
|
||||
this.model.set('data', handoutsContent);
|
||||
var saving = new NotificationView.Mini({
|
||||
title: gettext('Saving')
|
||||
});
|
||||
saving.show();
|
||||
this.model.save({}, {
|
||||
success: function() {
|
||||
saving.hide();
|
||||
}
|
||||
});
|
||||
this.render();
|
||||
this.$form.hide();
|
||||
this.closeEditor();
|
||||
|
||||
analytics.track('Saved Course Handouts', {
|
||||
course: course_location_analytics
|
||||
});
|
||||
} else {
|
||||
$('#handout_error').addClass('is-shown');
|
||||
$('.save-button').addClass('is-disabled').attr('aria-disabled', true);
|
||||
event.preventDefault();
|
||||
onSave: function(event) {
|
||||
var saving = new NotificationView.Mini({
|
||||
title: gettext('Saving')
|
||||
});
|
||||
var handoutsContent = this.$codeMirror.getValue();
|
||||
$('#handout_error').removeClass('is-shown');
|
||||
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
|
||||
if ($('.CodeMirror-lines').find('.cm-error').length === 0) {
|
||||
if (handoutsContent === '') {
|
||||
handoutsContent = '<ol></ol>';
|
||||
}
|
||||
},
|
||||
|
||||
onCancel: function(event) {
|
||||
$('#handout_error').removeClass('is-shown');
|
||||
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
|
||||
this.model.set('data', handoutsContent);
|
||||
saving.show();
|
||||
this.model.save({}, {
|
||||
success: function() {
|
||||
saving.hide();
|
||||
}
|
||||
});
|
||||
this.render();
|
||||
this.$form.hide();
|
||||
this.closeEditor();
|
||||
},
|
||||
|
||||
closeEditor: function() {
|
||||
$('#handout_error').removeClass('is-shown');
|
||||
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
|
||||
this.$form.hide();
|
||||
ModalUtils.hideModalCover();
|
||||
this.$form.find('.CodeMirror').remove();
|
||||
this.$codeMirror = null;
|
||||
analytics.track('Saved Course Handouts', { // eslint-disable-line no-undef
|
||||
course: course_location_analytics // eslint-disable-line no-undef
|
||||
});
|
||||
} else {
|
||||
$('#handout_error').addClass('is-shown');
|
||||
$('.save-button').addClass('is-disabled').attr('aria-disabled', true);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
return CourseInfoHandoutsView;
|
||||
}); // end define()
|
||||
onCancel: function() {
|
||||
$('#handout_error').removeClass('is-shown');
|
||||
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
|
||||
this.$form.hide();
|
||||
this.closeEditor();
|
||||
},
|
||||
|
||||
closeEditor: function() {
|
||||
$('#handout_error').removeClass('is-shown');
|
||||
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
|
||||
this.$form.hide();
|
||||
ModalUtils.hideModalCover();
|
||||
this.$form.find('.CodeMirror').remove();
|
||||
this.$codeMirror = null;
|
||||
}
|
||||
});
|
||||
|
||||
return CourseInfoHandoutsView;
|
||||
}); // end define()
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%page expression_filter="h"/>
|
||||
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%!
|
||||
from openedx.core.djangolib.js_utils import (
|
||||
dump_js_escaped_json
|
||||
)
|
||||
%>
|
||||
<%! import json %>
|
||||
<!DOCTYPE HTML>
|
||||
<script src="${static.url('js/vendor/xdomain.min.js')}"></script>
|
||||
<script>xdomain.masters(${xdomain_masters});</script>
|
||||
<script>xdomain.masters(${json.loads(xdomain_masters) | n, dump_js_escaped_json});</script>
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
[
|
||||
'gettext', 'jquery', 'underscore', 'backbone', 'moment',
|
||||
'text!learner_profile/templates/badge.underscore',
|
||||
'learner_profile/js/views/share_modal_view'
|
||||
'learner_profile/js/views/share_modal_view',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function(gettext, $, _, Backbone, Moment, badgeTemplate, ShareModalView) {
|
||||
function(gettext, $, _, Backbone, Moment, badgeTemplate, ShareModalView, HtmlUtils) {
|
||||
var BadgeView = Backbone.View.extend({
|
||||
initialize: function(options) {
|
||||
this.options = _.extend({}, options);
|
||||
@@ -35,7 +36,7 @@
|
||||
modal.$el.fadeIn('short', 'swing', _.bind(modal.ready, modal));
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template(this.context));
|
||||
this.$el.html(HtmlUtils.HTML(this.template(this.context)).toString());
|
||||
this.shareButton = this.$el.find('.share-button');
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
define(
|
||||
[
|
||||
'gettext', 'jquery', 'underscore', 'backbone', 'text!learner_profile/templates/section_two.underscore'
|
||||
'gettext', 'jquery', 'underscore', 'backbone', 'text!learner_profile/templates/section_two.underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function(gettext, $, _, Backbone, sectionTwoTemplate) {
|
||||
function(gettext, $, _, Backbone, sectionTwoTemplate, HtmlUtils) {
|
||||
var SectionTwoTab = Backbone.View.extend({
|
||||
attributes: {
|
||||
class: 'wrapper-profile-section-two'
|
||||
@@ -17,10 +18,7 @@
|
||||
render: function() {
|
||||
var self = this;
|
||||
var showFullProfile = this.options.showFullProfile();
|
||||
this.$el.html(this.template({
|
||||
ownProfile: self.options.ownProfile,
|
||||
showFullProfile: showFullProfile
|
||||
}));
|
||||
this.$el.html(HtmlUtils.HTML(this.template({ownProfile: self.options.ownProfile, showFullProfile: showFullProfile})).toString()); // eslint-disable-line max-len
|
||||
if (showFullProfile) {
|
||||
_.each(this.options.viewList, function(fieldView) {
|
||||
self.$el.find('.field-container').append(fieldView.render().el);
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
define(
|
||||
[
|
||||
'gettext', 'jquery', 'underscore', 'backbone', 'moment',
|
||||
'text!learner_profile/templates/share_modal.underscore'
|
||||
'text!learner_profile/templates/share_modal.underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
],
|
||||
function(gettext, $, _, Backbone, Moment, badgeModalTemplate) {
|
||||
function(gettext, $, _, Backbone, Moment, badgeModalTemplate, HtmlUtils) {
|
||||
var ShareModalView = Backbone.View.extend({
|
||||
attributes: {
|
||||
class: 'badges-overlay'
|
||||
@@ -45,7 +46,7 @@
|
||||
this.$el.find('.badges-modal').focus();
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
this.$el.html(HtmlUtils.HTML(this.template(this.model.toJSON())).toString());
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<td width="70">
|
||||
<a href="{% with_link_tracking homepage_url %}"><img
|
||||
src="http://localhost:18000/static/red-theme/images/logo.png"
|
||||
alt="{% blocktrans %}Go to {{ platform_name }} Home Page{% endblocktrans %}"/></a>
|
||||
alt="{% filter force_escape %} {% blocktrans %}Go to {{ platform_name }} Home Page{% endblocktrans %} {% endfilter %}"/></a>
|
||||
</td>
|
||||
<td align="right" style="text-align: {{ LANGUAGE_BIDI|yesno:"left,right" }};">
|
||||
<a class="login" href="{% with_link_tracking dashboard_url %}" style="color: #960909;">{% trans "Sign In" %}</a>
|
||||
@@ -97,7 +97,7 @@
|
||||
<td height="32" width="42">
|
||||
<a href="{{ social_media_urls.linkedin|safe }}">
|
||||
<img src="https://media.sailthru.com/595/1k1/8/o/599f354ec70cb.png"
|
||||
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on LinkedIn{% endblocktrans %}"/>
|
||||
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on LinkedIn{% endblocktrans %} {% endfilter %}"/>
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
@@ -105,7 +105,7 @@
|
||||
<td height="32" width="42">
|
||||
<a href="{{ social_media_urls.twitter|safe }}">
|
||||
<img src="https://media.sailthru.com/595/1k1/8/o/599f354d9c26e.png"
|
||||
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Twitter{% endblocktrans %}"/>
|
||||
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Twitter{% endblocktrans %} {% endfilter %}"/>
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
@@ -113,7 +113,7 @@
|
||||
<td height="32" width="42">
|
||||
<a href="{{ social_media_urls.facebook|safe }}">
|
||||
<img src="https://media.sailthru.com/595/1k1/8/o/599f355052c8e.png"
|
||||
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Facebook{% endblocktrans %}"/>
|
||||
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Facebook{% endblocktrans %} {% endfilter %}"/>
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
@@ -121,7 +121,7 @@
|
||||
<td height="32" width="42">
|
||||
<a href="{{ social_media_urls.google_plus|safe }}">
|
||||
<img src="https://media.sailthru.com/595/1k1/8/o/599f354fc554a.png"
|
||||
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Google Plus{% endblocktrans %}"/>
|
||||
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Google Plus{% endblocktrans %} {% endfilter %}"/>
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
@@ -129,7 +129,7 @@
|
||||
<td height="32" width="42">
|
||||
<a href="{{ social_media_urls.reddit|safe }}">
|
||||
<img src="https://media.sailthru.com/595/1k1/8/o/599f354e326b9.png"
|
||||
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Reddit{% endblocktrans %}"/>
|
||||
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Reddit{% endblocktrans %} {% endfilter %}"/>
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
@@ -143,14 +143,14 @@
|
||||
{% if mobile_store_urls.apple %}
|
||||
<a href="{{ mobile_store_urls.apple|safe }}" style="text-decoration: none">
|
||||
<img src="https://media.sailthru.com/595/1k1/6/2/5931cfbba391b.png"
|
||||
alt="{% trans "Download the iOS app on the Apple Store" %}"
|
||||
alt="{% trans "Download the iOS app on the Apple Store" as tmsg %}{{ tmsg | force_escape }}"
|
||||
width="136" height="50" style="margin-{{ LANGUAGE_BIDI|yesno:"left,right" }}: 10px"/>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if mobile_store_urls.google %}
|
||||
<a href="{{ mobile_store_urls.google|safe }}" style="text-decoration: none">
|
||||
<img src="https://media.sailthru.com/595/1k1/6/2/5931cf879a033.png"
|
||||
alt="{% trans "Download the Android app on the Google Play Store" %}"
|
||||
alt="{% trans "Download the Android app on the Google Play Store" as tmsg %}{{ tmsg | force_escape }}"
|
||||
width="136" height="50"/>
|
||||
</a>
|
||||
{% endif %}
|
||||
@@ -171,9 +171,9 @@
|
||||
<tr>
|
||||
<!-- COPYRIGHT -->
|
||||
<td>
|
||||
© {% now "Y" %} {{ platform_name }}, {% trans "All rights reserved" %}.<br/>
|
||||
© {% now "Y" %} {{ platform_name }}, {% trans "All rights reserved" as tmsg %}{{ tmsg | force_escape }}.<br/>
|
||||
<br/>
|
||||
{% trans "Our mailing address is" %}:<br/>
|
||||
{% trans "Our mailing address is" as tmsg %}{{ tmsg | force_escape }}:<br/>
|
||||
{{ contact_mailing_address }}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
%>
|
||||
@@ -5,10 +6,10 @@ from django.utils.translation import ugettext as _
|
||||
<header>
|
||||
<div class="social-sharing">
|
||||
<div class="sharing-message">${_("Share with friends and family!")}</div>
|
||||
<a href="http://twitter.com/intent/tweet?text=I+just+enrolled+in+${course.number}+${course.display_name_with_default_escaped}!+(http://class.stanford.edu)" class="share">
|
||||
<a href="http://twitter.com/intent/tweet?text=I+just+enrolled+in+${course.number}+${course.display_name_with_default}!+(http://class.stanford.edu)" class="share">
|
||||
<span class="icon fa fa-twitter" aria-hidden="true"></span><span class="sr">${_("Tweet that you've enrolled in this course")}</span>
|
||||
</a>
|
||||
<a href="mailto:?subject=Take%20a%20course%20at%20Stanford%20online!&body=I%20just%20enrolled%20in%20${course.number}%20${course.display_name_with_default_escaped}+(http://class.stanford.edu)" class="share">
|
||||
<a href="mailto:?subject=Take%20a%20course%20at%20Stanford%20online!&body=I%20just%20enrolled%20in%20${course.number}%20${course.display_name_with_default}+(http://class.stanford.edu)" class="share">
|
||||
<span class="icon fa fa-envelope" aria-hidden="true"></span><span class="sr">${_("Email someone to say you've enrolled in this course")}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user