-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
course_grader.js
79 lines (77 loc) · 3.64 KB
/
course_grader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
define(["backbone", "underscore", "gettext"], function(Backbone, _, gettext) {
var CourseGrader = Backbone.Model.extend({
defaults: {
"type" : "", // must be unique w/in collection (ie. w/in course)
"min_count" : 1,
"drop_count" : 0,
"short_label" : "", // what to use in place of type if space is an issue
"weight" : 0 // int 0..100
},
parse : function(attrs) {
// round off values while converting them to integer
if (attrs['weight']) {
attrs.weight = Math.round(attrs.weight);
}
if (attrs['min_count']) {
attrs.min_count = Math.round(attrs.min_count);
}
if (attrs['drop_count']) {
attrs.drop_count = Math.round(attrs.drop_count);
}
return attrs;
},
validate : function(attrs) {
var errors = {};
if (_.has(attrs, 'type')) {
if (_.isEmpty(attrs['type'])) {
errors.type = "The assignment type must have a name.";
}
else {
// FIXME somehow this.collection is unbound sometimes. I can't track down when
var existing = this.collection && this.collection.some(function(other) { return (other.cid != this.cid) && (other.get('type') == attrs['type']);}, this);
if (existing) {
errors.type = gettext("There's already another assignment type with this name.");
}
}
}
if (_.has(attrs, 'weight')) {
var intWeight = Math.round(attrs.weight); // see if this ensures value saved is int
if (!isFinite(intWeight) || /\D+/.test(attrs.weight) || intWeight < 0 || intWeight > 100) {
errors.weight = gettext("Please enter an integer between 0 and 100.");
}
else {
attrs.weight = intWeight;
if (this.collection && attrs.weight > 0) {
// FIXME b/c saves don't update the models if validation fails, we should
// either revert the field value to the one in the model and make them make room
// or figure out a holistic way to balance the vals across the whole
// if ((this.collection.sumWeights() + attrs.weight - this.get('weight')) > 100)
// errors.weight = "The weights cannot add to more than 100.";
}
}}
if (_.has(attrs, 'min_count')) {
var intMinCount = Math.round(attrs.min_count);
if (!isFinite(intMinCount) || /\D+/.test(attrs.min_count) || intMinCount < 1) {
errors.min_count = gettext("Please enter an integer greater than 0.");
}
else attrs.min_count = intMinCount;
}
if (_.has(attrs, 'drop_count')) {
var dropCount = attrs.drop_count;
var intDropCount = Math.round(dropCount);
if (!isFinite(intDropCount) || /\D+/.test(dropCount) || (_.isString(dropCount) && _.isEmpty(dropCount.trim())) || intDropCount < 0) {
errors.drop_count = gettext("Please enter non-negative integer.");
}
else attrs.drop_count = intDropCount;
}
if (_.has(attrs, 'min_count') && _.has(attrs, 'drop_count') && !_.has(errors, 'min_count') && !_.has(errors, 'drop_count') && attrs.drop_count > attrs.min_count) {
var template = _.template(
gettext("Cannot drop more <%= types %> assignments than are assigned.")
);
errors.drop_count = template({types: attrs.type});
}
if (!_.isEmpty(errors)) return errors;
}
});
return CourseGrader;
}); // end define()