Commit 3d4f9268 by Peter Fogg

Make sure that changing grading cutoffs triggers a save confirmation, and…

Make sure that changing grading cutoffs triggers a save confirmation, and reliable reverting of changes.
parent eba1bd09
...@@ -61,7 +61,10 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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({ ...@@ -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() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment