Fix validation in many cases, and ensure that the notification bar pops up correctly.

This commit is contained in:
Peter Fogg
2013-07-02 11:46:26 -04:00
parent d9716a7249
commit c2f0b7d4e9
5 changed files with 62 additions and 36 deletions

View File

@@ -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() {

View File

@@ -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();
}
});

View File

@@ -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