diff --git a/common/lib/capa/capa/templates/rubricinput.html b/common/lib/capa/capa/templates/rubricinput.html index 32e7180656..1780603d91 100644 --- a/common/lib/capa/capa/templates/rubricinput.html +++ b/common/lib/capa/capa/templates/rubricinput.html @@ -1,4 +1,10 @@
+

Rubric

+ % if view_only: +

Select the criteria you feel best represents this submission in each category.

+ % else +

The highlighted selection best matches how the student feels you performed in each category.

+ % endif % for i in range(len(categories)): <% category = categories[i] %> @@ -7,7 +13,6 @@ % for j in range(len(category['options'])): <% option = category['options'][j] %>
- % if view_only:
${option['text']} diff --git a/lms/djangoapps/open_ended_grading/staff_grading_service.py b/lms/djangoapps/open_ended_grading/staff_grading_service.py index 5c6cec17eb..b9d263867c 100644 --- a/lms/djangoapps/open_ended_grading/staff_grading_service.py +++ b/lms/djangoapps/open_ended_grading/staff_grading_service.py @@ -17,6 +17,10 @@ from courseware.access import has_access from util.json_request import expect_json from xmodule.course_module import CourseDescriptor from student.models import unique_id_for_user +from xmodule.x_module import ModuleSystem +from mitxmako.shortcuts import render_to_string +from capa import inputtypes +from lxml import etree log = logging.getLogger(__name__) @@ -136,6 +140,8 @@ class StaffGradingService(GradingService): # importing this file doesn't create objects that may not have the right config _service = None +module_system = ModuleSystem("", None, None, render_to_string, None) + def staff_grading_service(): """ Return a staff grading service instance--if settings.MOCK_STAFF_GRADING is True, @@ -252,12 +258,24 @@ def _get_next(course_id, grader_id, location): Implementation of get_next (also called from save_grade) -- returns a json string """ try: - return staff_grading_service().get_next(course_id, location, grader_id) + response = staff_grading_service().get_next(course_id, location, grader_id) + response_json = json.loads(response) + rubric = response_json['rubric'] + rubric_input = inputtypes.RubricInput(module_system, etree.XML(rubric), {'id': location}) + rubric_html = etree.tostring(rubric_input.get_html()) + response_json['rubric'] = rubric_html + return json.dumps(response_json) except GradingServiceError: log.exception("Error from grading service. server url: {0}" .format(staff_grading_service().url)) return json.dumps({'success': False, 'error': 'Could not connect to grading service'}) + # if we can't parse the rubric into HTML, + except etree.XMLSyntaxError: + log.exception("Cannot parse rubric string. Raw string: {0}" + .format(rubric)) + return json.dumps({'success': False, + 'error': 'Error displaying submission'}) @expect_json diff --git a/lms/static/coffee/src/staff_grading/staff_grading.coffee b/lms/static/coffee/src/staff_grading/staff_grading.coffee index 7039fd1358..26d604756a 100644 --- a/lms/static/coffee/src/staff_grading/staff_grading.coffee +++ b/lms/static/coffee/src/staff_grading/staff_grading.coffee @@ -42,14 +42,49 @@ class StaffGradingBackend The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham. ''' rubric: ''' -
    -
  • Metals tend to be good electronic conductors, meaning that they have a large number of electrons which are able to access empty (mobile) energy states within the material.
  • -
  • Sodium has a half-filled s-band, so there are a number of empty states immediately above the highest occupied energy levels within the band.
  • -
  • Magnesium has a full s-band, but the the s-band and p-band overlap in magnesium. Thus are still a large number of available energy states immediately above the s-band highest occupied energy level.
  • -
- -

Please score your response according to how many of the above components you identified:

- ''' + + + + + + + + + + + + + + + + + + +
Purpose + + + + + + + + + + + +
Organization + + + + + + + + + + + +
''' submission_id: @mock_cnt max_score: 2 + @mock_cnt % 3 ml_error_info : 'ML accuracy info: ' + @mock_cnt @@ -166,8 +201,8 @@ class StaffGrading @min_for_ml = 0 @num_graded = 0 @num_pending = 0 + @score_lst = [] - @score = null @problems = null # action handlers @@ -181,31 +216,36 @@ class StaffGrading setup_score_selection: => - # first, get rid of all the old inputs, if any. - @score_selection_container.html('Choose score: ') + @score_selection_container.html(@rubric) + $('.score-selection').click => @graded_callback() - # Now create new labels and inputs for each possible score. - for score in [0..@max_score] - id = 'score-' + score - label = """""" + graded_callback: () => + # check to see whether or not any categories have not been scored + num_categories = $('table.rubric tr').length + for i in [0..(num_categories-1)] + score = $("input[name='score-selection-#{i}']:checked").val() + if score == undefined + return + # show button if we have scores for all categories + @submit_button.show() - input = """ - - """ # " fix broken parsing in emacs - @score_selection_container.append(input + label) - # And now hook up an event handler again - $("input[name='score-selection']").change @graded_callback - set_button_text: (text) => @action_button.attr('value', text) - graded_callback: (event) => - @score = event.target.value - @state = state_graded - @message = '' - @render_view() + # finds the scores for each rubric category + get_score_list: () => + # find the number of categories: + num_categories = $('table.rubric tr').length + + score_lst = [] + # get the score for each one + for i in [0..(num_categories-1)] + score = $("input[name='score-selection-#{i}']:checked").val() + score_lst.append(score) + + return score_lst ajax_callback: (response) => # always clear out errors and messages on transition. @@ -231,7 +271,7 @@ class StaffGrading skip_and_get_next: () => data = - score: @score + rubric_scores: @get_score_list() feedback: @feedback_area.val() submission_id: @submission_id location: @location @@ -244,7 +284,7 @@ class StaffGrading submit_and_get_next: () -> data = - score: @score + rubric_scores: @get_score_list() feedback: @feedback_area.val() submission_id: @submission_id location: @location @@ -261,8 +301,6 @@ class StaffGrading @rubric = response.rubric @submission_id = response.submission_id @feedback_area.val('') - @max_score = response.max_score - @score = null @ml_error_info=response.ml_error_info @prompt_name = response.problem_name @num_graded = response.num_graded @@ -282,8 +320,6 @@ class StaffGrading @ml_error_info = null @submission_id = null @message = message - @score = null - @max_score = 0 @state = state_no_data @@ -361,8 +397,6 @@ class StaffGrading @prompt_container.html(@prompt) @prompt_name_container.html("#{@prompt_name}") @submission_container.html(@make_paragraphs(@submission)) - @rubric_container.html(@rubric) - # no submit button until user picks grade. show_submit_button = false show_action_button = false @@ -397,7 +431,7 @@ class StaffGrading # for now, just create an instance and load it... -mock_backend = false +mock_backend = true ajax_url = $('.staff-grading').data('ajax_url') backend = new StaffGradingBackend(ajax_url, mock_backend) diff --git a/lms/static/sass/course/_staff_grading.scss b/lms/static/sass/course/_staff_grading.scss index 92fa760d4a..edcd16b350 100644 --- a/lms/static/sass/course/_staff_grading.scss +++ b/lms/static/sass/course/_staff_grading.scss @@ -159,5 +159,50 @@ div.peer-grading{ } } padding: 40px; + .rubric { + tr { + margin:10px 0px; + height: 100%; + } + td { + padding: 20px 0px; + margin: 10px 0px; + height: 100%; + } + th { + padding: 5px; + margin: 5px; + } + label, + .view-only { + margin:3px; + position: relative; + padding: 15px; + width: 150px; + height:100%; + display: inline-block; + min-height: 50px; + min-width: 50px; + background-color: #CCC; + font-size: .9em; + } + .grade { + position: absolute; + bottom:0px; + right:0px; + margin:10px; + } + .selected-grade { + background: #666; + color: white; + } + input[type=radio]:checked + label { + background: #666; + color: white; } + input[class='score-selection'] { + display: none; + } + } + } diff --git a/lms/templates/instructor/staff_grading.html b/lms/templates/instructor/staff_grading.html index 085480a332..3749a63e73 100644 --- a/lms/templates/instructor/staff_grading.html +++ b/lms/templates/instructor/staff_grading.html @@ -54,11 +54,6 @@
-
-

Grading Rubric

-
-
-