Fix validation in many cases, and ensure that the notification bar pops up correctly.
This commit is contained in:
@@ -56,6 +56,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
|
||||
CodeMirror.fromTextArea(textarea, {
|
||||
mode: "application/json", lineNumbers: false, lineWrapping: false,
|
||||
onChange: function(instance, changeobj) {
|
||||
instance.save()
|
||||
// this event's being called even when there's no change :-(
|
||||
if (instance.getValue() !== oldValue) {
|
||||
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.");
|
||||
@@ -94,8 +95,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
|
||||
}
|
||||
}
|
||||
if (JSONValue !== undefined) {
|
||||
self.clearValidationErrors();
|
||||
self.model.set(key, JSONValue, {validate: true});
|
||||
self.model.set(key, JSONValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -115,7 +115,8 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
|
||||
analytics.track('Saved Advanced Settings', {
|
||||
'course': course_location_analytics
|
||||
});
|
||||
}
|
||||
},
|
||||
silent: true
|
||||
});
|
||||
},
|
||||
revertView: function() {
|
||||
|
||||
@@ -89,7 +89,6 @@ CMS.Views.Settings.Details = CMS.Views.ValidatingView.extend({
|
||||
var timefield = $(div).find("input:.time");
|
||||
var cachethis = this;
|
||||
var setfield = function () {
|
||||
cachethis.clearValidationErrors();
|
||||
var date = datefield.datepicker('getDate');
|
||||
if (date) {
|
||||
var time = timefield.timepicker("getSecondsFromMidnight");
|
||||
@@ -98,14 +97,16 @@ CMS.Views.Settings.Details = CMS.Views.ValidatingView.extend({
|
||||
}
|
||||
var newVal = new Date(date.getTime() + time * 1000);
|
||||
if (!cacheModel.has(fieldName) || cacheModel.get(fieldName).getTime() !== newVal.getTime()) {
|
||||
cacheModel.set(fieldName, newVal, {validate: true});
|
||||
cachethis.clearValidationErrors();
|
||||
cachethis.setAndValidate(fieldName, newVal);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Clear date (note that this clears the time as well, as date and time are linked).
|
||||
// Note also that the validation logic prevents us from clearing the start date
|
||||
// (start date is required by the back end).
|
||||
cacheModel.set(fieldName, null, {validate: true});
|
||||
cachethis.clearValidationErrors();
|
||||
cachethis.setAndValidate(fieldName, null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -142,14 +143,13 @@ CMS.Views.Settings.Details = CMS.Views.ValidatingView.extend({
|
||||
default: // Everything else is handled by datepickers and CodeMirror.
|
||||
break;
|
||||
}
|
||||
var self = this;
|
||||
this.showNotificationBar(this.save_message,
|
||||
_.bind(this.saveView, this),
|
||||
_.bind(this.revertView, this));
|
||||
},
|
||||
|
||||
removeSyllabus: function() {
|
||||
if (this.model.has('syllabus')) this.model.set({'syllabus': null});
|
||||
if (this.model.has('syllabus')) this.setAndValidate('syllabus', null);
|
||||
},
|
||||
|
||||
assetSyllabus : function() {
|
||||
@@ -184,7 +184,7 @@ CMS.Views.Settings.Details = CMS.Views.ValidatingView.extend({
|
||||
cachethis.clearValidationErrors();
|
||||
var newVal = mirror.getValue();
|
||||
if (cachethis.model.get(field) != newVal) {
|
||||
cachethis.model.set(field, newVal);
|
||||
cachethis.setAndValidate(field, newVal);
|
||||
cachethis.showNotificationBar(cachethis.save_message,
|
||||
_.bind(cachethis.saveView, cachethis),
|
||||
_.bind(cachethis.revertView, cachethis));
|
||||
@@ -209,6 +209,16 @@ CMS.Views.Settings.Details = CMS.Views.ValidatingView.extend({
|
||||
});
|
||||
},
|
||||
reset: true});
|
||||
},
|
||||
setAndValidate: function(attr, value) {
|
||||
// If we call model.set() with {validate: true}, model fields
|
||||
// will not be set if validation fails. This puts the UI and
|
||||
// the model in an inconsistent state, and causes us to not
|
||||
// see the right validation errors the next time validate() is
|
||||
// called on the model. So we set *without* validating, then
|
||||
// call validate ourselves.
|
||||
this.model.set(attr, value);
|
||||
this.model.isValid();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
}
|
||||
);
|
||||
this.listenTo(this.model, 'invalid', this.handleValidationError);
|
||||
this.listenTo(this.model, 'change', this.showNotificationBar);
|
||||
this.model.get('graders').on('reset', this.render, this);
|
||||
this.model.get('graders').on('add', this.render, this);
|
||||
this.selectorToField = _.invert(this.fieldToSelectorMap);
|
||||
@@ -53,14 +54,18 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
// Undo the double invocation error. At some point, fix the double invocation
|
||||
$(gradelist).empty();
|
||||
var gradeCollection = this.model.get('graders');
|
||||
// We need to bind the 'remove' event here (rather than in
|
||||
// We need to bind these events 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);
|
||||
_.each(['change', 'remove', 'add'],
|
||||
function (event) {
|
||||
gradeCollection.on(event, function() {
|
||||
this.showNotificationBar();
|
||||
this.render();
|
||||
}, this);
|
||||
},
|
||||
this);
|
||||
gradeCollection.each(function(gradeModel) {
|
||||
$(gradelist).append(self.template({model : gradeModel }));
|
||||
var newEle = gradelist.children().last();
|
||||
@@ -69,9 +74,6 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
// 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
|
||||
@@ -89,7 +91,6 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
addAssignmentType : function(e) {
|
||||
e.preventDefault();
|
||||
this.model.get('graders').push({});
|
||||
this.showNotificationBar();
|
||||
},
|
||||
fieldToSelectorMap : {
|
||||
'grace_period' : 'course-grading-graceperiod'
|
||||
@@ -99,7 +100,6 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
self.clearValidationErrors();
|
||||
var newVal = self.model.dateToGracePeriod($(event.currentTarget).timepicker('getTime'));
|
||||
self.model.set('grace_period', newVal, {validate: true});
|
||||
self.showNotificationBar();
|
||||
},
|
||||
updateModel : function(event) {
|
||||
if (!this.selectorToField[event.currentTarget.id]) return;
|
||||
@@ -112,7 +112,6 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
this.setField(event);
|
||||
break;
|
||||
}
|
||||
this.showNotificationBar();
|
||||
},
|
||||
|
||||
// Grade sliders attributes and methods
|
||||
@@ -238,7 +237,6 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
},
|
||||
{}),
|
||||
{validate: true});
|
||||
this.showNotificationBar();
|
||||
},
|
||||
|
||||
addNewGrade: function(e) {
|
||||
@@ -333,7 +331,8 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
self.render();
|
||||
self.renderCutoffBar();
|
||||
},
|
||||
reset: true});
|
||||
reset: true,
|
||||
silent: true});
|
||||
},
|
||||
showNotificationBar: function() {
|
||||
// We always call showNotificationBar with the same args, just
|
||||
|
||||
Reference in New Issue
Block a user