Commit 85a1315e by muzaffaryousaf

Merging master into this branch

parents b64f73dc ba7136c4
...@@ -11,3 +11,4 @@ David Baumgold <david@davidbaumgold.com> ...@@ -11,3 +11,4 @@ David Baumgold <david@davidbaumgold.com>
Grady Ward <gward@brandeis.edu> Grady Ward <gward@brandeis.edu>
Andrew Dekker <a.dekker@uq.edu.au> Andrew Dekker <a.dekker@uq.edu.au>
Steven Burch <stv@stanford.edu> Steven Burch <stv@stanford.edu>
Muzaffar Yousaf <muzaffar@edx.org>
...@@ -9,6 +9,8 @@ class Migration(SchemaMigration): ...@@ -9,6 +9,8 @@ class Migration(SchemaMigration):
def forwards(self, orm): def forwards(self, orm):
# Make the AssessmentPart.criterion field NOT nullable # Make the AssessmentPart.criterion field NOT nullable
# Bug: The field was also (incorrectly) altered to point to the CriterionOption table instead of the Criterion
# table. This is fixed in migration 0024.
db.alter_column('assessment_assessmentpart', 'criterion_id', db.alter_column('assessment_assessmentpart', 'criterion_id',
self.gf('django.db.models.fields.related.ForeignKey')( self.gf('django.db.models.fields.related.ForeignKey')(
related_name='+', null=False, to=orm['assessment.CriterionOption'] related_name='+', null=False, to=orm['assessment.CriterionOption']
...@@ -94,7 +96,7 @@ class Migration(SchemaMigration): ...@@ -94,7 +96,7 @@ class Migration(SchemaMigration):
'assessment.assessmentpart': { 'assessment.assessmentpart': {
'Meta': {'object_name': 'AssessmentPart'}, 'Meta': {'object_name': 'AssessmentPart'},
'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}), 'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}),
'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.Criterion']"}), 'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.CriterionOption']"}),
'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), 'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.CriterionOption']"}) 'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.CriterionOption']"})
......
...@@ -91,7 +91,7 @@ class Migration(SchemaMigration): ...@@ -91,7 +91,7 @@ class Migration(SchemaMigration):
'assessment.assessmentpart': { 'assessment.assessmentpart': {
'Meta': {'object_name': 'AssessmentPart'}, 'Meta': {'object_name': 'AssessmentPart'},
'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}), 'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}),
'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.Criterion']"}), 'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.CriterionOption']"}),
'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), 'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.CriterionOption']"}) 'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.CriterionOption']"})
......
...@@ -98,7 +98,7 @@ class Migration(SchemaMigration): ...@@ -98,7 +98,7 @@ class Migration(SchemaMigration):
'assessment.assessmentpart': { 'assessment.assessmentpart': {
'Meta': {'object_name': 'AssessmentPart'}, 'Meta': {'object_name': 'AssessmentPart'},
'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}), 'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}),
'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.Criterion']"}), 'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.CriterionOption']"}),
'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), 'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.CriterionOption']"}) 'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.CriterionOption']"})
......
...@@ -95,7 +95,7 @@ class Migration(DataMigration): ...@@ -95,7 +95,7 @@ class Migration(DataMigration):
'assessment.assessmentpart': { 'assessment.assessmentpart': {
'Meta': {'object_name': 'AssessmentPart'}, 'Meta': {'object_name': 'AssessmentPart'},
'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}), 'assessment': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parts'", 'to': "orm['assessment.Assessment']"}),
'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.Criterion']"}), 'criterion': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['assessment.CriterionOption']"}),
'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), 'feedback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.CriterionOption']"}) 'option': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['assessment.CriterionOption']"})
......
...@@ -3,7 +3,10 @@ ...@@ -3,7 +3,10 @@
<li class="openassessment_criterion is-collapsible" data-criterion="{{ criterion_name }}"> <li class="openassessment_criterion is-collapsible" data-criterion="{{ criterion_name }}">
<div class="openassessment_criterion_header view-outline"> <div class="openassessment_criterion_header view-outline">
<a class="action expand-collapse collapse"><i class="icon-caret-down ui-toggle-expansion"></i></a> <a class="action expand-collapse collapse"><i class="icon-caret-down ui-toggle-expansion"></i></a>
<h6 class="openassessment_criterion_header_title">{% trans "Criterion" %}</h6> <div class="openassessment_criterion_header_title_box">
<h6 class="openassessment_criterion_header_title">{% trans "Criterion" %}</h6>
<p class="openassessment_criterion_guide">{% trans "You cannot delete a criterion after the assignment has been released." %}</p>
</div>
<div class="openassessment_criterion_remove_button"><h2>{% trans "Remove" %}</h2></div> <div class="openassessment_criterion_remove_button"><h2>{% trans "Remove" %}</h2></div>
</div> </div>
<div class="openassessment_criterion_body wrapper-comp-settings"> <div class="openassessment_criterion_body wrapper-comp-settings">
...@@ -61,4 +64,4 @@ ...@@ -61,4 +64,4 @@
</div> </div>
</div> </div>
</li> </li>
{% endspaceless %} {% endspaceless %}
\ No newline at end of file
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
<div class="wrapper-openassessment__message"> <div class="wrapper-openassessment__message">
{% block message %} {% block message %}
<div id="openassessment__message" class="openassessment__message message"> <div id="openassessment__message" class="openassessment__message message">
<h3 class="message__title">Instructions</h3>
<div class="message__content"> <div class="message__content">
<p>{% trans "This assignment has several steps. In the first step, you'll provide a response to the question. The other steps appear below the Your Response field." %}</p> <p>{% trans "This assignment has several steps. In the first step, you'll provide a response to the question. The other steps appear below the Your Response field." %}</p>
</div> </div>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -44,6 +44,10 @@ describe("OpenAssessment.DatetimeControl", function() { ...@@ -44,6 +44,10 @@ describe("OpenAssessment.DatetimeControl", function() {
testValidateDate(datetimeControl, "99999999-01-01", "00:00", false, expectedError); testValidateDate(datetimeControl, "99999999-01-01", "00:00", false, expectedError);
testValidateDate(datetimeControl, "2014-99999-01", "00:00", false, expectedError); testValidateDate(datetimeControl, "2014-99999-01", "00:00", false, expectedError);
testValidateDate(datetimeControl, "2014-01-99999", "00:00", false, expectedError); testValidateDate(datetimeControl, "2014-01-99999", "00:00", false, expectedError);
//invalid month
testValidateDate(datetimeControl, "2014-13-01", "00:00", false, expectedError);
//invalid day
testValidateDate(datetimeControl, "2014-02-30", "00:00", false, expectedError);
}); });
it("validates invalid times", function() { it("validates invalid times", function() {
...@@ -64,6 +68,8 @@ describe("OpenAssessment.DatetimeControl", function() { ...@@ -64,6 +68,8 @@ describe("OpenAssessment.DatetimeControl", function() {
testValidateDate(datetimeControl, "2001-12-31", "00:00", true); testValidateDate(datetimeControl, "2001-12-31", "00:00", true);
testValidateDate(datetimeControl, "2014-04-01", "12:34", true); testValidateDate(datetimeControl, "2014-04-01", "12:34", true);
testValidateDate(datetimeControl, "2014-04-01", "23:59", true); testValidateDate(datetimeControl, "2014-04-01", "23:59", true);
// single character for month and date.
testValidateDate(datetimeControl, "2014-4-1", "23:59", true);
}); });
it("clears validation errors", function() { it("clears validation errors", function() {
......
...@@ -227,16 +227,31 @@ OpenAssessment.DatetimeControl.prototype = { ...@@ -227,16 +227,31 @@ OpenAssessment.DatetimeControl.prototype = {
**/ **/
validate: function() { validate: function() {
var datetimeString = this.datetime(); var dateString = $(this.datePicker, this.element).val();
var matches = datetimeString.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/g); var timeString = $(this.timePicker, this.element).val();
var isValid = (matches !== null);
if (!isValid) { //date validation
var isDateValid = false;
try {
var parsedDate = $.datepicker.parseDate($.datepicker.ISO_8601, dateString);
isDateValid = parsedDate instanceof Date;
} catch (err) {
// parseDate function throws error if date is not in expected format.
// isDateValid flag would remain false.
}
if (!isDateValid) {
$(this.datePicker, this.element).addClass("openassessment_highlighted_field"); $(this.datePicker, this.element).addClass("openassessment_highlighted_field");
}
//time validation
var matches = timeString.match(/^\d{2}:\d{2}$/g);
var isTimeValid = (matches !== null);
if(!isTimeValid) {
$(this.timePicker, this.element).addClass("openassessment_highlighted_field"); $(this.timePicker, this.element).addClass("openassessment_highlighted_field");
} }
return isValid; return (isDateValid && isTimeValid);
}, },
/** /**
......
...@@ -530,15 +530,22 @@ ...@@ -530,15 +530,22 @@
} }
} }
.openassessment_criterion_header_title_box {
float: left;
width: 80%;
display: inline-block;
}
.openassessment_criterion_header_title { .openassessment_criterion_header_title {
text-transform: uppercase; text-transform: uppercase;
width: 50%;
display: inline-block;
float: left;
cursor: default; cursor: default;
padding-top: 2px; padding-top: 2px;
} }
.openassessment_criterion_guide {
@extend %t-small;
}
.openassessment_criterion_header_remove { .openassessment_criterion_header_remove {
@extend .openassessment_rubric_remove_button; @extend .openassessment_rubric_remove_button;
} }
...@@ -1105,26 +1112,6 @@ ...@@ -1105,26 +1112,6 @@
} }
} }
@include media($bp-m) {
@include span-columns(4 of 4);
}
@include media($bp-ds) {
@include span-columns(6 of 6);
}
@include media($bp-dm) {
@include span-columns(12 of 12);
}
@include media($bp-dl) {
@include span-columns(12 of 12);
}
@include media($bp-dx) {
@include span-columns(12 of 12);
}
.step__label, .grade__value { .step__label, .grade__value {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
......
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