Make sure that changing grading cutoffs triggers a save confirmation, and reliable reverting of changes.
This commit is contained in:
@@ -61,7 +61,10 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
|
|||||||
var message = gettext("Your changes will not take effect until you save your progress. Take care with key and value formatting, as validation is not implemented.");
|
var message = gettext("Your changes will not take effect until you save your progress. Take care with key and value formatting, as validation is not implemented.");
|
||||||
self.showNotificationBar(message,
|
self.showNotificationBar(message,
|
||||||
_.bind(self.saveView, self),
|
_.bind(self.saveView, self),
|
||||||
_.bind(self.revertView, self));
|
function() {
|
||||||
|
self.model.deleteKeys = [];
|
||||||
|
self.revertView();
|
||||||
|
});
|
||||||
if(self.saved) {
|
if(self.saved) {
|
||||||
self.saved.hide();
|
self.saved.hide();
|
||||||
}
|
}
|
||||||
@@ -112,25 +115,19 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
|
|||||||
{
|
{
|
||||||
success : function() {
|
success : function() {
|
||||||
self.render();
|
self.render();
|
||||||
|
var title = gettext("Your policy changes have been saved.");
|
||||||
var message = gettext("Please note that validation of your policy key and value pairs is not currently in place yet. If you are having difficulties, please review your policy pairs.");
|
var message = gettext("Please note that validation of your policy key and value pairs is not currently in place yet. If you are having difficulties, please review your policy pairs.");
|
||||||
self.saved = new CMS.Views.Alert.Confirmation({
|
self.showSavedBar(title, message);
|
||||||
title: gettext("Your policy changes have been saved."),
|
|
||||||
message: message,
|
|
||||||
closeIcon: false
|
|
||||||
});
|
|
||||||
self.saved.show();
|
|
||||||
analytics.track('Saved Advanced Settings', {
|
analytics.track('Saved Advanced Settings', {
|
||||||
'course': course_location_analytics
|
'course': course_location_analytics
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
revertView : function() {
|
revertView: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.model.deleteKeys = [];
|
|
||||||
this.model.clear({silent : true});
|
|
||||||
this.model.fetch({
|
this.model.fetch({
|
||||||
success : function() { self.render(); },
|
success: function() { self.render(); },
|
||||||
reset: true
|
reset: true
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -144,7 +144,8 @@ CMS.Views.Settings.Details = CMS.Views.ValidatingView.extend({
|
|||||||
}
|
}
|
||||||
var self = this;
|
var self = this;
|
||||||
this.showNotificationBar(this.save_message,
|
this.showNotificationBar(this.save_message,
|
||||||
_.bind(this.saveModel, this));
|
_.bind(this.saveView, this),
|
||||||
|
_.bind(this.revertView, this));
|
||||||
},
|
},
|
||||||
|
|
||||||
removeSyllabus: function() {
|
removeSyllabus: function() {
|
||||||
@@ -185,12 +186,29 @@ CMS.Views.Settings.Details = CMS.Views.ValidatingView.extend({
|
|||||||
if (cachethis.model.get(field) != newVal) {
|
if (cachethis.model.get(field) != newVal) {
|
||||||
cachethis.model.set(field, newVal);
|
cachethis.model.set(field, newVal);
|
||||||
cachethis.showNotificationBar(cachethis.save_message,
|
cachethis.showNotificationBar(cachethis.save_message,
|
||||||
_.bind(cachethis.saveModel, cachethis));
|
_.bind(cachethis.saveView, cachethis),
|
||||||
|
_.bind(cachethis.revertView, cachethis));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
revertView: function() {
|
||||||
|
// Make sure that the CodeMirror instance has the correct
|
||||||
|
// data from its corresponding textarea
|
||||||
|
var self = this;
|
||||||
|
this.model.fetch({
|
||||||
|
success: function() {
|
||||||
|
self.render();
|
||||||
|
_.each(self.codeMirrors,
|
||||||
|
function(mirror) {
|
||||||
|
var ele = mirror.getTextArea();
|
||||||
|
var field = self.selectorToField[ele.id];
|
||||||
|
mirror.setValue(self.model.get(field));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reset: true});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
'<% if (removable) {%><a href="#" class="remove-button">remove</a><% ;} %>' +
|
'<% if (removable) {%><a href="#" class="remove-button">remove</a><% ;} %>' +
|
||||||
'</li>');
|
'</li>');
|
||||||
|
|
||||||
// Instrument grading scale
|
this.setupCutoffs();
|
||||||
// convert cutoffs to inversely ordered list
|
|
||||||
var modelCutoffs = this.model.get('grade_cutoffs');
|
|
||||||
for (var cutoff in modelCutoffs) {
|
|
||||||
this.descendingCutoffs.push({designation: cutoff, cutoff: Math.round(modelCutoffs[cutoff] * 100)});
|
|
||||||
}
|
|
||||||
this.descendingCutoffs = _.sortBy(this.descendingCutoffs,
|
|
||||||
function (gradeEle) { return -gradeEle['cutoff']; });
|
|
||||||
|
|
||||||
// Instrument grace period
|
// Instrument grace period
|
||||||
this.$el.find('#course-grading-graceperiod').timepicker();
|
this.$el.find('#course-grading-graceperiod').timepicker();
|
||||||
@@ -45,7 +38,6 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.listenTo(this.model, 'invalid', this.handleValidationError);
|
this.listenTo(this.model, 'invalid', this.handleValidationError);
|
||||||
this.model.get('graders').on('remove', this.render, this);
|
|
||||||
this.model.get('graders').on('reset', this.render, this);
|
this.model.get('graders').on('reset', this.render, this);
|
||||||
this.model.get('graders').on('add', this.render, this);
|
this.model.get('graders').on('add', this.render, this);
|
||||||
this.selectorToField = _.invert(this.fieldToSelectorMap);
|
this.selectorToField = _.invert(this.fieldToSelectorMap);
|
||||||
@@ -61,11 +53,25 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
// Undo the double invocation error. At some point, fix the double invocation
|
// Undo the double invocation error. At some point, fix the double invocation
|
||||||
$(gradelist).empty();
|
$(gradelist).empty();
|
||||||
var gradeCollection = this.model.get('graders');
|
var gradeCollection = this.model.get('graders');
|
||||||
|
// We need to bind the 'remove' event here (rather than in
|
||||||
|
// initialize), or else we can only press the delete button
|
||||||
|
// once due to the graders collection changing when we cancel
|
||||||
|
// our changes.
|
||||||
|
gradeCollection.on('remove', function() {
|
||||||
|
this.showNotificationBar();
|
||||||
|
this.render();
|
||||||
|
}, this);
|
||||||
gradeCollection.each(function(gradeModel) {
|
gradeCollection.each(function(gradeModel) {
|
||||||
$(gradelist).append(self.template({model : gradeModel }));
|
$(gradelist).append(self.template({model : gradeModel }));
|
||||||
var newEle = gradelist.children().last();
|
var newEle = gradelist.children().last();
|
||||||
var newView = new CMS.Views.Settings.GraderView({el: newEle,
|
var newView = new CMS.Views.Settings.GraderView({el: newEle,
|
||||||
model : gradeModel, collection : gradeCollection });
|
model : gradeModel, collection : gradeCollection });
|
||||||
|
// Listen in order to rerender when the 'cancel' button is
|
||||||
|
// pressed
|
||||||
|
self.listenTo(newView, 'revert', _.bind(self.render, self));
|
||||||
|
self.listenTo(gradeModel, 'change', function() {
|
||||||
|
self.showNotificationBar();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// render the grade cutoffs
|
// render the grade cutoffs
|
||||||
@@ -83,6 +89,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
addAssignmentType : function(e) {
|
addAssignmentType : function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.model.get('graders').push({});
|
this.model.get('graders').push({});
|
||||||
|
this.showNotificationBar();
|
||||||
},
|
},
|
||||||
fieldToSelectorMap : {
|
fieldToSelectorMap : {
|
||||||
'grace_period' : 'course-grading-graceperiod'
|
'grace_period' : 'course-grading-graceperiod'
|
||||||
@@ -92,8 +99,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
self.clearValidationErrors();
|
self.clearValidationErrors();
|
||||||
var newVal = self.model.dateToGracePeriod($(event.currentTarget).timepicker('getTime'));
|
var newVal = self.model.dateToGracePeriod($(event.currentTarget).timepicker('getTime'));
|
||||||
self.model.set('grace_period', newVal, {validate: true});
|
self.model.set('grace_period', newVal, {validate: true});
|
||||||
self.showNotificationBar(self.save_message,
|
self.showNotificationBar();
|
||||||
_.bind(self.saveModel, self));
|
|
||||||
},
|
},
|
||||||
updateModel : function(event) {
|
updateModel : function(event) {
|
||||||
if (!this.selectorToField[event.currentTarget.id]) return;
|
if (!this.selectorToField[event.currentTarget.id]) return;
|
||||||
@@ -106,9 +112,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
this.setField(event);
|
this.setField(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var self = this;
|
this.showNotificationBar();
|
||||||
this.showNotificationBar(this.save_message,
|
|
||||||
_.bind(self.saveModel, self));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Grade sliders attributes and methods
|
// Grade sliders attributes and methods
|
||||||
@@ -234,8 +238,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
},
|
},
|
||||||
{}),
|
{}),
|
||||||
{validate: true});
|
{validate: true});
|
||||||
this.showNotificationBar(this.save_message,
|
this.showNotificationBar();
|
||||||
_.bind(this.saveModel, this));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addNewGrade: function(e) {
|
addNewGrade: function(e) {
|
||||||
@@ -310,8 +313,36 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
|||||||
},
|
},
|
||||||
setTopGradeLabel: function() {
|
setTopGradeLabel: function() {
|
||||||
this.$el.find('.grades .letter-grade').first().html(this.descendingCutoffs[0]['designation']);
|
this.$el.find('.grades .letter-grade').first().html(this.descendingCutoffs[0]['designation']);
|
||||||
|
},
|
||||||
|
setupCutoffs: function() {
|
||||||
|
// Instrument grading scale
|
||||||
|
// convert cutoffs to inversely ordered list
|
||||||
|
var modelCutoffs = this.model.get('grade_cutoffs');
|
||||||
|
for (var cutoff in modelCutoffs) {
|
||||||
|
this.descendingCutoffs.push({designation: cutoff, cutoff: Math.round(modelCutoffs[cutoff] * 100)});
|
||||||
|
}
|
||||||
|
this.descendingCutoffs = _.sortBy(this.descendingCutoffs,
|
||||||
|
function (gradeEle) { return -gradeEle['cutoff']; });
|
||||||
|
},
|
||||||
|
revertView: function() {
|
||||||
|
var self = this;
|
||||||
|
this.model.fetch({
|
||||||
|
success: function() {
|
||||||
|
self.descendingCutoffs = [];
|
||||||
|
self.setupCutoffs();
|
||||||
|
self.render();
|
||||||
|
self.renderCutoffBar();
|
||||||
|
},
|
||||||
|
reset: true});
|
||||||
|
},
|
||||||
|
showNotificationBar: function() {
|
||||||
|
// We always call showNotificationBar with the same args, just
|
||||||
|
// delegate to superclass
|
||||||
|
CMS.Views.ValidatingView.prototype.showNotificationBar.call(this,
|
||||||
|
this.save_message,
|
||||||
|
_.bind(this.saveView, this),
|
||||||
|
_.bind(this.revertView, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
CMS.Views.Settings.GraderView = CMS.Views.ValidatingView.extend({
|
CMS.Views.Settings.GraderView = CMS.Views.ValidatingView.extend({
|
||||||
@@ -368,13 +399,9 @@ CMS.Views.Settings.GraderView = CMS.Views.ValidatingView.extend({
|
|||||||
this.setField(event);
|
this.setField(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var self = this;
|
|
||||||
this.showNotificationBar(this.save_message,
|
|
||||||
_.bind(this.saveModel, this));
|
|
||||||
},
|
},
|
||||||
deleteModel : function(e) {
|
deleteModel : function(e) {
|
||||||
this.model.destroy();
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this.collection.remove(this.model);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ CMS.Views.ValidatingView = Backbone.View.extend({
|
|||||||
if(secondaryClick) {
|
if(secondaryClick) {
|
||||||
secondaryClick();
|
secondaryClick();
|
||||||
}
|
}
|
||||||
|
self.model.clear({silent : true});
|
||||||
|
/*self.model.fetch({
|
||||||
|
success : function() { self.render(); },
|
||||||
|
reset: true
|
||||||
|
});*/
|
||||||
self.confirmation.hide();
|
self.confirmation.hide();
|
||||||
self.notificationBarShowing = false;
|
self.notificationBarShowing = false;
|
||||||
}
|
}
|
||||||
@@ -111,7 +116,7 @@ CMS.Views.ValidatingView = Backbone.View.extend({
|
|||||||
this.saved.show();
|
this.saved.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveModel: function() {
|
saveView: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.model.save({},
|
this.model.save({},
|
||||||
{success: function() {
|
{success: function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user