Commit 86a5d3be by Stephen Sanchez

Merge pull request #480 from edx/sanchez/dynamic-html-modification

Updating the studio mixin to deliver context with initial rendering
parents 318341cb de75db12
{% load i18n %}
{% spaceless %}
<div id="openassessment-editor" class="editor-with-buttons editor-with-tabs">
<div class="openassessment_editor_content_and_tabs">
<div id="openassessment_editor_header">
<h6 id="oa_editor_window_title" class="title modal_window_title" >{% trans "Component: Open Response Problem" %}</h6>
<ul class="editor_modes action_list action_modes editor_tabs">
<li class="view-button oa_editor_tab"><a href="#oa_settings_editor_wrapper">{% trans "Settings" %}</a></li>
<li class="view-button oa_editor_tab"><a href="#oa_rubric_editor_wrapper">{% trans "Rubric" %}</a></li>
<li class="view-button oa_editor_tab"><a href="#oa_prompt_editor_wrapper">{% trans "Prompt" %}</a></li>
</ul>
</div>
<div id = "oa_prompt_editor_wrapper" class="oa_editor_content_wrapper">
<textarea id="openassessment_prompt_editor">{{ prompt }}</textarea>
</div>
{% include "openassessmentblock/edit/oa_edit_rubric.html" %}
<div id="oa_settings_editor_wrapper" class="oa_editor_content_wrapper wrapper-comp-settings">
<ul id="oa_basic_settings_editor" class="list-input settings-list">
<li id="openassessment_title_editor_wrapper" class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_title_editor" class="setting-label">{% trans "Display Name "%}</label>
<input type="text" id="openassessment_title_editor" class="input setting-input" value="{{ title }}">
</div>
<p class="setting-help">{% trans "This name appears when you hover over the unit in the course ribbon at the top of the page." %}</p>
</li>
<li class="openassessment_date_editor field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_submission_start_editor" class="setting-label">{% trans "Response Submission Start Date"%} </label>
<input type="datetime-local" class="input setting-input" id="openassessment_submission_start_editor" value="{{ submission_start }}">
</div>
<p class="setting-help">{% trans "The date at which submissions will first be accepted." %}</p>
</li>
<li class="openassessment_date_editor field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_submission_due_editor" class="setting-label">{% trans "Response Submission Due Date" %}</label>
<input type="datetime-local" class="input setting-input" id="openassessment_submission_due_editor" value="{{ submission_due }}">
</div>
<p class="setting-help">{% trans "The date at which submissions will stop being accepted." %}</p>
</li>
<li id="openassessment_sumbission_image_wrapper" class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_submission_image_editor" class="setting-label">{% trans "Allow Image Submissions"%}</label>
<select id="openassessment_submission_image_editor" class="input setting-input" name="image submission">
<option value="0">{% trans "Disabled"%}</option>
<option value="1">{% trans "Enabled"%}</option>
</select>
</div>
<p class="setting-help">{% trans "If enabled, students will be able to submit an image along with their open response." %}</p>
</li>
</ul>
<p class="openassessment_description" id="openassessment_step_select_description">
{% trans "Select the steps that students must complete. All steps are optional, but every assignment must include at least one step." %}
</p>
{% include "openassessmentblock/edit/oa_edit_training.html" %}
{% include "openassessmentblock/edit/oa_edit_peer.html" %}
{% include "openassessmentblock/edit/oa_edit_self.html" %}
{% include "openassessmentblock/edit/oa_edit_ai.html" %}
</div>
</div>
<div class="openassessment_editor_buttons xblock-actions">
<h3 class="sr">Actions</h3>
<ul>
<li class="action-item">
<a href="#" class="button action-primary openassessment_save_button">{% trans "Save" %}</a>
</li>
<li class="action-item">
<a href="#" class="button openassessment_cancel_button">{% trans "Cancel" %}</a>
</li>
</ul>
</div>
</div>
{% endspaceless %}
{% load i18n %}
{% spaceless %}
<div class="openassessment_assessment_module_settings_editor" id="oa_ai_assessment_editor">
<div class = "openassessment_inclusion_wrapper">
<input id="include_ai_assessment" type="checkbox"
{% if assessments.example_based_assessment %} checked="true" {% endif %}>
<label for="include_ai_assessment">{% trans "Step: Example-Based Assessment" %}</label>
</div>
<div class="openassessment_assessment_module_editor">
{% if not assessments.example_based_assessment %}
<p id="ai_assessment_description_closed" class="openassessment_description_closed">
{% trans "An algorithm assesses students' responses by comparing the responses to pre-assessed sample responses that the instructor provides."%}
</p>
{% endif %}
<div id="ai_assessment_settings_editor" class="assessment_settings_wrapper {% if not assessments.example_based_assessment %} is--hidden {% endif %}">
<p class="openassessment_description">
{% trans "Enter one or more sample responses that you've created, together with the scores you would give those responses. Be sure to format the responses and scores according to the placeholder text below. The algorithm assesses students' responses by comparing them to the sample responses and scores that you provide."%}
</p>
<textarea id="ai_training_examples">{{ assessments.example_based_assessment.examples }}</textarea>
</div>
</div>
</div>
{% endspaceless %}
\ No newline at end of file
{% load i18n %}
{% spaceless %}
<div class="openassessment_assessment_module_settings_editor" id="oa_peer_assessment_editor">
<div class="openassessment_inclusion_wrapper">
<input type="checkbox" id="include_peer_assessment"
{% if assessments.peer_assessment %} checked="true" {% endif %}>
<label for="include_peer_assessment">{% trans "Step: Peer Assessment" %}</label>
</div>
<div class = "openassessment_assessment_module_editor">
{% if not assessments.peer_assessment %}
<p id="peer_assessment_description_closed" class="openassessment_description_closed">
{% trans "Students assess a specified number of other students' responses using the rubric for the assignment." %}
</p>
{% endif %}
<div id="peer_assessment_settings_editor" class="assessment_settings_wrapper {% if not assessments.peer_assessment %} is--hidden {% endif %}">
<p class="openassessment_description">
{% trans "Specify the following values for the peer assessment step. The numeric grading requirements must be given a value." %}
</p>
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_must_grade" class="setting-label">{% trans "Must Grade" %}</label>
<input id="peer_assessment_must_grade" class="input setting-input" type="number" value="{{ assessments.peer_assessment.must_grade }}">
</div>
<p class="setting-help">{% trans "Each student must assess this number of peer responses in order to recieve a grade."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_graded_by" class="setting-label"> {% trans "Graded By" %}</label>
<input id="peer_assessment_graded_by" class="input setting-input" type="number" value="{{ assessments.peer_assessment.must_be_graded_by }}">
</div>
<p class="setting-help">{% trans "Each response must be assessed by at least this many students in order to tabulate a score."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label>
<input id="peer_assessment_start_date" type="datetime-local" class="input setting-input" value="{{ assessments.peer_assessment.start }}">
</div>
<p class="setting-help">{% trans "If desired, specify a start date for the peer assessment period. If no date is specified, peer assessment can begin when submissions begin."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label>
<input id="peer_assessment_due_date" type="datetime-local" class="input setting-input" value="{{ assessments.peer_assessment.due }}">
</div>
<p class="setting-help">{% trans "If desired, specify a due date for the peer assessment period. If no date is specified, peer assessment can run as long as the problem is open."%}</p>
</li>
</ul>
</div>
</div>
</div>
{% endspaceless %}
\ No newline at end of file
{% load i18n %}
{% spaceless %}
<div id="oa_rubric_editor_wrapper" class="oa_editor_content_wrapper">
<div id="openassessment_rubric_instructions">
<p class = openassessment_description>
{% trans "For open response problems, assessment is rubric-based. Rubric criterion have point breakdowns and explanations to help students with peer and self assessment steps. For more information on how to build your rubric, see our online help documentation."%}
</p>
</div>
<ul id="openassessment_criterion_list" >
{% for criterion in criteria %}
{% with criterion_num=forloop.counter %}
<li class="openassessment_criterion is-collapsible" id="openassessment_criterion_1">
<div class="openassessment_criterion_header view-outline" id="openassessment_criterion_header_{{ criterion_num }}">
<a class="action expand-collapse collapse">
<i class="icon-caret-down ui-toggle-expansion"></i>
</a>
<h6 class="openassessment_criterion_header_title">
{% blocktrans %} Criterion {{ criterion_num }}{% endblocktrans %}
</h6>
<div class="openassessment_rubric_remove_button" id="openassessment_criterion_{{ criterion_num }}_remove">
<h2>{% trans "Remove" %}</h2>
</div>
</div>
<div class="openassessment_criterion_body wrapper-comp-settings" id="openassessment_criterion_body_{{ criterion_num }}">
<ul class="list-input settings-list openassessment_criterion_basic_editor">
<li class="field comp-setting-entry">
<div class="wrapper-comp-settings">
<label for="openassessment_criterion_{{ criterion_num }}_name" class="openassessment_criterion_name_label setting-label">
{% trans "Criterion Name"%}
</label>
<input id="openassessment_criterion_{{ criterion_num }}_name" class="openassessment_criterion_name input setting-input" type="text" value={{ criterion.name }}>
</div>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-settings">
<label for="openassessment_criterion_{{ criterion_num }}_prompt" class="openassessment_criterion_prompt_label setting-label">
{% trans "Criterion Prompt"%}
</label>
<textarea id="openassessment_criterion_{{ criterion_num }}_prompt" class="openassessment_criterion_prompt setting-input">{{ criterion.prompt }}</textarea>
</div>
</li>
</ul>
<ul id="openassessment_criterion_{{ criterion_num }}_options" class="openassessment_criterion_option_list">
{% for option in criterion.options %}
{% with option_num=forloop.counter %}
<li id=openassessment_criterion_{{ criterion_num }}_option_{{ option_num }} class="openassessment_criterion_option">
<div class="openassessment_option_header">
<span class="openassessment_option_header_title">
{% blocktrans %} Option {{ option_num }}{% endblocktrans %}
</span>
<div class="openassessment_rubric_remove_button" id="openassessment_criterion_{{ criterion_num }}_option_1_remove">
<h2>{% trans "Remove" %}</h2>
</div>
</div>
<div class="wrapper-comp-settings">
<ul class="list-input settings-list">
<li class="field comp-setting-entry openassessment_criterion_option_name_wrapper">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_{{ criterion_num }}_option_{{ option_num }}_name"
class="openassessment_criterion_option_name_label setting-label">
{% trans "Option Name"%}
</label>
<input id="openassessment_criterion_{{ criterion_num }}_option_{{ option_num }}_name"
class="openassessment_criterion_option_name input input-label"
type="text"
value="{{ option.name }}">
</div>
</li>
<li class="field comp-setting-entry openassessment_criterion_option_point_wrapper">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_{{ criterion_num }}_option_{{ option_num }}_points"
class="openassessment_criterion_option_points_label setting-label">
{% trans "Option Points"%}
</label>
<input id="openassessment_criterion_{{ criterion_num }}_option_{{ option_num }}_points"
class="openassessment_criterion_option_points input setting-input"
type="number"
value="{{ option.points }}">
</div>
</li>
<li class="field comp-setting-entry openassessment_criterion_option_explanation_wrapper">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_{{ criterion_num }}_option_{{ option_num }}_explanation"
class="openassessment_criterion_option_explanation_label setting-label">
{% trans "Option Explanation"%}
</label>
<textarea id="openassessment_criterion_{{ criterion_num }}_option_{{ option_num }}_explanation"
class="openassessment_criterion_option_explanation setting-input">{{ option.explanation }}</textarea>
</div>
</li>
</ul>
</div>
</li>
{% endwith %}
{% endfor %}
</ul>
<div id="openassessment_criterion_{{ criterion_num }}_add_option" class="openassessment_criterion_add_option openassessment_option_header">
<h2>{% trans "Add Another Option"%}</h2>
</div>
<div id="openassessment_criterion_{{ criterion_num }}_feedback_wrapper" class="openassessment_criterion_feedback_wrapper wrapper-comp-settings">
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_{{ criterion_num }}_feedback" class="setting-label">{% trans "Criterion Feeedback" %}</label>
<select id="openassessment_criterion_{{ criterion_num }}_feedback" class="input setting-input">
<option value="disabled">{% trans "Disabled" %}</option>
<option value="optional" {% if criterion.feedbackprompt == "optional" %} selected="true" {% endif %}>{% trans "Optional" %}</option>
<option value="required" {% if criterion.feedbackprompt == "required" %} selected="true" {% endif %}>{% trans "Required" %}</option>
</select>
</div>
<p class="setting-help">
{% trans "Select one of the options above. This describes whether or not the student will have to provide criterion feedback." %}
</p>
</li>
</ul>
</div>
</div>
</li>
{% endwith %}
{% endfor %}
</ul>
<div id="openassessment_rubric_add_criterion">
<h6>
{% trans "Add Another Criterion"%}
</h6>
</div>
<div id="openassessment_rubric_feedback_wrapper" class="wrapper-comp-settings">
<div id="openassessment_rubric_feedback_header_open">
<span>
{% trans "Rubric Feedback" %}
</span>
<div class="openassessment_rubric_remove_button" id="openassessment_rubric_feedback_remove">
<h2>{% trans "Remove" %}</h2>
</div>
<div id="openassessment_rubric_feedback_header_closed">
<h2>
{% trans "Add Rubric Feedback" %}
</h2>
</div>
</div>
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting" id="openassessment_rubric_feedback_input_wrapper">
<label for="openassessment_rubric_feedback" class="setting-label">{% trans "Feedback Direction" %}</label>
<textarea id="openassessment_rubric_feedback" class="input setting-input">{{ feedbackprompt }}</textarea>
</div>
</li>
<p class="setting-help">
{% trans "If you would like your students to be able to provide feedback on the rubric, add a prompt to ask them for it." %}
</p>
</ul>
</div>
</div>
{% endspaceless %}
\ No newline at end of file
{% load i18n %}
{% spaceless %}
<div class="openassessment_assessment_module_settings_editor" id="oa_self_assessment_editor">
<div class = "openassessment_inclusion_wrapper">
<input id="include_self_assessment" type="checkbox"
{% if assessments.self_assessment %} checked="true" {% endif %}>
<label for="include_self_assessment">{% trans "Step: Self Assessment" %}</label>
</div>
<div class="openassessment_assessment_module_editor">
{% if not assessments.self_assessment %}
<p id="self_assessment_description_closed" class="openassessment_description_closed">
{% trans "Students assess their own responses using the rubric for the assignment." %}
</p>
{% endif %}
<div id="self_assessment_settings_editor" class="assessment_settings_wrapper {% if not assessments.self_assessment %} is--hidden {% endif %}">
<p class="openassessment_description">
{% trans "Specify start and due dates for the self assessment step. To allow self assessment to run as long as the assignment is open, leave both fields blank." %}
</p>
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="self_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label>
<input id="self_assessment_start_date" type="datetime-local" class="input setting-input" value="{{ assessments.self_assessment.start }}">
</div>
<p class="setting-help">{% trans "If desired, specify a start date for the self assessment period. If no date is specified, self assessment can begin when submissions begin."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="self_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label>
<input id="self_assessment_due_date" type="datetime-local" class="input setting-input" value="{{ assessments.self_assessment.due }}">
</div>
<p class="setting-help">{% trans "If desired, specify a due date for the self assessment period. If no date is specified, self assessment can run as long as the problem is open."%}</p>
</li>
</ul>
</div>
</div>
</div>
{% endspaceless %}
\ No newline at end of file
{% load i18n %}
{% spaceless %}
<div class="openassessment_assessment_module_settings_editor" id="oa_student_training_editor">
<div class = "openassessment_inclusion_wrapper">
<input type="checkbox" id="include_student_training"
{% if assessments.student_training %} checked="true" {% endif %}>
<label for="include_student_training">{% trans "Step: Student Training" %}</label>
</div>
<div class = "openassessment_assessment_module_editor">
{% if not assessments.student_training %}
<p id="student_training_description_closed" class="openassessment_description_closed">
{% trans "Students learn to assess responses by scoring pre-assessed sample responses that the instructor provides. Students move to the next step when the scores they give match the instructor's scores. Note that Student Training Requires that the Peer Assessment module is also selected." %}
</p>
{% endif %}
<div id="student_training_settings_editor" class="assessment_settings_wrapper {% if not assessments.student_training %} is--hidden {% endif %}">
<p class="openassessment_description">
{% trans "Enter one or more sample responses that you've created, together with the scores you would give those responses. Be sure to format the responses and scores according to the placeholder text below." %}
</p>
<textarea id="student_training_examples">{{ assessments.student_training.examples }}</textarea>
</div>
</div>
</div>
{% endspaceless %}
\ No newline at end of file
{% load i18n %}
<div id="openassessment-editor" class="editor-with-buttons editor-with-tabs">
<div class="openassessment_editor_content_and_tabs">
<div id="openassessment_editor_header">
<h6 id="oa_editor_window_title" class="title modal_window_title" >{% trans "Component: Open Response Problem" %}</h6>
<ul class="editor_modes action_list action_modes editor_tabs">
<li class="view-button oa_editor_tab"><a href="#oa_settings_editor_wrapper">{% trans "Settings" %}</a></li>
<li class="view-button oa_editor_tab"><a href="#oa_rubric_editor_wrapper">{% trans "Rubric" %}</a></li>
<li class="view-button oa_editor_tab"><a href="#oa_prompt_editor_wrapper">{% trans "Prompt" %}</a></li>
</ul>
</div>
<div id = "oa_prompt_editor_wrapper" class="oa_editor_content_wrapper">
<textarea id="openassessment_prompt_editor"></textarea>
</div>
<div id="oa_rubric_editor_wrapper" class="oa_editor_content_wrapper">
<div id="openassessment_rubric_instructions">
<p class = openassessment_description>
{% trans "For open response problems, assessment is rubric-based. Rubric criterion have point breakdowns and explanations to help students with peer and self assessment steps. For more information on how to build your rubric, see our online help documentation."%}
</p>
</div>
<ul id="openassessment_criterion_list" >
<li class="openassessment_criterion is-collapsible" id="openassessment_criterion_1">
<div class="openassessment_criterion_header view-outline" id="openassessment_criterion_header_1">
<a class="action expand-collapse collapse">
<i class="icon-caret-down ui-toggle-expansion"></i>
</a>
<h6 class="openassessment_criterion_header_title">
{% trans "Criterion C-C-C"%}
</h6>
<div class="openassessment_rubric_remove_button" id="openassessment_criterion_1_remove">
<h2>{% trans "Remove" %}</h2>
</div>
</div>
<div class="openassessment_criterion_body wrapper-comp-settings" id="openassessment_criterion_body_1">
<ul class="list-input settings-list openassessment_criterion_basic_editor">
<li class="field comp-setting-entry">
<div class="wrapper-comp-settings">
<label for="openassessment_criterion_1_name" class="openassessment_criterion_name_label setting-label">
{% trans "Criterion Name"%}
</label>
<input id="openassessment_criterion_1_name" class="openassessment_criterion_name input setting-input" type="text">
</div>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-settings">
<label for="openassessment_criterion_1_prompt" class="openassessment_criterion_prompt_label setting-label">
{% trans "Criterion Prompt"%}
</label>
<textarea id="openassessment_criterion_1_prompt" class="openassessment_criterion_prompt setting-input"></textarea>
</div>
</li>
</ul>
<ul id="openassessment_criterion_1_options" class="openassessment_criterion_option_list">
<li id=openassessment_criterion_1_option_1 class="openassessment_criterion_option">
<div class="openassessment_option_header">
<span class="openassessment_option_header_title">
{% trans "Option O-O-O" %}
</span>
<div class="openassessment_rubric_remove_button" id="openassessment_criterion_1_option_1_remove">
<h2>{% trans "Remove" %}</h2>
</div>
</div>
<div class="wrapper-comp-settings">
<ul class="list-input settings-list">
<li class="field comp-setting-entry openassessment_criterion_option_name_wrapper">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_1_option_1_name" class="openassessment_criterion_option_name_label setting-label">
{% trans "Option Name"%}
</label>
<input id="openassessment_criterion_1_option_1_name" class="openassessment_criterion_option_name input input-label" type="text">
</div>
</li>
<li class="field comp-setting-entry openassessment_criterion_option_point_wrapper">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_1_option_1_points" class="openassessment_criterion_option_points_label setting-label">
{% trans "Option Points"%}
</label>
<input id="openassessment_criterion_1_option_1_points" class="openassessment_criterion_option_points input setting-input" type="number">
</div>
</li>
<li class="field comp-setting-entry openassessment_criterion_option_explanation_wrapper">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_1_option_1_explanation" class="openassessment_criterion_option_explanation_label setting-label">
{% trans "Option Explanation"%}
</label>
<textarea id="openassessment_criterion_1_option_1_explanation" class="openassessment_criterion_option_explanation setting-input"></textarea>
</div>
</li>
</ul>
</div>
</li>
</ul>
<div id="openassessment_criterion_1_add_option" class="openassessment_criterion_add_option openassessment_option_header">
<h2>{% trans "Add Another Option"%}</h2>
</div>
<div id="openassessment_criterion_1_feedback_wrapper" class="openassessment_criterion_feedback_wrapper wrapper-comp-settings">
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_criterion_1_feedback" class="setting-label">{% trans "Criterion Feeedback" %}</label>
<select id="openassessment_criterion_1_feedback" class="input setting-input">
<option value="disabled">{% trans "Disabled" %}</option>
<option value="optional">{% trans "Optional" %}</option>
<option value="required">{% trans "Required" %}</option>
</select>
</div>
<p class="setting-help">
{% trans "Select one of the options above. This describes whether or not the student will have to provide criterion feedback." %}
</p>
</li>
</ul>
</div>
</div>
</li>
</ul>
<div id="openassessment_rubric_add_criterion">
<h6>
{% trans "Add Another Criterion"%}
</h6>
</div>
<div id="openassessment_rubric_feedback_wrapper" class="wrapper-comp-settings">
<div id="openassessment_rubric_feedback_header">
<span>
{% trans "Rubric Feedback" %}
</span>
</div>
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting" id="openassessment_rubric_feedback_input_wrapper">
<label for="openassessment_rubric_feedback" class="setting-label">{% trans "Feedback Direction" %}</label>
<textarea id="openassessment_rubric_feedback" class="input setting-input"></textarea>
</div>
</li>
<p class="setting-help">
{% trans "Directions shown to students when they give feedback." %}
</p>
</ul>
</div>
</div>
<div id="oa_settings_editor_wrapper" class="oa_editor_content_wrapper wrapper-comp-settings">
<ul id="oa_basic_settings_editor" class="list-input settings-list">
<li id="openassessment_title_editor_wrapper" class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_title_editor" class="setting-label">{% trans "Display Name "%}</label>
<input type="text" id="openassessment_title_editor" class="input setting-input">
</div>
<p class="setting-help">{% trans "This name appears when you hover over the unit in the course ribbon at the top of the page." %}</p>
</li>
<li class="openassessment_date_editor field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_submission_start_editor" class="setting-label">{% trans "Response Submission Start Date"%} </label>
<input type="text" class="input setting-input" id="openassessment_submission_start_editor">
</div>
<p class="setting-help">{% trans "The date at which submissions will first be accepted." %}</p>
</li>
<li class="openassessment_date_editor field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_submission_due_editor" class="setting-label">{% trans "Response Submission Due Date" %}</label>
<input type="text" class="input setting-input" id="openassessment_submission_due_editor">
</div>
<p class="setting-help">{% trans "The date at which submissions will stop being accepted." %}</p>
</li>
<li id="openassessment_sumbission_image_wrapper" class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_submission_image_editor" class="setting-label">{% trans "Allow Image Submissions"%}</label>
<select id="openassessment_submission_image_editor" class = "input setting-input" name="image submission">
<option value="0">{% trans "Disabled"%}</option>
<option value="1">{% trans "Enabled"%}</option>
</select>
</div>
<p class="setting-help">{% trans "If enabled, students will be able to submit an image along with their open response." %}</p>
</li>
</ul>
<p class="openassessment_description" id="openassessment_step_select_description">
{% trans "Select the steps that students must complete. All steps are optional, but every assignment must include at least one step." %}
</p>
<div class="openassessment_assessment_module_settings_editor" id="oa_student_training_editor">
<div class = "openassessment_inclusion_wrapper">
<input type="checkbox" id="include_student_training">
<label for="include_student_training">{% trans "Step: Student Training" %}</label>
</div>
<div class = "openassessment_assessment_module_editor">
<p id="student_training_description_closed" class="openassessment_description_closed">
{% trans "Students learn to assess responses by scoring pre-assessed sample responses that the instructor provides. Students move to the next step when the scores they give match the instructor's scores. Note that Student Training Requires that the Peer Assessment module is also selected." %}
</p>
<div id="student_training_settings_editor" class="assessment_settings_wrapper">
<p class="openassessment_description">
{% trans "Enter one or more sample responses that you've created, together with the scores you would give those responses. Be sure to format the responses and scores according to the placeholder text below." %}
</p>
<textarea id="student_training_examples"></textarea>
</div>
</div>
</div>
<div class="openassessment_assessment_module_settings_editor" id="oa_peer_assessment_editor">
<div class="openassessment_inclusion_wrapper">
<input type="checkbox" id="include_peer_assessment">
<label for="include_peer_assessment">{% trans "Step: Peer Assessment" %}</label>
</div>
<div class = "openassessment_assessment_module_editor">
<p id="peer_assessment_description_closed" class="openassessment_description_closed">
{% trans "Students assess a specified number of other students' responses using the rubric for the assignment." %}
</p>
<div id="peer_assessment_settings_editor" class="assessment_settings_wrapper">
<p class="openassessment_description">
{% trans "Specify the following values for the peer assessment step. The numeric grading requirements must be given a value." %}
</p>
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_must_grade" class="setting-label">{% trans "Must Grade" %}</label>
<input id="peer_assessment_must_grade" class="input setting-input" type="number">
</div>
<p class="setting-help">{% trans "Each student must assess this number of peer responses in order to recieve a grade."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_graded_by" class="setting-label"> {% trans "Graded By" %}</label>
<input id="peer_assessment_graded_by" class="input setting-input" type="number">
</div>
<p class="setting-help">{% trans "Each response must be assessed by at least this many students in order to tabulate a score."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label>
<input id="peer_assessment_start_date" type="text" class="input setting-input">
</div>
<p class="setting-help">{% trans "If desired, specify a start date for the peer assessment period. If no date is specified, peer assessment can begin when submissions begin."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="peer_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label>
<input id="peer_assessment_due_date" type="text" class="input setting-input">
</div>
<p class="setting-help">{% trans "If desired, specify a due date for the peer assessment period. If no date is specified, peer assessment can run as long as the problem is open."%}</p>
</li>
</ul>
</div>
</div>
</div>
<div class="openassessment_assessment_module_settings_editor" id="oa_self_assessment_editor">
<div class = "openassessment_inclusion_wrapper">
<input id="include_self_assessment" type="checkbox">
<label for="include_self_assessment">{% trans "Step: Self Assessment" %}</label>
</div>
<div class="openassessment_assessment_module_editor">
<p id="self_assessment_description_closed" class="openassessment_description_closed">
{% trans "Students assess their own responses using the rubric for the assignment." %}
</p>
<div id="self_assessment_settings_editor" class="assessment_settings_wrapper">
<p class="openassessment_description">
{% trans "Specify start and due dates for the self assessment step. To allow self assessment to run as long as the assignment is open, leave both fields blank." %}
</p>
<ul class="list-input settings-list">
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="self_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label>
<input id="self_assessment_start_date" type="text" class="input setting-input">
</div>
<p class="setting-help">{% trans "If desired, specify a start date for the self assessment period. If no date is specified, self assessment can begin when submissions begin."%}</p>
</li>
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="self_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label>
<input id="self_assessment_due_date" type="text" class="input setting-input">
</div>
<p class="setting-help">{% trans "If desired, specify a due date for the self assessment period. If no date is specified, self assessment can run as long as the problem is open."%}</p>
</li>
</ul>
</div>
</div>
</div>
<div class="openassessment_assessment_module_settings_editor" id="oa_ai_assessment_editor">
<div class = "openassessment_inclusion_wrapper">
<input id="include_ai_assessment" type="checkbox">
<label for="include_ai_assessment">{% trans "Step: Example-Based Assessment" %}</label>
</div>
<div class="openassessment_assessment_module_editor">
<p id="ai_assessment_description_closed" class="openassessment_description_closed">
{% trans "An algorithm assesses students' responses by comparing the responses to pre-assessed sample responses that the instructor provides."%}
</p>
<div id="ai_assessment_settings_editor" class="assessment_settings_wrapper">
<p class="openassessment_description">
{% trans "Enter one or more sample responses that you've created, together with the scores you would give those responses. Be sure to format the responses and scores according to the placeholder text below. The algorithm assesses students' responses by comparing them to the sample responses and scores that you provide."%}
</p>
<textarea id="ai_training_examples"></textarea>
</div>
</div>
</div>
</div>
</div>
<div class="openassessment_editor_buttons xblock-actions">
<h3 class="sr">Actions</h3>
<ul>
<li class="action-item">
<a href="#" class="button action-primary openassessment_save_button">{% trans "Save" %}</a>
</li>
<li class="action-item">
<a href="#" class="button openassessment_cancel_button">{% trans "Cancel" %}</a>
</li>
</ul>
</div>
</div>
...@@ -379,8 +379,66 @@ ...@@ -379,8 +379,66 @@
"output": "oa_grade_complete.html" "output": "oa_grade_complete.html"
}, },
{ {
"template": "openassessmentblock/oa_edit.html", "template": "openassessmentblock/edit/oa_edit.html",
"context": {}, "context": {
"prompt": "How much do you like waffles?",
"title": "The most important of all questions.",
"submission_due": "2014-10-1T10:00:00",
"criteria": [
{
"name": "Criterion 1",
"prompt": "Prompt 1",
"order_num": 0,
"feedback": "optional",
"options": [
{
"order_num": 2,
"points": 2,
"name": "Good"
}
],
"points_possible": 2
},
{
"name": "Criterion 2",
"prompt": "Prompt 2",
"order_num": 1,
"options": [
{
"order_num": 1,
"points": 1,
"name": "Fair"
}
],
"points_possible": 2
},
{
"name": "Criterion 3",
"prompt": "Prompt 3",
"order_num": 2,
"feedback": "optional",
"options": [
{
"order_num": 2,
"points": 2,
"name": "Good"
}
],
"points_possible": 2
}
],
"assessments": {
"peer_assessment": {
"start": "2014-10-04T00:00:00",
"must_grade": 5,
"must_be_graded_by": 3
},
"self_assessment": {
"due": ""
}
}
},
"output": "oa_edit.html" "output": "oa_edit.html"
}, },
{ {
......
if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this);this.trainingView=new OpenAssessment.StudentTrainingView(this.element,this.server,this);this.selfView=new OpenAssessment.SelfView(this.element,this.server,this);this.peerView=new OpenAssessment.PeerView(this.element,this.server,this);this.gradeView=new OpenAssessment.GradeView(this.element,this.server,this);this.messageView=new OpenAssessment.MessageView(this.element,this.server,this);this.staffInfoView=new OpenAssessment.StaffInfoView(this.element,this.server,this)};OpenAssessment.BaseView.prototype={scrollToTop:function(){if($.scrollTo instanceof Function){$(window).scrollTo($("#openassessment__steps"),800,{offset:-50})}},setUpCollapseExpand:function(parentSel,onExpand){parentSel.find(".ui-toggle-visibility__control").click(function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");if(sel.hasClass("is--collapsed")&&onExpand!==undefined){onExpand()}sel.toggleClass("is--collapsed")})},load:function(){this.responseView.load();this.loadAssessmentModules();this.staffInfoView.load()},loadAssessmentModules:function(){this.trainingView.load();this.peerView.load();this.selfView.load();this.gradeView.load()},loadMessageView:function(){this.messageView.load()},toggleActionError:function(type,msg){var element=this.element;var container=null;if(type=="save"){container=".response__submission__actions"}else if(type=="submit"||type=="peer"||type=="self"||type=="student-training"){container=".step__actions"}else if(type=="feedback_assess"){container=".submission__feedback__actions"}if(container===null){if(msg!==null){console.log(msg)}}else{var msgHtml=msg===null?"":msg;$(container+" .message__content",element).html("<p>"+msgHtml+"</p>");$(container,element).toggleClass("has--error",msg!==null)}},showLoadError:function(step){var container="#openassessment__"+step;$(container).toggleClass("has--error",true);$(container+" .step__status__value i").removeClass().addClass("ico icon-warning-sign");$(container+" .step__status__value .copy").html(gettext("Unable to Load"))}};function OpenAssessmentBlock(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.BaseView(runtime,element,server);view.load()}OpenAssessment.StudioView=function(runtime,element,server){this.runtime=runtime;this.server=server;this.liveElement=$(element);var liveElement=this.liveElement;this.settingsFieldSelectors={promptBox:$("#openassessment_prompt_editor",liveElement),titleField:$("#openassessment_title_editor",liveElement),submissionStartField:$("#openassessment_submission_start_editor",liveElement),submissionDueField:$("#openassessment_submission_due_editor",liveElement),hasPeer:$("#include_peer_assessment",liveElement),hasSelf:$("#include_self_assessment",liveElement),hasAI:$("#include_ai_assessment",liveElement),hasTraining:$("#include_student_training",liveElement),peerMustGrade:$("#peer_assessment_must_grade",liveElement),peerGradedBy:$("#peer_assessment_graded_by",liveElement),peerStart:$("#peer_assessment_start_date",liveElement),peerDue:$("#peer_assessment_due_date",liveElement),selfStart:$("#self_assessment_start_date",liveElement),selfDue:$("#self_assessment_due_date",liveElement)};this.aiTrainingExamplesCodeBox=CodeMirror.fromTextArea($("#ai_training_examples",liveElement).first().get(0),{mode:"xml",lineNumbers:true,lineWrapping:true});this.studentTrainingExamplesCodeBox=CodeMirror.fromTextArea($("#student_training_examples",liveElement).first().get(0),{mode:"xml",lineNumbers:true,lineWrapping:true});var criterionHtml=$("#openassessment_criterion_1",liveElement).parent().html();this.criterionHtmlTemplate=criterionHtml.replace(new RegExp("1","g"),"C-C-C");var optionHtml=$("#openassessment_criterion_1_option_1",liveElement).parent().html();var criteriaReplaced=optionHtml.replace(new RegExp("criterion_1","g"),"criterion_C-C-C");this.optionHtmlTemplate=criteriaReplaced.replace(new RegExp("option_1","g"),"option_O-O-O");this.numberOfCriteria=0;this.numberOfOptions=[];this.rubricCriteriaSelectors=[];this.rubricFeedbackPrompt=$("#openassessment_rubric_feedback",liveElement);$("#openassessment_criterion_list",liveElement).empty();this.addNewCriterionToRubric();var view=this;$(".openassessment_save_button",liveElement).click(function(eventData){view.save()});$(".openassessment_cancel_button",liveElement).click(function(eventData){view.cancel()});$(".openassessment_editor_content_and_tabs",liveElement).tabs();view.addSettingsAssessmentCheckboxListener("ai_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("self_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("peer_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("student_training",liveElement);$("#openassessment_rubric_add_criterion",liveElement).click(function(eventData){view.addNewCriterionToRubric(liveElement)})};OpenAssessment.StudioView.prototype={load:function(){var view=this;this.server.loadEditorContext().done(function(prompt,rubric,title,subStart,subDue,assessments){view.settingsFieldSelectors.submissionStartField.prop("value",subStart);view.settingsFieldSelectors.submissionDueField.prop("value",subDue);view.settingsFieldSelectors.promptBox.prop("value",prompt);view.settingsFieldSelectors.titleField.prop("value",title);view.settingsFieldSelectors.hasTraining.prop("checked",false).change();view.settingsFieldSelectors.hasPeer.prop("checked",false).change();view.settingsFieldSelectors.hasSelf.prop("checked",false).change();view.settingsFieldSelectors.hasAI.prop("checked",false).change();for(var i=0;i<assessments.length;i++){var assessment=assessments[i];if(assessment.name=="peer-assessment"){view.settingsFieldSelectors.peerMustGrade.prop("value",assessment.must_grade);view.settingsFieldSelectors.peerGradedBy.prop("value",assessment.must_be_graded_by);view.settingsFieldSelectors.peerStart.prop("value",assessment.start);view.settingsFieldSelectors.peerDue.prop("value",assessment.due);view.settingsFieldSelectors.hasPeer.prop("checked",true).change()}else if(assessment.name=="self-assessment"){view.settingsFieldSelectors.selfStart.prop("value",assessment.start);view.settingsFieldSelectors.selfDue.prop("value",assessment.due);view.settingsFieldSelectors.hasSelf.prop("checked",true).change()}else if(assessment.name=="example-based-assessment"){view.settingsFieldSelectors.aiTrainingExamplesCodeBox.setValue(assessment.examples);view.settingsFieldSelectors.hasAI.prop("checked",true).change()}else if(assessment.name=="student-training"){view.studentTrainingExamplesCodeBox.setValue(assessment.examples);view.settingsFieldSelectors.hasTraining.prop("checked",true).change()}}while(view.numberOfCriteria<rubric.criteria.length){view.addNewCriterionToRubric()}while(view.numberOfCriteria>rubric.criteria.length){view.removeCriterionFromRubric(1)}for(i=0;i<rubric.criteria.length;i++){while(view.numberOfOptions[i+1]<rubric.criteria[i].options.length){view.addNewOptionToCriterion(view.liveElement,i+1)}while(view.numberOfOptions[i+1]>rubric.criteria[i].options.length){view.removeOptionFromCriterion(view.liveElement,i+1,1)}}for(i=0;i<rubric.criteria.length;i++){var criterion=rubric.criteria[i];var selectors=view.rubricCriteriaSelectors[i+1];selectors.name.prop("value",criterion.name);selectors.prompt.prop("value",criterion.prompt);selectors.feedback=criterion.feedback;for(var j=0;j<criterion.options.length;j++){var option=criterion.options[j];var optionSelectors=selectors.options[j+1];optionSelectors.name.prop("value",option.name);optionSelectors.points.prop("value",option.points);optionSelectors.explanation.prop("value",option.explanation)}}if(rubric.feedbackprompt){view.rubricFeedbackPrompt.prop("value",rubric.feedbackprompt);view.hasRubricFeedbackPrompt=true}else{view.rubricFeedbackPrompt.prop("value","");view.hasRubricFeedbackPrompt=false}}).fail(function(msg){view.showError(msg)})},save:function(){var view=this;this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})},addSettingsAssessmentCheckboxListener:function(name,liveElement){$("#include_"+name,liveElement).change(function(){if(this.checked){$("#"+name+"_description_closed",liveElement).fadeOut("fast");$("#"+name+"_settings_editor",liveElement).fadeIn()}else{$("#"+name+"_settings_editor",liveElement).fadeOut("fast");$("#"+name+"_description_closed",liveElement).fadeIn()}})},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},addNewCriterionToRubric:function(){var view=this;var liveElement=this.liveElement;var newCriterionID=this.numberOfCriteria+1;this.numberOfCriteria+=1;this.numberOfOptions[newCriterionID]=0;var criterionHtml=this.criterionHtmlTemplate.replace(new RegExp("C-C-C","g"),""+newCriterionID);$("#openassessment_criterion_list",liveElement).append(criterionHtml);liveElement=$("#openassessment_criterion_"+newCriterionID);$(".openassessment_criterion_option_list",liveElement).empty();view.rubricCriteriaSelectors[newCriterionID]={criterion:liveElement,name:$(".openassessment_criterion_name",liveElement).first(),prompt:$(".openassessment_criterion_prompt",liveElement).first(),options:[],feedback:"disabled"};$("input:radio[value=disabled]",liveElement).prop("checked",true);view.addNewOptionToCriterion(liveElement,newCriterionID);$("#openassessment_display_criterion_"+newCriterionID,liveElement).change(function(){if(this.checked){$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeIn()}else{$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeOut()}});$("#openassessment_criterion_"+newCriterionID+"_remove",liveElement).click(function(eventData){view.removeCriterionFromRubric(newCriterionID)});$("#openassessment_criterion_"+newCriterionID+"_add_option",liveElement).click(function(eventData){view.addNewOptionToCriterion(liveElement,newCriterionID)});$(".openassessment_feedback_remove_button",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_open",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeIn();$(".openassessment_feedback_remove_button",liveElement).fadeOut();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=false});$(".openassessment_criterion_feedback_header_closed",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_open",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeOut();$(".openassessment_feedback_remove_button",liveElement).fadeIn();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=true});$(".openassessment_criterion_feedback_header_closed",liveElement).hide()},removeCriterionFromRubric:function(criterionToRemove){var view=this;var numCriteria=view.numberOfCriteria;var selectors=view.rubricCriteriaSelectors;for(var i=criterionToRemove;i<numCriteria;i++){selectors[i].name.prop("value",selectors[i+1].name.prop("value"));selectors[i].prompt.prop("value",selectors[i+1].prompt.prop("value"));selectors[i].feedback=selectors[i+1].feedback;$('input:radio[value="disabled"]',selectors[i].criterion).prop("checked",true);while(view.numberOfOptions[i]<view.numberOfOptions[i+1]){view.addNewOptionToCriterion(selectors[i].criteria,i)}while(view.numberOfOptions[i]>view.numberOfOptions[i+1]){view.removeOptionFromCriterion(selectors[i].criteria,i,1)}var options1=selectors[i].options;var options2=selectors[i+1].options;var numOptions2=view.numberOfOptions[i+1];for(var j=1;j<numOptions2;j++){options1[j].points.prop("value",options2[j].points.prop("value"));options1[j].name.prop("value",options2[j].name.prop("value"));options1[j].explanation.prop("value",options2[j].explanation.prop("value"))}}view.rubricCriteriaSelectors[view.rubricCriteriaSelectors.length-1].criterion.remove();view.rubricCriteriaSelectors=view.rubricCriteriaSelectors.slice(0,numCriteria);view.numberOfOptions=view.numberOfOptions.slice(0,numCriteria);view.numberOfCriteria-=1},addNewOptionToCriterion:function(liveElement,criterionID){var view=this;var newOptionID=this.numberOfOptions[criterionID]+1;this.numberOfOptions[criterionID]+=1;var optionHtml=this.optionHtmlTemplate;optionHtml=optionHtml.replace(new RegExp("C-C-C","g"),""+criterionID);optionHtml=optionHtml.replace(new RegExp("O-O-O","g"),""+newOptionID);$("#openassessment_criterion_"+criterionID+"_options",liveElement).append(optionHtml);liveElement=$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID);view.rubricCriteriaSelectors[criterionID].options[newOptionID]={option:liveElement,points:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_points",liveElement),name:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_name",liveElement),explanation:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_explanation",liveElement)};$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_remove",liveElement).click(function(eventData){view.removeOptionFromCriterion(liveElement,criterionID,newOptionID)})},removeOptionFromCriterion:function(liveElement,criterionID,optionToRemove){var view=this;var numberOfOptions=view.numberOfOptions[criterionID];var optionSelectors=view.rubricCriteriaSelectors[criterionID].options;for(var i=optionToRemove;i<numberOfOptions;i++){optionSelectors[i].points.prop("value",optionSelectors[i+1].points.prop("value"));optionSelectors[i].name.prop("value",optionSelectors[i+1].name.prop("value"));optionSelectors[i].explanation.prop("value",optionSelectors[i+1].explanation.prop("value"))}optionSelectors[optionSelectors.length-1].option.remove();view.rubricCriteriaSelectors[criterionID].options=view.rubricCriteriaSelectors[criterionID].options.slice(0,optionSelectors.length-1);view.numberOfOptions[criterionID]-=1},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var rubricCriteria=[];for(var i=1;i<=this.numberOfCriteria;i++){var selectorDict=this.rubricCriteriaSelectors[i];var criterionValueDict={order_num:i-1,name:selectorDict.name.prop("value"),prompt:selectorDict.prompt.prop("value"),feedback:$("#openassessment_criterion_"+i+"_feedback").val()};var optionSelectorList=selectorDict.options;var optionValueList=[];for(var j=1;j<=this.numberOfOptions[i];j++){var optionSelectors=optionSelectorList[j];optionValueList=optionValueList.concat([{order_num:j-1,points:this._getInt(optionSelectors.points),name:optionSelectors.name.val(),explanation:optionSelectors.explanation.val()}])}criterionValueDict.options=optionValueList;rubricCriteria=rubricCriteria.concat([criterionValueDict])}var assessments=[];if(this.settingsFieldSelectors.hasTraining.prop("checked")){assessments.push({name:"student-training",examples:this.studentTrainingExamplesCodeBox.getValue()})}if(this.settingsFieldSelectors.hasPeer.prop("checked")){assessments.push({name:"peer-assessment",must_grade:this._getInt(this.settingsFieldSelectors.peerMustGrade),must_be_graded_by:this._getInt(this.settingsFieldSelectors.peerGradedBy),start:this._getDateTime(this.settingsFieldSelectors.peerStart),due:this._getDateTime(this.settingsFieldSelectors.peerDue)})}if(this.settingsFieldSelectors.hasSelf.prop("checked")){assessments.push({name:"self-assessment",start:this._getDateTime(this.settingsFieldSelectors.selfStart),due:this._getDateTime(this.settingsFieldSelectors.selfDue)})}if(this.settingsFieldSelectors.hasAI.prop("checked")){assessments.push({name:"example-based-assessment",examples:this.aiTrainingExamplesCodeBox.getValue()})}var view=this;this.server.updateEditorContext({title:this.settingsFieldSelectors.titleField.val(),prompt:this.settingsFieldSelectors.promptBox.val(),feedbackPrompt:this.rubricFeedbackPrompt.val(),submissionStart:this._getDateTime(this.settingsFieldSelectors.submissionStartField),submissionDue:this._getDateTime(this.settingsFieldSelectors.submissionDueField),criteria:rubricCriteria,assessments:assessments}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})},_getDateTime:function(selector){var dateStr=selector.val();if(dateStr===""){return null}debugger;var timestamp=Date.parse(dateStr);if(isNaN(timestamp)){return null}return new Date(timestamp).toISOString()},_getInt:function(selector){return parseInt(selector.val(),10)}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server);view.load()}OpenAssessment.GradeView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.GradeView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("grade").done(function(html){$("#openassessment__grade",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){baseView.showLoadError("grade",errMsg)})},installHandlers:function(){var sel=$("#openassessment__grade",this.element);this.baseView.setUpCollapseExpand(sel);var view=this;sel.find("#feedback__submit").click(function(eventObject){eventObject.preventDefault();view.submitFeedbackOnAssessment()})},feedbackText:function(text){if(typeof text==="undefined"){return $("#feedback__remarks__value",this.element).val()}else{$("#feedback__remarks__value",this.element).val(text)}},feedbackOptions:function(options){var view=this;if(typeof options==="undefined"){return $.map($(".feedback__overall__value:checked",view.element),function(element,index){return $(element).val()})}else{$(".feedback__overall__value",this.element).prop("checked",false);$.each(options,function(index,opt){$("#feedback__overall__value--"+opt,view.element).prop("checked",true)})}},setHidden:function(sel,hidden){sel.toggleClass("is--hidden",hidden);sel.attr("aria-hidden",hidden?"true":"false")},isHidden:function(sel){return sel.hasClass("is--hidden")&&sel.attr("aria-hidden")=="true"},feedbackState:function(newState){var containerSel=$(".submission__feedback__content",this.element);var instructionsSel=containerSel.find(".submission__feedback__instructions");var fieldsSel=containerSel.find(".submission__feedback__fields");var actionsSel=containerSel.find(".submission__feedback__actions");var transitionSel=containerSel.find(".transition__status");var messageSel=containerSel.find(".message--complete");if(typeof newState==="undefined"){var isSubmitting=containerSel.hasClass("is--transitioning")&&containerSel.hasClass("is--submitting")&&!this.isHidden(transitionSel)&&this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var hasSubmitted=containerSel.hasClass("is--submitted")&&this.isHidden(transitionSel)&&!this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var isOpen=!containerSel.hasClass("is--submitted")&&!containerSel.hasClass("is--transitioning")&&!containerSel.hasClass("is--submitting")&&this.isHidden(transitionSel)&&this.isHidden(messageSel)&&!this.isHidden(instructionsSel)&&!this.isHidden(fieldsSel)&&!this.isHidden(actionsSel);if(isOpen){return"open"}else if(isSubmitting){return"submitting"}else if(hasSubmitted){return"submitted"}else{throw"Invalid feedback state"}}else{if(newState=="open"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,false);this.setHidden(fieldsSel,false);this.setHidden(actionsSel,false);this.setHidden(transitionSel,true);this.setHidden(messageSel,true)}else if(newState=="submitting"){containerSel.toggleClass("is--transitioning",true);containerSel.toggleClass("is--submitting",true);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,false);this.setHidden(messageSel,true)}else if(newState=="submitted"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",true);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,true);this.setHidden(messageSel,false)}}},submitFeedbackOnAssessment:function(){var view=this;var baseView=this.baseView;$("#feedback__submit",this.element).toggleClass("is--disabled",true);view.feedbackState("submitting");this.server.submitFeedbackOnAssessment(this.feedbackText(),this.feedbackOptions()).done(function(){view.feedbackState("submitted")}).fail(function(errMsg){baseView.toggleActionError("feedback_assess",errMsg)})}};OpenAssessment.MessageView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.MessageView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("message").done(function(html){$("#openassessment__message",view.element).replaceWith(html)}).fail(function(errMsg){baseView.showLoadError("message",errMsg)})}};OpenAssessment.PeerView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.PeerView.prototype={load:function(){var view=this;this.server.render("peer_assessment").done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")})},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel,$.proxy(view.loadContinuedAssessment,view));var rubricSelector=$("#peer-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(view.peerSubmitEnabled,view))}sel.find("#peer-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();if(!isContinuedAssessment){view.peerAssess()}else{view.continuedPeerAssess()}})},peerSubmitEnabled:function(enabled){var button=$("#peer-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},peerAssess:function(){var view=this;var baseView=view.baseView;this.peerAssessRequest(function(){view.load();baseView.loadAssessmentModules();baseView.scrollToTop()})},continuedPeerAssess:function(){var view=this;var gradeView=this.baseView.gradeView;var baseView=view.baseView;view.peerAssessRequest(function(){view.loadContinuedAssessment();gradeView.load();baseView.scrollToTop()})},peerAssessRequest:function(successFunction){var view=this;view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.overallFeedback()).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})},overallFeedback:function(overallFeedback){var selector="#assessment__rubric__question--feedback__value";if(typeof overallFeedback==="undefined"){return $(selector,this.element).val()}else{$(selector,this.element).val(overallFeedback)}}};OpenAssessment.ResponseView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.savedResponse="";this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.installHandlers();view.setAutoSaveEnabled(true)}).fail(function(errMsg){view.baseView.showLoadError("response")})},installHandlers:function(){var sel=$("#openassessment__response",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);this.savedResponse=this.response();var handleChange=function(eventData){view.handleResponseChanged()};sel.find("#submission__answer__value").on("change keyup drop paste",handleChange);sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()})},setAutoSaveEnabled:function(enabled){if(enabled){if(this.autoSaveTimerId===null){this.autoSaveTimerId=setInterval($.proxy(this.autoSave,this),this.AUTO_SAVE_POLL_INTERVAL)}}else{if(this.autoSaveTimerId!==null){clearInterval(this.autoSaveTimerId)}}},submitEnabled:function(enabled){var sel=$("#step--response__submit",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveEnabled:function(enabled){var sel=$("#submission__save",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveStatus:function(msg){var sel=$("#response__save_status h3",this.element);if(typeof msg==="undefined"){return sel.text()}else{var label=gettext("Status of Your Response");sel.html('<span class="sr">'+label+":"+"</span>\n"+msg)}},unsavedWarningEnabled:function(enabled){if(typeof enabled==="undefined"){return window.onbeforeunload!==null}else{if(enabled){window.onbeforeunload=function(){return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.")}}else{window.onbeforeunload=null}}},response:function(text){var sel=$("#submission__answer__value",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},responseChanged:function(){var currentResponse=$.trim(this.response());var savedResponse=$.trim(this.savedResponse);return savedResponse!==currentResponse},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isBlank=$.trim(this.response())!=="";this.submitEnabled(isBlank);if(this.responseChanged()){this.saveEnabled(isBlank);this.saveStatus(gettext("This response has not been saved."));this.unsavedWarningEnabled(true)}this.lastChangeTime=Date.now()},save:function(){this.errorOnLastSave=false;this.saveStatus(gettext("Saving..."));this.baseView.toggleActionError("save",null);this.unsavedWarningEnabled(false);var view=this;var savedResponse=this.response();this.server.save(savedResponse).done(function(){view.savedResponse=savedResponse;var currentResponse=view.response();view.submitEnabled(currentResponse!=="");if(currentResponse==savedResponse){view.saveEnabled(false);view.saveStatus(gettext("This response has been saved but not submitted."))}}).fail(function(errMsg){view.saveStatus(gettext("Error"));view.baseView.toggleActionError("save",errMsg);view.errorOnLastSave=true})},submit:function(){this.submitEnabled(false);var view=this;var baseView=this.baseView;this.confirmSubmission().pipe(function(){var submission=$("#submission__answer__value",view.element).val();baseView.toggleActionError("response",null);return view.server.submit(submission)}).done($.proxy(view.moveToNextStep,view)).fail(function(errCode,errMsg){if(errCode=="ENOMULTI"){view.moveToNextStep()}else{if(errMsg){baseView.toggleActionError("submit",errMsg)}view.submitEnabled(true)}})},moveToNextStep:function(){this.load();this.baseView.loadAssessmentModules();this.unsavedWarningEnabled(false)},confirmSubmission:function(){var msg="You're about to submit your response for this assignment. "+"After you submit this response, you can't change it or submit a new response.";return $.Deferred(function(defer){if(confirm(msg)){defer.resolve()}else{defer.reject()}})}};OpenAssessment.Rubric=function(element){this.element=element};OpenAssessment.Rubric.prototype={criterionFeedback:function(criterionFeedback){var selector="textarea.answer__value";var feedback={};$(selector,this.element).each(function(index,sel){if(typeof criterionFeedback!=="undefined"){$(sel).val(criterionFeedback[sel.name]);feedback[sel.name]=criterionFeedback[sel.name]}else{feedback[sel.name]=$(sel).val()}});return feedback},optionsSelected:function(optionsSelected){var selector="input[type=radio]";if(typeof optionsSelected==="undefined"){var options={};$(selector+":checked",this.element).each(function(index,sel){options[sel.name]=sel.value});return options}else{$(selector,this.element).prop("checked",false);$(selector,this.element).each(function(index,sel){if(optionsSelected.hasOwnProperty(sel.name)){if(sel.value==optionsSelected[sel.name]){$(sel).prop("checked",true)}}})}},canSubmitCallback:function(callback){$(this.element).change(function(){var numChecked=$("input[type=radio]:checked",this).length;var numAvailable=$(".field--radio.assessment__rubric__question",this).length;var canSubmit=numChecked==numAvailable;callback(canSubmit)})},showCorrections:function(corrections){var selector="input[type=radio]";var hasErrors=false;$(selector,this.element).each(function(index,sel){var listItem=$(sel).parents(".assessment__rubric__question");if(corrections.hasOwnProperty(sel.name)){hasErrors=true;listItem.find(".message--incorrect").removeClass("is--hidden");listItem.find(".message--correct").addClass("is--hidden")}else{listItem.find(".message--correct").removeClass("is--hidden");listItem.find(".message--incorrect").addClass("is--hidden")}});return hasErrors}};OpenAssessment.SelfView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.SelfView.prototype={load:function(){var view=this;this.server.render("self_assessment").done(function(html){$("#openassessment__self-assessment",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.showLoadError("self-assessment")})},installHandlers:function(){var view=this;var sel=$("#openassessment__self-assessment",view.element);this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#self-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.selfSubmitEnabled,this))}sel.find("#self-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.selfAssess()})},selfSubmitEnabled:function(enabled){var button=$("#self-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},selfAssess:function(){var view=this;var baseView=this.baseView;baseView.toggleActionError("self",null); if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this);this.trainingView=new OpenAssessment.StudentTrainingView(this.element,this.server,this);this.selfView=new OpenAssessment.SelfView(this.element,this.server,this);this.peerView=new OpenAssessment.PeerView(this.element,this.server,this);this.gradeView=new OpenAssessment.GradeView(this.element,this.server,this);this.messageView=new OpenAssessment.MessageView(this.element,this.server,this);this.staffInfoView=new OpenAssessment.StaffInfoView(this.element,this.server,this)};OpenAssessment.BaseView.prototype={scrollToTop:function(){if($.scrollTo instanceof Function){$(window).scrollTo($("#openassessment__steps"),800,{offset:-50})}},setUpCollapseExpand:function(parentSel,onExpand){parentSel.find(".ui-toggle-visibility__control").click(function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");if(sel.hasClass("is--collapsed")&&onExpand!==undefined){onExpand()}sel.toggleClass("is--collapsed")})},load:function(){this.responseView.load();this.loadAssessmentModules();this.staffInfoView.load()},loadAssessmentModules:function(){this.trainingView.load();this.peerView.load();this.selfView.load();this.gradeView.load()},loadMessageView:function(){this.messageView.load()},toggleActionError:function(type,msg){var element=this.element;var container=null;if(type=="save"){container=".response__submission__actions"}else if(type=="submit"||type=="peer"||type=="self"||type=="student-training"){container=".step__actions"}else if(type=="feedback_assess"){container=".submission__feedback__actions"}if(container===null){if(msg!==null){console.log(msg)}}else{var msgHtml=msg===null?"":msg;$(container+" .message__content",element).html("<p>"+msgHtml+"</p>");$(container,element).toggleClass("has--error",msg!==null)}},showLoadError:function(step){var container="#openassessment__"+step;$(container).toggleClass("has--error",true);$(container+" .step__status__value i").removeClass().addClass("ico icon-warning-sign");$(container+" .step__status__value .copy").html(gettext("Unable to Load"))}};function OpenAssessmentBlock(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.BaseView(runtime,element,server);view.load()}OpenAssessment.StudioView=function(runtime,element,server){this.runtime=runtime;this.server=server;this.liveElement=$(element);var liveElement=this.liveElement;this.settingsFieldSelectors={promptBox:$("#openassessment_prompt_editor",liveElement),titleField:$("#openassessment_title_editor",liveElement),submissionStartField:$("#openassessment_submission_start_editor",liveElement),submissionDueField:$("#openassessment_submission_due_editor",liveElement),hasPeer:$("#include_peer_assessment",liveElement),hasSelf:$("#include_self_assessment",liveElement),hasAI:$("#include_ai_assessment",liveElement),hasTraining:$("#include_student_training",liveElement),peerMustGrade:$("#peer_assessment_must_grade",liveElement),peerGradedBy:$("#peer_assessment_graded_by",liveElement),peerStart:$("#peer_assessment_start_date",liveElement),peerDue:$("#peer_assessment_due_date",liveElement),selfStart:$("#self_assessment_start_date",liveElement),selfDue:$("#self_assessment_due_date",liveElement)};var criterionHtml=$("#openassessment_criterion_1",liveElement).parent().html();this.criterionHtmlTemplate=criterionHtml.replace(new RegExp("1","g"),"C-C-C");var optionHtml=$("#openassessment_criterion_1_option_1",liveElement).parent().html();var criteriaReplaced=optionHtml.replace(new RegExp("criterion_1","g"),"criterion_C-C-C");this.optionHtmlTemplate=criteriaReplaced.replace(new RegExp("option_1","g"),"option_O-O-O");this.numberOfCriteria=0;this.numberOfOptions=[];this.rubricCriteriaSelectors=[];this.rubricFeedbackPrompt=$("#openassessment_rubric_feedback",liveElement);$("#openassessment_criterion_list",liveElement).empty();this.addNewCriterionToRubric();var view=this;$(".openassessment_save_button",liveElement).click(function(eventData){view.save()});$(".openassessment_cancel_button",liveElement).click(function(eventData){view.cancel()});$(".openassessment_editor_content_and_tabs",liveElement).tabs();view.addSettingsAssessmentCheckboxListener("ai_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("self_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("peer_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("student_training",liveElement);$("#openassessment_rubric_add_criterion",liveElement).click(function(eventData){view.addNewCriterionToRubric(liveElement)})};OpenAssessment.StudioView.prototype={load:function(){var view=this},save:function(){var view=this;this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})},addSettingsAssessmentCheckboxListener:function(name,liveElement){$("#include_"+name,liveElement).change(function(){$("#"+name+"_description_closed",liveElement).toggleClass("is--hidden",this.checked);$("#"+name+"_settings_editor",liveElement).toggleClass("is--hidden",!this.checked)})},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},addNewCriterionToRubric:function(){var view=this;var liveElement=this.liveElement;var newCriterionID=this.numberOfCriteria+1;this.numberOfCriteria+=1;this.numberOfOptions[newCriterionID]=0;var criterionHtml=this.criterionHtmlTemplate.replace(new RegExp("C-C-C","g"),""+newCriterionID);$("#openassessment_criterion_list",liveElement).append(criterionHtml);liveElement=$("#openassessment_criterion_"+newCriterionID);$(".openassessment_criterion_option_list",liveElement).empty();view.rubricCriteriaSelectors[newCriterionID]={criterion:liveElement,name:$(".openassessment_criterion_name",liveElement).first(),prompt:$(".openassessment_criterion_prompt",liveElement).first(),options:[],feedback:"disabled"};$("input:radio[value=disabled]",liveElement).prop("checked",true);view.addNewOptionToCriterion(liveElement,newCriterionID);$("#openassessment_display_criterion_"+newCriterionID,liveElement).change(function(){if(this.checked){$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeIn()}else{$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeOut()}});$("#openassessment_criterion_"+newCriterionID+"_remove",liveElement).click(function(eventData){view.removeCriterionFromRubric(newCriterionID)});$("#openassessment_criterion_"+newCriterionID+"_add_option",liveElement).click(function(eventData){view.addNewOptionToCriterion(liveElement,newCriterionID)});$(".openassessment_feedback_remove_button",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_open",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeIn();$(".openassessment_feedback_remove_button",liveElement).fadeOut();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=false});$(".openassessment_criterion_feedback_header_closed",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_open",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeOut();$(".openassessment_feedback_remove_button",liveElement).fadeIn();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=true});$(".openassessment_criterion_feedback_header_closed",liveElement).hide()},removeCriterionFromRubric:function(criterionToRemove){var view=this;var numCriteria=view.numberOfCriteria;var selectors=view.rubricCriteriaSelectors;for(var i=criterionToRemove;i<numCriteria;i++){selectors[i].name.prop("value",selectors[i+1].name.prop("value"));selectors[i].prompt.prop("value",selectors[i+1].prompt.prop("value"));selectors[i].feedback=selectors[i+1].feedback;$('input:radio[value="disabled"]',selectors[i].criterion).prop("checked",true);while(view.numberOfOptions[i]<view.numberOfOptions[i+1]){view.addNewOptionToCriterion(selectors[i].criteria,i)}while(view.numberOfOptions[i]>view.numberOfOptions[i+1]){view.removeOptionFromCriterion(selectors[i].criteria,i,1)}var options1=selectors[i].options;var options2=selectors[i+1].options;var numOptions2=view.numberOfOptions[i+1];for(var j=1;j<numOptions2;j++){options1[j].points.prop("value",options2[j].points.prop("value"));options1[j].name.prop("value",options2[j].name.prop("value"));options1[j].explanation.prop("value",options2[j].explanation.prop("value"))}}view.rubricCriteriaSelectors[view.rubricCriteriaSelectors.length-1].criterion.remove();view.rubricCriteriaSelectors=view.rubricCriteriaSelectors.slice(0,numCriteria);view.numberOfOptions=view.numberOfOptions.slice(0,numCriteria);view.numberOfCriteria-=1},addNewOptionToCriterion:function(liveElement,criterionID){var view=this;var newOptionID=this.numberOfOptions[criterionID]+1;this.numberOfOptions[criterionID]+=1;var optionHtml=this.optionHtmlTemplate;optionHtml=optionHtml.replace(new RegExp("C-C-C","g"),""+criterionID);optionHtml=optionHtml.replace(new RegExp("O-O-O","g"),""+newOptionID);$("#openassessment_criterion_"+criterionID+"_options",liveElement).append(optionHtml);liveElement=$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID);view.rubricCriteriaSelectors[criterionID].options[newOptionID]={option:liveElement,points:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_points",liveElement),name:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_name",liveElement),explanation:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_explanation",liveElement)};$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_remove",liveElement).click(function(eventData){view.removeOptionFromCriterion(liveElement,criterionID,newOptionID)})},removeOptionFromCriterion:function(liveElement,criterionID,optionToRemove){var view=this;var numberOfOptions=view.numberOfOptions[criterionID];var optionSelectors=view.rubricCriteriaSelectors[criterionID].options;for(var i=optionToRemove;i<numberOfOptions;i++){optionSelectors[i].points.prop("value",optionSelectors[i+1].points.prop("value"));optionSelectors[i].name.prop("value",optionSelectors[i+1].name.prop("value"));optionSelectors[i].explanation.prop("value",optionSelectors[i+1].explanation.prop("value"))}optionSelectors[optionSelectors.length-1].option.remove();view.rubricCriteriaSelectors[criterionID].options=view.rubricCriteriaSelectors[criterionID].options.slice(0,optionSelectors.length-1);view.numberOfOptions[criterionID]-=1},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var rubricCriteria=[];for(var i=1;i<=this.numberOfCriteria;i++){var selectorDict=this.rubricCriteriaSelectors[i];var criterionValueDict={order_num:i-1,name:selectorDict.name.prop("value"),prompt:selectorDict.prompt.prop("value"),feedback:$("#openassessment_criterion_"+i+"_feedback").val()};var optionSelectorList=selectorDict.options;var optionValueList=[];for(var j=1;j<=this.numberOfOptions[i];j++){var optionSelectors=optionSelectorList[j];optionValueList=optionValueList.concat([{order_num:j-1,points:this._getInt(optionSelectors.points),name:optionSelectors.name.val(),explanation:optionSelectors.explanation.val()}])}criterionValueDict.options=optionValueList;rubricCriteria=rubricCriteria.concat([criterionValueDict])}var assessments=[];if(this.settingsFieldSelectors.hasTraining.prop("checked")){assessments.push({name:"student-training",examples:this.studentTrainingExamplesCodeBox.getValue()})}if(this.settingsFieldSelectors.hasPeer.prop("checked")){assessments.push({name:"peer-assessment",must_grade:this._getInt(this.settingsFieldSelectors.peerMustGrade),must_be_graded_by:this._getInt(this.settingsFieldSelectors.peerGradedBy),start:this._getDateTime(this.settingsFieldSelectors.peerStart),due:this._getDateTime(this.settingsFieldSelectors.peerDue)})}if(this.settingsFieldSelectors.hasSelf.prop("checked")){assessments.push({name:"self-assessment",start:this._getDateTime(this.settingsFieldSelectors.selfStart),due:this._getDateTime(this.settingsFieldSelectors.selfDue)})}if(this.settingsFieldSelectors.hasAI.prop("checked")){assessments.push({name:"example-based-assessment",examples:this.aiTrainingExamplesCodeBox.getValue()})}var view=this;this.server.updateEditorContext({title:this.settingsFieldSelectors.titleField.val(),prompt:this.settingsFieldSelectors.promptBox.val(),feedbackPrompt:this.rubricFeedbackPrompt.val(),submissionStart:this._getDateTime(this.settingsFieldSelectors.submissionStartField),submissionDue:this._getDateTime(this.settingsFieldSelectors.submissionDueField),criteria:rubricCriteria,assessments:assessments}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})},_getDateTime:function(selector){var dateStr=selector.val();if(dateStr===""){return null}var timestamp=Date.parse(dateStr);if(isNaN(timestamp)){return null}return new Date(timestamp).toISOString()},_getInt:function(selector){return parseInt(selector.val(),10)}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server);view.load()}OpenAssessment.GradeView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.GradeView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("grade").done(function(html){$("#openassessment__grade",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){baseView.showLoadError("grade",errMsg)})},installHandlers:function(){var sel=$("#openassessment__grade",this.element);this.baseView.setUpCollapseExpand(sel);var view=this;sel.find("#feedback__submit").click(function(eventObject){eventObject.preventDefault();view.submitFeedbackOnAssessment()})},feedbackText:function(text){if(typeof text==="undefined"){return $("#feedback__remarks__value",this.element).val()}else{$("#feedback__remarks__value",this.element).val(text)}},feedbackOptions:function(options){var view=this;if(typeof options==="undefined"){return $.map($(".feedback__overall__value:checked",view.element),function(element,index){return $(element).val()})}else{$(".feedback__overall__value",this.element).prop("checked",false);$.each(options,function(index,opt){$("#feedback__overall__value--"+opt,view.element).prop("checked",true)})}},setHidden:function(sel,hidden){sel.toggleClass("is--hidden",hidden);sel.attr("aria-hidden",hidden?"true":"false")},isHidden:function(sel){return sel.hasClass("is--hidden")&&sel.attr("aria-hidden")=="true"},feedbackState:function(newState){var containerSel=$(".submission__feedback__content",this.element);var instructionsSel=containerSel.find(".submission__feedback__instructions");var fieldsSel=containerSel.find(".submission__feedback__fields");var actionsSel=containerSel.find(".submission__feedback__actions");var transitionSel=containerSel.find(".transition__status");var messageSel=containerSel.find(".message--complete");if(typeof newState==="undefined"){var isSubmitting=containerSel.hasClass("is--transitioning")&&containerSel.hasClass("is--submitting")&&!this.isHidden(transitionSel)&&this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var hasSubmitted=containerSel.hasClass("is--submitted")&&this.isHidden(transitionSel)&&!this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var isOpen=!containerSel.hasClass("is--submitted")&&!containerSel.hasClass("is--transitioning")&&!containerSel.hasClass("is--submitting")&&this.isHidden(transitionSel)&&this.isHidden(messageSel)&&!this.isHidden(instructionsSel)&&!this.isHidden(fieldsSel)&&!this.isHidden(actionsSel);if(isOpen){return"open"}else if(isSubmitting){return"submitting"}else if(hasSubmitted){return"submitted"}else{throw"Invalid feedback state"}}else{if(newState=="open"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,false);this.setHidden(fieldsSel,false);this.setHidden(actionsSel,false);this.setHidden(transitionSel,true);this.setHidden(messageSel,true)}else if(newState=="submitting"){containerSel.toggleClass("is--transitioning",true);containerSel.toggleClass("is--submitting",true);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,false);this.setHidden(messageSel,true)}else if(newState=="submitted"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",true);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,true);this.setHidden(messageSel,false)}}},submitFeedbackOnAssessment:function(){var view=this;var baseView=this.baseView;$("#feedback__submit",this.element).toggleClass("is--disabled",true);view.feedbackState("submitting");this.server.submitFeedbackOnAssessment(this.feedbackText(),this.feedbackOptions()).done(function(){view.feedbackState("submitted")}).fail(function(errMsg){baseView.toggleActionError("feedback_assess",errMsg)})}};OpenAssessment.MessageView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.MessageView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("message").done(function(html){$("#openassessment__message",view.element).replaceWith(html)}).fail(function(errMsg){baseView.showLoadError("message",errMsg)})}};OpenAssessment.PeerView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.PeerView.prototype={load:function(){var view=this;this.server.render("peer_assessment").done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")})},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel,$.proxy(view.loadContinuedAssessment,view));var rubricSelector=$("#peer-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(view.peerSubmitEnabled,view))}sel.find("#peer-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();if(!isContinuedAssessment){view.peerAssess()}else{view.continuedPeerAssess()}})},peerSubmitEnabled:function(enabled){var button=$("#peer-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},peerAssess:function(){var view=this;var baseView=view.baseView;this.peerAssessRequest(function(){view.load();baseView.loadAssessmentModules();baseView.scrollToTop()})},continuedPeerAssess:function(){var view=this;var gradeView=this.baseView.gradeView;var baseView=view.baseView;view.peerAssessRequest(function(){view.loadContinuedAssessment();gradeView.load();baseView.scrollToTop()})},peerAssessRequest:function(successFunction){var view=this;view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.overallFeedback()).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})},overallFeedback:function(overallFeedback){var selector="#assessment__rubric__question--feedback__value";if(typeof overallFeedback==="undefined"){return $(selector,this.element).val()}else{$(selector,this.element).val(overallFeedback)}}};OpenAssessment.ResponseView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.savedResponse="";this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.installHandlers();view.setAutoSaveEnabled(true)}).fail(function(errMsg){view.baseView.showLoadError("response")})},installHandlers:function(){var sel=$("#openassessment__response",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);this.savedResponse=this.response();var handleChange=function(eventData){view.handleResponseChanged()};sel.find("#submission__answer__value").on("change keyup drop paste",handleChange);sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()})},setAutoSaveEnabled:function(enabled){if(enabled){if(this.autoSaveTimerId===null){this.autoSaveTimerId=setInterval($.proxy(this.autoSave,this),this.AUTO_SAVE_POLL_INTERVAL)}}else{if(this.autoSaveTimerId!==null){clearInterval(this.autoSaveTimerId)}}},submitEnabled:function(enabled){var sel=$("#step--response__submit",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveEnabled:function(enabled){var sel=$("#submission__save",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveStatus:function(msg){var sel=$("#response__save_status h3",this.element);if(typeof msg==="undefined"){return sel.text()}else{var label=gettext("Status of Your Response");sel.html('<span class="sr">'+label+":"+"</span>\n"+msg)}},unsavedWarningEnabled:function(enabled){if(typeof enabled==="undefined"){return window.onbeforeunload!==null}else{if(enabled){window.onbeforeunload=function(){return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.")}}else{window.onbeforeunload=null}}},response:function(text){var sel=$("#submission__answer__value",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},responseChanged:function(){var currentResponse=$.trim(this.response());var savedResponse=$.trim(this.savedResponse);return savedResponse!==currentResponse},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isBlank=$.trim(this.response())!=="";this.submitEnabled(isBlank);if(this.responseChanged()){this.saveEnabled(isBlank);this.saveStatus(gettext("This response has not been saved."));this.unsavedWarningEnabled(true)}this.lastChangeTime=Date.now()},save:function(){this.errorOnLastSave=false;this.saveStatus(gettext("Saving..."));this.baseView.toggleActionError("save",null);this.unsavedWarningEnabled(false);var view=this;var savedResponse=this.response();this.server.save(savedResponse).done(function(){view.savedResponse=savedResponse;var currentResponse=view.response();view.submitEnabled(currentResponse!=="");if(currentResponse==savedResponse){view.saveEnabled(false);view.saveStatus(gettext("This response has been saved but not submitted."))}}).fail(function(errMsg){view.saveStatus(gettext("Error"));view.baseView.toggleActionError("save",errMsg);view.errorOnLastSave=true})},submit:function(){this.submitEnabled(false);var view=this;var baseView=this.baseView;this.confirmSubmission().pipe(function(){var submission=$("#submission__answer__value",view.element).val();baseView.toggleActionError("response",null);return view.server.submit(submission)}).done($.proxy(view.moveToNextStep,view)).fail(function(errCode,errMsg){if(errCode=="ENOMULTI"){view.moveToNextStep()}else{if(errMsg){baseView.toggleActionError("submit",errMsg)}view.submitEnabled(true)}})},moveToNextStep:function(){this.load();this.baseView.loadAssessmentModules();this.unsavedWarningEnabled(false)},confirmSubmission:function(){var msg="You're about to submit your response for this assignment. "+"After you submit this response, you can't change it or submit a new response.";return $.Deferred(function(defer){if(confirm(msg)){defer.resolve()}else{defer.reject()}})}};OpenAssessment.Rubric=function(element){this.element=element};OpenAssessment.Rubric.prototype={criterionFeedback:function(criterionFeedback){var selector="textarea.answer__value";var feedback={};$(selector,this.element).each(function(index,sel){if(typeof criterionFeedback!=="undefined"){$(sel).val(criterionFeedback[sel.name]);feedback[sel.name]=criterionFeedback[sel.name]}else{feedback[sel.name]=$(sel).val()}});return feedback},optionsSelected:function(optionsSelected){var selector="input[type=radio]";if(typeof optionsSelected==="undefined"){var options={};$(selector+":checked",this.element).each(function(index,sel){options[sel.name]=sel.value});return options}else{$(selector,this.element).prop("checked",false);$(selector,this.element).each(function(index,sel){if(optionsSelected.hasOwnProperty(sel.name)){if(sel.value==optionsSelected[sel.name]){$(sel).prop("checked",true)}}})}},canSubmitCallback:function(callback){$(this.element).change(function(){var numChecked=$("input[type=radio]:checked",this).length;var numAvailable=$(".field--radio.assessment__rubric__question",this).length;var canSubmit=numChecked==numAvailable;callback(canSubmit)})},showCorrections:function(corrections){var selector="input[type=radio]";var hasErrors=false;$(selector,this.element).each(function(index,sel){var listItem=$(sel).parents(".assessment__rubric__question");if(corrections.hasOwnProperty(sel.name)){hasErrors=true;listItem.find(".message--incorrect").removeClass("is--hidden");listItem.find(".message--correct").addClass("is--hidden")}else{listItem.find(".message--correct").removeClass("is--hidden");listItem.find(".message--incorrect").addClass("is--hidden")}});return hasErrors}};OpenAssessment.SelfView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.SelfView.prototype={load:function(){var view=this;this.server.render("self_assessment").done(function(html){$("#openassessment__self-assessment",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.showLoadError("self-assessment")})},installHandlers:function(){var view=this;var sel=$("#openassessment__self-assessment",view.element);this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#self-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.selfSubmitEnabled,this))}sel.find("#self-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.selfAssess()})},selfSubmitEnabled:function(enabled){var button=$("#self-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},selfAssess:function(){var view=this;var baseView=this.baseView;baseView.toggleActionError("self",null);view.selfSubmitEnabled(false);var options=this.rubric.optionsSelected();this.server.selfAssess(options).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");
view.selfSubmitEnabled(false);var options=this.rubric.optionsSelected();this.server.selfAssess(options).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},loadEditorContext:function(){var url=this.url("editor_context");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.prompt,data.rubric,data.title,data.submission_start,data.submission_due,data.assessments])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be loaded.")])})}).promise()},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()}};if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.StaffInfoView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.StaffInfoView.prototype={load:function(){var view=this;if($("#openassessment__staff-info",view.element).length>0){this.server.render("staff_info").done(function(html){$("#openassessment__staff-info",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_id=sel.find("#openassessment__student_id").val();this.server.studentInfo(student_id).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html)}).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_id").click(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#schedule_training").click(function(eventObject){eventObject.preventDefault();view.scheduleTraining()});sel.find("#reschedule_unfinished_tasks").click(function(eventObject){eventObject.preventDefault();view.rescheduleUnfinishedTasks()})},scheduleTraining:function(){var view=this;this.server.scheduleTraining().done(function(msg){$("#schedule_training_message",this.element).text(msg)}).fail(function(errMsg){$("#schedule_training_message",this.element).text(errMsg)})},rescheduleUnfinishedTasks:function(){var view=this;this.server.rescheduleUnfinishedTasks().done(function(msg){$("#reschedule_unfinished_tasks_message",this.element).text(msg)}).fail(function(errMsg){$("#reschedule_unfinished_tasks_message",this.element).text(errMsg)})}};OpenAssessment.StudentTrainingView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.StudentTrainingView.prototype={load:function(){var view=this;this.server.render("student_training").done(function(html){$("#openassessment__student-training",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("student-training")})},installHandlers:function(){var sel=$("#openassessment__student-training",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#student-training--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.assessButtonEnabled,this))}sel.find("#student-training--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.assess()})},assess:function(){this.assessButtonEnabled(false);var options={};if(this.rubric!==null){options=this.rubric.optionsSelected()}var view=this;var baseView=this.baseView;this.server.trainingAssess(options).done(function(corrections){var incorrect=$("#openassessment__student-training--incorrect",this.element);var instructions=$("#openassessment__student-training--instructions",this.element);if(!view.rubric.showCorrections(corrections)){view.load();baseView.loadAssessmentModules();incorrect.addClass("is--hidden");instructions.removeClass("is--hidden")}else{instructions.addClass("is--hidden");incorrect.removeClass("is--hidden")}baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("student-training",errMsg);view.assessButtonEnabled(true)})},assessButtonEnabled:function(isEnabled){var button=$("#student-training--001__assessment__submit",this.element);if(typeof isEnabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!isEnabled)}}}; var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()}};if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.StaffInfoView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.StaffInfoView.prototype={load:function(){var view=this;if($("#openassessment__staff-info",view.element).length>0){this.server.render("staff_info").done(function(html){$("#openassessment__staff-info",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_id=sel.find("#openassessment__student_id").val();this.server.studentInfo(student_id).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html)}).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_id").click(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#schedule_training").click(function(eventObject){eventObject.preventDefault();view.scheduleTraining()});sel.find("#reschedule_unfinished_tasks").click(function(eventObject){eventObject.preventDefault();view.rescheduleUnfinishedTasks()})},scheduleTraining:function(){var view=this;this.server.scheduleTraining().done(function(msg){$("#schedule_training_message",this.element).text(msg)}).fail(function(errMsg){$("#schedule_training_message",this.element).text(errMsg)})},rescheduleUnfinishedTasks:function(){var view=this;this.server.rescheduleUnfinishedTasks().done(function(msg){$("#reschedule_unfinished_tasks_message",this.element).text(msg)}).fail(function(errMsg){$("#reschedule_unfinished_tasks_message",this.element).text(errMsg)})}};OpenAssessment.StudentTrainingView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.StudentTrainingView.prototype={load:function(){var view=this;this.server.render("student_training").done(function(html){$("#openassessment__student-training",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("student-training")})},installHandlers:function(){var sel=$("#openassessment__student-training",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#student-training--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.assessButtonEnabled,this))}sel.find("#student-training--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.assess()})},assess:function(){this.assessButtonEnabled(false);var options={};if(this.rubric!==null){options=this.rubric.optionsSelected()}var view=this;var baseView=this.baseView;this.server.trainingAssess(options).done(function(corrections){var incorrect=$("#openassessment__student-training--incorrect",this.element);var instructions=$("#openassessment__student-training--instructions",this.element);if(!view.rubric.showCorrections(corrections)){view.load();baseView.loadAssessmentModules();incorrect.addClass("is--hidden");instructions.removeClass("is--hidden")}else{instructions.addClass("is--hidden");incorrect.removeClass("is--hidden")}baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("student-training",errMsg);view.assessButtonEnabled(true)})},assessButtonEnabled:function(isEnabled){var button=$("#student-training--001__assessment__submit",this.element);if(typeof isEnabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!isEnabled)}}};
\ No newline at end of file \ No newline at end of file
...@@ -199,39 +199,6 @@ describe("OpenAssessment.Server", function() { ...@@ -199,39 +199,6 @@ describe("OpenAssessment.Server", function() {
}); });
}); });
it("loads the XBlock's Context definition", function() {
stubAjax(true, {
success: true, prompt: PROMPT, rubric: RUBRIC, title: TITLE,
submission_start: SUBMISSION_START, submission_due: SUBMISSION_DUE, assessments: ASSESSMENTS
});
var loadedPrompt = "";
var loadedRubric = "";
var loadedAssessments = [];
var loadedTitle = "";
var loadedStart = "";
var loadedDue = "";
server.loadEditorContext().done(function(prompt, rubric, title, sub_start, sub_due, assessments) {
loadedPrompt = prompt;
loadedRubric = rubric;
loadedTitle = title;
loadedStart = sub_start;
loadedDue = sub_due;
loadedAssessments = assessments;
});
expect(loadedPrompt).toEqual(PROMPT);
expect(loadedRubric).toEqual(RUBRIC);
expect(loadedTitle).toEqual(TITLE);
expect(loadedStart).toEqual(SUBMISSION_START);
expect(loadedDue).toEqual(SUBMISSION_DUE);
expect(loadedAssessments).toEqual(ASSESSMENTS);
expect($.ajax).toHaveBeenCalledWith({
url: '/editor_context', type: "POST", data: '""'
});
});
it("updates the XBlock's Context definition", function() { it("updates the XBlock's Context definition", function() {
stubAjax(true, { success: true }); stubAjax(true, { success: true });
...@@ -336,18 +303,6 @@ describe("OpenAssessment.Server", function() { ...@@ -336,18 +303,6 @@ describe("OpenAssessment.Server", function() {
expect(receivedMsg).toEqual('test error'); expect(receivedMsg).toEqual('test error');
}); });
it("informs the caller of an Ajax error when loading the editor context", function() {
stubAjax(false, null);
var receivedMsg = null;
server.loadEditorContext().fail(function(msg) {
receivedMsg = msg;
});
expect(receivedMsg).toContain("This problem could not be loaded");
});
it("informs the caller of an Ajax error when updating the editor context", function() { it("informs the caller of an Ajax error when updating the editor context", function() {
stubAjax(false, null); stubAjax(false, null);
...@@ -370,17 +325,6 @@ describe("OpenAssessment.Server", function() { ...@@ -370,17 +325,6 @@ describe("OpenAssessment.Server", function() {
expect(receivedMsg).toEqual("Test error"); expect(receivedMsg).toEqual("Test error");
}); });
it("informs the caller of a server error when updating the editor context", function() {
stubAjax(true, { success: false, msg: "Test error" });
var receivedMsg = null;
server.loadEditorContext().fail(function(msg) {
receivedMsg = msg;
});
expect(receivedMsg).toEqual("Test error");
});
it("informs the caller of a server error when sending a peer assessment", function() { it("informs the caller of a server error when sending a peer assessment", function() {
stubAjax(true, {success:false, msg:'Test error!'}); stubAjax(true, {success:false, msg:'Test error!'});
......
...@@ -37,16 +37,6 @@ OpenAssessment.StudioView = function(runtime, element, server) { ...@@ -37,16 +37,6 @@ OpenAssessment.StudioView = function(runtime, element, server) {
selfDue: $('#self_assessment_due_date', liveElement) selfDue: $('#self_assessment_due_date', liveElement)
}; };
this.aiTrainingExamplesCodeBox = CodeMirror.fromTextArea(
$('#ai_training_examples', liveElement).first().get(0),
{mode: "xml", lineNumbers: true, lineWrapping: true}
);
this.studentTrainingExamplesCodeBox = CodeMirror.fromTextArea(
$('#student_training_examples', liveElement).first().get(0),
{mode: "xml", lineNumbers: true, lineWrapping: true}
);
// Captures the HTML definition of the original criterion element. This will be the template // Captures the HTML definition of the original criterion element. This will be the template
// used for all other criterion creations // used for all other criterion creations
var criterionHtml = $("#openassessment_criterion_1", liveElement).parent().html(); var criterionHtml = $("#openassessment_criterion_1", liveElement).parent().html();
...@@ -104,85 +94,6 @@ OpenAssessment.StudioView.prototype = { ...@@ -104,85 +94,6 @@ OpenAssessment.StudioView.prototype = {
**/ **/
load: function () { load: function () {
var view = this; var view = this;
this.server.loadEditorContext().done(
function (prompt, rubric, title, subStart, subDue, assessments) {
view.settingsFieldSelectors.submissionStartField.prop('value', subStart);
view.settingsFieldSelectors.submissionDueField.prop('value', subDue);
view.settingsFieldSelectors.promptBox.prop('value', prompt);
view.settingsFieldSelectors.titleField.prop('value', title);
view.settingsFieldSelectors.hasTraining.prop('checked', false).change();
view.settingsFieldSelectors.hasPeer.prop('checked', false).change();
view.settingsFieldSelectors.hasSelf.prop('checked', false).change();
view.settingsFieldSelectors.hasAI.prop('checked', false).change();
for (var i = 0; i < assessments.length; i++) {
var assessment = assessments[i];
if (assessment.name == 'peer-assessment') {
view.settingsFieldSelectors.peerMustGrade.prop('value', assessment.must_grade);
view.settingsFieldSelectors.peerGradedBy.prop('value', assessment.must_be_graded_by);
view.settingsFieldSelectors.peerStart.prop('value', assessment.start);
view.settingsFieldSelectors.peerDue.prop('value', assessment.due);
view.settingsFieldSelectors.hasPeer.prop('checked', true).change();
} else if (assessment.name == 'self-assessment') {
view.settingsFieldSelectors.selfStart.prop('value', assessment.start);
view.settingsFieldSelectors.selfDue.prop('value', assessment.due);
view.settingsFieldSelectors.hasSelf.prop('checked', true).change();
} else if (assessment.name == 'example-based-assessment') {
view.settingsFieldSelectors.aiTrainingExamplesCodeBox.setValue(assessment.examples);
view.settingsFieldSelectors.hasAI.prop('checked', true).change();
} else if (assessment.name == 'student-training') {
view.studentTrainingExamplesCodeBox.setValue(assessment.examples);
view.settingsFieldSelectors.hasTraining.prop('checked', true).change();
}
}
// Corrects the length of the number of criteria
while(view.numberOfCriteria < rubric.criteria.length){
view.addNewCriterionToRubric();
}
while(view.numberOfCriteria > rubric.criteria.length){
view.removeCriterionFromRubric(1);
}
// Corrects the number of options in each criterion
for (i = 0; i < rubric.criteria.length; i++){
while(view.numberOfOptions[i+1] < rubric.criteria[i].options.length){
view.addNewOptionToCriterion(view.liveElement, i+1);
}
while(view.numberOfOptions[i+1] > rubric.criteria[i].options.length){
view.removeOptionFromCriterion(view.liveElement, i+1, 1);
}
}
// Inserts the data from the rubric into the GUI's fields
for (i = 0; i < rubric.criteria.length; i++){
var criterion = rubric.criteria[i];
var selectors = view.rubricCriteriaSelectors[i+1];
// Transfers the Criteria Fields
selectors.name.prop('value', criterion.name);
selectors.prompt.prop('value', criterion.prompt);
selectors.feedback = criterion.feedback;
for (var j = 0; j < criterion.options.length; j++){
var option = criterion.options[j];
var optionSelectors = selectors.options[j+1];
// Transfers all of the option data.
optionSelectors.name.prop('value', option.name);
optionSelectors.points.prop('value', option.points);
optionSelectors.explanation.prop('value', option.explanation);
}
}
if (rubric.feedbackprompt){
view.rubricFeedbackPrompt.prop('value', rubric.feedbackprompt);
view.hasRubricFeedbackPrompt = true;
} else {
view.rubricFeedbackPrompt.prop('value', "");
view.hasRubricFeedbackPrompt = false;
}
}).fail(function (msg) {
view.showError(msg);
}
);
}, },
/** /**
...@@ -217,13 +128,8 @@ OpenAssessment.StudioView.prototype = { ...@@ -217,13 +128,8 @@ OpenAssessment.StudioView.prototype = {
*/ */
addSettingsAssessmentCheckboxListener: function (name, liveElement) { addSettingsAssessmentCheckboxListener: function (name, liveElement) {
$("#include_" + name , liveElement) .change(function () { $("#include_" + name , liveElement) .change(function () {
if (this.checked){ $("#" + name + "_description_closed", liveElement).toggleClass('is--hidden', this.checked);
$("#" + name + "_description_closed", liveElement).fadeOut('fast'); $("#" + name + "_settings_editor", liveElement).toggleClass('is--hidden', !this.checked);
$("#" + name + "_settings_editor", liveElement).fadeIn();
} else {
$("#" + name + "_settings_editor", liveElement).fadeOut('fast');
$("#" + name + "_description_closed", liveElement).fadeIn();
}
}); });
}, },
......
...@@ -395,36 +395,6 @@ OpenAssessment.Server.prototype = { ...@@ -395,36 +395,6 @@ OpenAssessment.Server.prototype = {
}, },
/** /**
Load the XBlock's XML definition from the server.
Returns:
A JQuery promise, which resolves with the XML definition
and fails with an error message.
Example:
server.loadXml().done(
function(xml) { console.log(xml); }
).fail(
function(err) { console.log(err); }
);
**/
loadEditorContext: function() {
var url = this.url('editor_context');
return $.Deferred(function(defer) {
$.ajax({
type: "POST", url: url, data: "\"\""
}).done(function(data) {
if (data.success) { defer.resolveWith(this, [
data.prompt, data.rubric, data.title, data.submission_start, data.submission_due, data.assessments
]); }
else { defer.rejectWith(this, [data.msg]); }
}).fail(function(data) {
defer.rejectWith(this, [gettext('This problem could not be loaded.')]);
});
}).promise();
},
/**
Update the XBlock's XML definition on the server. Update the XBlock's XML definition on the server.
Kwargs: Kwargs:
......
""" """
Studio editing view for OpenAssessment XBlock. Studio editing view for OpenAssessment XBlock.
""" """
from django.template import Context
import pkg_resources import pkg_resources
import copy import copy
import logging import logging
from django.template.context import Context
from django.template.loader import get_template from django.template.loader import get_template
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from voluptuous import MultipleInvalid from voluptuous import MultipleInvalid
...@@ -20,6 +20,16 @@ logger = logging.getLogger(__name__) ...@@ -20,6 +20,16 @@ logger = logging.getLogger(__name__)
class StudioMixin(object): class StudioMixin(object):
DEFAULT_CRITERIA = [
{
'options': [
{
},
]
}
]
""" """
Studio editing view for OpenAssessment XBlock. Studio editing view for OpenAssessment XBlock.
""" """
...@@ -34,12 +44,73 @@ class StudioMixin(object): ...@@ -34,12 +44,73 @@ class StudioMixin(object):
Returns: Returns:
(Fragment): An HTML fragment for editing the configuration of this XBlock. (Fragment): An HTML fragment for editing the configuration of this XBlock.
""" """
rendered_template = get_template('openassessmentblock/oa_edit.html').render(Context({})) rendered_template = get_template(
'openassessmentblock/edit/oa_edit.html'
).render(Context(self.editor_context()))
frag = Fragment(rendered_template) frag = Fragment(rendered_template)
frag.add_javascript(pkg_resources.resource_string(__name__, "static/js/openassessment.min.js")) frag.add_javascript(pkg_resources.resource_string(__name__, "static/js/openassessment.min.js"))
frag.initialize_js('OpenAssessmentEditor') frag.initialize_js('OpenAssessmentEditor')
return frag return frag
def editor_context(self):
"""
Retrieve the XBlock's content definition.
Returns:
dict with keys
'rubric' (unicode), 'prompt' (unicode), 'title' (unicode),
'submission_start' (unicode), 'submission_due' (unicode),
'assessments (dict)
"""
# Copies the rubric assessments so that we can change student
# training examples from dict -> str without negatively modifying
# the openassessmentblock definition.
# Django Templates cannot handle dict keys with dashes, so we'll convert
# the dashes to underscores.
assessments = {}
for assessment in self.rubric_assessments:
name = assessment['name']
assessments[name.replace('-', '_')] = copy.deepcopy(
assessment
)
student_training_module = self.get_assessment_module(
'student-training'
)
if student_training_module:
student_training_module = copy.deepcopy(student_training_module)
try:
examples = xml.serialize_examples_to_xml_str(
student_training_module
)
student_training_module["examples"] = examples
assessments['training'] = student_training_module
# We do not expect serialization to raise an exception, but if it does,
# handle it gracefully.
except:
logger.exception("An error occurred while serializing the XBlock")
submission_due = self.submission_due if self.submission_due else ''
submission_start = self.submission_start if self.submission_start else ''
# Every rubric requires one criterion. If there is no criteria
# configured for the XBlock, return one empty default criterion, with
# an empty default option.
criteria = copy.deepcopy(self.rubric_criteria)
if not criteria:
criteria = self.DEFAULT_CRITERIA
return {
'prompt': self.prompt,
'title': self.title,
'submission_due': submission_due,
'submission_start': submission_start,
'assessments': assessments,
'criteria': criteria,
'feedbackprompt': unicode(self.rubric_feedback_prompt),
}
@XBlock.json_handler @XBlock.json_handler
def update_editor_context(self, data, suffix=''): def update_editor_context(self, data, suffix=''):
""" """
...@@ -94,66 +165,6 @@ class StudioMixin(object): ...@@ -94,66 +165,6 @@ class StudioMixin(object):
return {'success': True, 'msg': _(u'Successfully updated OpenAssessment XBlock')} return {'success': True, 'msg': _(u'Successfully updated OpenAssessment XBlock')}
@XBlock.json_handler @XBlock.json_handler
def editor_context(self, data, suffix=''):
"""
Retrieve the XBlock's content definition, serialized as a JSON object
containing all the configuration as it will be displayed for studio
editing.
Args:
data (dict): Not used
Kwargs:
suffix (str): Not used
Returns:
dict with keys
'success' (bool), 'message' (unicode), 'rubric' (unicode), 'prompt' (unicode),
'title' (unicode), 'submission_start' (unicode), 'submission_due' (unicode), 'assessments (dict)
"""
try:
# Copies the rubric assessments so that we can change student training examples from dict -> str without
# negatively modifying the openassessmentblock definition.
assessment_list = copy.deepcopy(self.rubric_assessments)
# Finds the student training dictionary, if it exists, and replaces the examples with their XML definition
student_training_dictionary = [d for d in assessment_list if d["name"] == "student-training"]
if student_training_dictionary:
# Our for loop will return a list. Select the first element of that list if it exists.
student_training_dictionary = student_training_dictionary[0]
examples = xml.serialize_examples_to_xml_str(student_training_dictionary)
student_training_dictionary["examples"] = examples
# We do not expect serialization to raise an exception, but if it does, handle it gracefully.
except:
logger.exception("An error occurred while serializing the XBlock")
msg = _('An unexpected error occurred while loading the problem')
return {'success': False, 'msg': msg, 'xml': u''}
# Populates the context for the assessments section of the editing
# panel. This will adjust according to the fields laid out in this
# section.
submission_due = self.submission_due if self.submission_due else ''
submission_start = self.submission_start if self.submission_start else ''
rubric_dict = {
'criteria' : self.rubric_criteria,
'feedbackprompt': unicode(self.rubric_feedback_prompt)
}
return {
'success': True,
'msg': '',
'rubric': rubric_dict,
'prompt': self.prompt,
'submission_due': submission_due,
'submission_start': submission_start,
'title': self.title,
'assessments': assessment_list
}
@XBlock.json_handler
def check_released(self, data, suffix=''): def check_released(self, data, suffix=''):
""" """
Check whether the problem has been released. Check whether the problem has been released.
......
...@@ -21,23 +21,6 @@ class StudioViewTest(XBlockHandlerTestCase): ...@@ -21,23 +21,6 @@ class StudioViewTest(XBlockHandlerTestCase):
frag = self.runtime.render(xblock, 'studio_view') frag = self.runtime.render(xblock, 'studio_view')
self.assertTrue(frag.body_html().find('openassessment-edit')) self.assertTrue(frag.body_html().find('openassessment-edit'))
@scenario('data/basic_scenario.xml')
def test_get_editor_context(self, xblock):
resp = self.request(xblock, 'editor_context', '""', response_format='json')
self.assertTrue(resp['success'])
self.assertEqual(resp['msg'], u'')
# Verify that the Rubric has criteria, and that they are a list of dictionaries
self.assertTrue(isinstance(resp['rubric']['criteria'], list))
self.assertTrue(isinstance(resp['rubric']['criteria'][0], dict))
# Verify that every assessment in the list of assessments has a name.
for assessment_dict in resp['assessments']:
self.assertTrue(assessment_dict.get('name', False))
if assessment_dict.get('name') == 'student-training':
examples = etree.fromstring(assessment_dict['examples'])
self.assertEqual(examples.tag, 'examples')
@file_data('data/update_xblock.json') @file_data('data/update_xblock.json')
@scenario('data/basic_scenario.xml') @scenario('data/basic_scenario.xml')
def test_update_context(self, xblock, data): def test_update_context(self, xblock, data):
......
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