Commit 2e4c9ef4 by Usman Khalid

Merge pull request #655 from edx/usman/tnl708-multiple-prompts-studio

Multiple prompts 2: Studio changes.
parents 3f816d0a ac69321b
...@@ -25,9 +25,7 @@ ...@@ -25,9 +25,7 @@
</a> </a>
</div> </div>
<div id="oa_prompt_editor_wrapper" class="oa_editor_content_wrapper"> {% include "openassessmentblock/edit/oa_edit_prompts.html" %}
<textarea id="openassessment_prompt_editor" maxlength="10000">{{ prompt }}</textarea>
</div>
{% include "openassessmentblock/edit/oa_edit_rubric.html" %} {% include "openassessmentblock/edit/oa_edit_rubric.html" %}
......
{% load i18n %} {% load i18n %}
{% spaceless %} {% spaceless %}
<li class="openassessment_criterion is-collapsible" data-criterion="{{ criterion_name }}"> <li class="openassessment_criterion is-collapsible" data-criterion="{{ criterion_name }}">
<div class="openassessment_criterion_header view-outline"> <div class="openassessment_container_header openassessment_criterion_header view-outline">
<a class="action expand-collapse collapse"><i class="icon-caret-down ui-toggle-expansion"></i></a> <a class="action expand-collapse collapse"><i class="icon-caret-down ui-toggle-expansion"></i></a>
<div class="openassessment_criterion_header_title_box"> <div class="openassessment_container_header_title_box openassessment_criterion_header_title_box">
<h6 class="openassessment_criterion_header_title">{% trans "Criterion" %}</h6> <h6 class="openassessment_container_header_title openassessment_criterion_header_title">{% trans "Criterion" %}</h6>
<p class="openassessment_criterion_guide">{% trans "You cannot delete a criterion after the assignment has been released." %}</p> <p class="openassessment_container_guide openassessment_criterion_guide">{% trans "You cannot delete a criterion after the assignment has been released." %}</p>
</div> </div>
<div class="openassessment_criterion_remove_button"><h2>{% trans "Remove" %}</h2></div> <div class="openassessment_container_remove_button openassessment_criterion_remove_button"><h2>{% trans "Remove" %}</h2></div>
</div> </div>
<div class="openassessment_criterion_body wrapper-comp-settings"> <div class="openassessment_criterion_body wrapper-comp-settings">
<input type="hidden" class="openassessment_criterion_name" value="{{ criterion_name }}" /> <input type="hidden" class="openassessment_criterion_name" value="{{ criterion_name }}" />
......
{% load i18n %}
{% spaceless %}
<li class="openassessment_prompt is-collapsible" data-prompt="{{ prompt_uuid }}">
<div class="openassessment_container_header openassessment_prompt_header view-outline">
<a class="action expand-collapse collapse"><i class="icon-caret-down ui-toggle-expansion"></i></a>
<div class="openassessment_container_header_title_box openassessment_prompt_header_title_box">
<h6 class="openassessment_container_header_title openassessment_prompt_header_title">{% trans "Prompt" %}</h6>
<p class="openassessment_container_guide openassessment_prompt_guide">{% trans "You cannot delete a prompt after the assignment has been released." %}</p>
</div>
<div class="openassessment_container_remove_button openassessment_prompt_remove_button"><h2>{% trans "Remove" %}</h2></div>
</div>
<div class="openassessment_prompt_body wrapper-comp-settings">
<input type="hidden" class="openassessment_prompt_uuid" value="{{ prompt_uuid }}" />
<ul class="list-input settings-list">
<li class="field comp-setting-entry openassessment_prompt_description_wrapper">
<div class="wrapper-comp-settings">
<textarea class="openassessment_prompt_description setting-input" maxlength="10000">{{ prompt_description }}</textarea>
</div>
</li>
</ul>
</div>
</li>
{% endspaceless %}
{% load i18n %}
{% spaceless %}
<div id="oa_prompts_editor_wrapper" class="oa_editor_content_wrapper">
<div id="openassessment_prompt_template" class="is--hidden">
{% include "openassessmentblock/edit/oa_edit_prompt.html" with prompt_uuid="" prompt_description="" %}
</div>
<div id="openassessment_prompts_instructions" class="openassessment_tab_instructions">
<p class="openassessment_description">
{% trans "Prompts. Replace the sample text with your own text. For more information, see the ORA documentation." %}
</p>
</div>
<ul id="openassessment_prompts_list">
{% for prompt in prompts %}
{% include "openassessmentblock/edit/oa_edit_prompt.html" with prompt_uuid=prompt.uuid prompt_description=prompt.description %}
{% endfor %}
</ul>
<div id="openassessment_prompts_add_prompt" class="openassessment_container_add_button">
<h6>
{% trans "Add Prompt" %}
</h6>
</div>
</div>
{% endspaceless %}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
{% include "openassessmentblock/edit/oa_edit_option.html" with option_name="" option_label="" option_points=1 option_explanation="" %} {% include "openassessmentblock/edit/oa_edit_option.html" with option_name="" option_label="" option_points=1 option_explanation="" %}
</div> </div>
<div id="openassessment_rubric_instructions"> <div id="openassessment_rubric_instructions" class="openassessment_tab_instructions">
<p class="openassessment_description"> <p class="openassessment_description">
{% trans "Rubrics are made up of criteria, which usually contain one or more options. Each option has a point value. This template contains two sample criteria and their options. Replace the sample text with your own text. For more information, see the ORA documentation." %} {% trans "Rubrics are made up of criteria, which usually contain one or more options. Each option has a point value. This template contains two sample criteria and their options. Replace the sample text with your own text. For more information, see the ORA documentation." %}
</p> </p>
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
{% endfor %} {% endfor %}
</ul> </ul>
<div id="openassessment_rubric_add_criterion"> <div id="openassessment_rubric_add_criterion" class="openassessment_container_add_button">
<h6> <h6>
{% trans "Add Criterion" %} {% trans "Add Criterion" %}
</h6> </h6>
......
...@@ -33,6 +33,11 @@ ...@@ -33,6 +33,11 @@
<ol id="openassessment_training_example_criterion_template" class="is--hidden"> <ol id="openassessment_training_example_criterion_template" class="is--hidden">
{% include "openassessmentblock/edit/oa_training_example_criterion.html" %} {% include "openassessmentblock/edit/oa_training_example_criterion.html" %}
</ol> </ol>
<ol id="openassessment_training_example_part_template" class="is--hidden">
<li class="openassessment_training_example_essay_part">
<textarea maxlength="100000"></textarea>
</li>
</ol>
</div> </div>
</li> </li>
......
...@@ -28,7 +28,13 @@ ...@@ -28,7 +28,13 @@
<div class="openassessment_training_example_essay_wrapper"> <div class="openassessment_training_example_essay_wrapper">
<h2>{% trans "Response" %}</h2> <h2>{% trans "Response" %}</h2>
<textarea class="openassessment_training_example_essay" maxlength="100000">{{ example.answer }}</textarea> <ol class="openassessment_training_example_essay">
{% for part in example.answer.parts %}
<li class="openassessment_training_example_essay_part">
<textarea maxlength="100000">{{ part.text }}</textarea>
</li>
{% endfor %}
</ol>
</div> </div>
</div> </div>
</li> </li>
......
...@@ -66,7 +66,11 @@ VALID_ASSESSMENT_TYPES = [ ...@@ -66,7 +66,11 @@ VALID_ASSESSMENT_TYPES = [
# Schema definition for an update from the Studio JavaScript editor. # Schema definition for an update from the Studio JavaScript editor.
EDITOR_UPDATE_SCHEMA = Schema({ EDITOR_UPDATE_SCHEMA = Schema({
Required('prompt'): utf8_validator, Required('prompts'): [
Schema({
Required('description'): utf8_validator,
})
],
Required('title'): utf8_validator, Required('title'): utf8_validator,
Required('feedback_prompt'): utf8_validator, Required('feedback_prompt'): utf8_validator,
Required('feedback_default_text'): utf8_validator, Required('feedback_default_text'): utf8_validator,
...@@ -84,7 +88,7 @@ EDITOR_UPDATE_SCHEMA = Schema({ ...@@ -84,7 +88,7 @@ EDITOR_UPDATE_SCHEMA = Schema({
'must_be_graded_by': All(int, Range(min=0)), 'must_be_graded_by': All(int, Range(min=0)),
'examples': [ 'examples': [
Schema({ Schema({
Required('answer'): utf8_validator, Required('answer'): [utf8_validator],
Required('options_selected'): [ Required('options_selected'): [
Schema({ Schema({
Required('criterion'): utf8_validator, Required('criterion'): utf8_validator,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -101,7 +101,18 @@ ...@@ -101,7 +101,18 @@
{ {
"template": "openassessmentblock/student_training/student_training.html", "template": "openassessmentblock/student_training/student_training.html",
"context": { "context": {
"training_essay": "My special essay.", "training_essay": {
"answer": {
"parts": [
{
"prompt": {
"description": "Given the state of the world today, what do you think should be done to combat poverty?"
},
"text": "My special essay."
}
]
}
},
"training_rubric": { "training_rubric": {
"criteria": [ "criteria": [
{ {
...@@ -403,7 +414,7 @@ ...@@ -403,7 +414,7 @@
{ {
"template": "openassessmentblock/edit/oa_edit.html", "template": "openassessmentblock/edit/oa_edit.html",
"context": { "context": {
"prompt": "How much do you like waffles?", "prompts": [{ "description": "How much do you like waffles?" }, { "description": "How much do you like waffles 2?" }],
"title": "The most important of all questions.", "title": "The most important of all questions.",
"submission_start": "2014-01-02T12:15", "submission_start": "2014-01-02T12:15",
"submission_due": "2014-10-01T04:53", "submission_due": "2014-10-01T04:53",
...@@ -484,7 +495,7 @@ ...@@ -484,7 +495,7 @@
{ {
"template": "openassessmentblock/edit/oa_edit.html", "template": "openassessmentblock/edit/oa_edit.html",
"context": { "context": {
"prompt": "Test prompt", "prompts": [{ "description": "How much do you like waffles?" }, { "description": "How much do you like waffles 2?" }],
"title": "Test title", "title": "Test title",
"submission_start": "2014-01-1T10:00:00", "submission_start": "2014-01-1T10:00:00",
"submission_due": "2014-10-1T10:00:00", "submission_due": "2014-10-1T10:00:00",
...@@ -528,7 +539,12 @@ ...@@ -528,7 +539,12 @@
"training": { "training": {
"examples": [ "examples": [
{ {
"answer": "Test answer", "answer": {
"parts": [
{ "text": "Test answer 1"},
{ "text": "Test answer 2"}
]
},
"criteria": [ "criteria": [
{ {
"name": "criterion_with_two_options", "name": "criterion_with_two_options",
...@@ -569,7 +585,12 @@ ...@@ -569,7 +585,12 @@
} }
], ],
"template": { "template": {
"answer": "", "answer": {
"parts": [
{ "text": ""},
{ "text": ""}
]
},
"criteria": [ "criteria": [
{ {
"name": "criterion_with_two_options", "name": "criterion_with_two_options",
......
if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){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 that=this;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()},renderLatex:function(element){element.filter(".allow--latex").each(function(){MathJax.Hub.Queue(["Typeset",MathJax.Hub,this])})},renderContinuedPeer:function(){var view=this;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_username){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_username:student_username}}).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,uuid){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback,submission_uuid:uuid});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,criterionFeedback,overallFeedback){var url=this.url("self_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.")])})})},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,feedback_default_text:kwargs.feedback_default_text,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments,editor_assessments_order:kwargs.editorAssessmentsOrder,allow_file_upload:kwargs.imageSubmissionEnabled,allow_latex:kwargs.latexEnabled,leaderboard_show:kwargs.leaderboardNum});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()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()},cancelSubmission:function(submissionUUID,comments){var url=this.url("cancel_submission");var payload=JSON.stringify({submission_uuid:submissionUUID,comments:comments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The submission could not be removed from the grading pool.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.fileUploader=new OpenAssessment.FileUploader;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this.fileUploader,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.leaderboardView=new OpenAssessment.LeaderboardView(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",this.element),800,{offset:-50})}},setUpCollapseExpand:function(parentSel){parentSel.on("click",".ui-toggle-visibility__control",function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");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();this.leaderboardView.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"}else if(type=="upload"){container="#upload__error"}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.FileUploader=function(){this.upload=function(url,file){return $.Deferred(function(defer){$.ajax({url:url,type:"PUT",data:file,async:false,processData:false,contentType:file.type}).done(function(data,textStatus,jqXHR){Logger.log("openassessment.upload_file",{fileName:file.name,fileSize:file.size,fileType:file.type});defer.resolve()}).fail(function(data,textStatus,jqXHR){defer.rejectWith(this,[textStatus])})}).promise()}};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.server.renderLatex($("#openassessment__grade",view.element));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.LeaderboardView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.LeaderboardView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("leaderboard").done(function(html){$("#openassessment__leaderboard",view.element).replaceWith(html);view.server.renderLatex($("#openassessment__leaderboard",view.element))}).fail(function(errMsg){baseView.showLoadError("leaderboard",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);view.server.renderLatex($("#openassessment__message",view.element))}).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.server.renderLatex($("#openassessment__peer-assessment",view.element));view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;view.continueAssessmentEnabled(false);this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.server.renderLatex($("#openassessment__peer-assessment",view.element));view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment");view.continueAssessmentEnabled(true)})},continueAssessmentEnabled:function(enabled){var button=$("#peer-assessment__continue__grading",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);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()}});sel.find("#peer-assessment__continue__grading").click(function(eventObject){eventObject.preventDefault();view.loadContinuedAssessment()})},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(){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;var uuid=$("#openassessment__peer-assessment").data("submission-uuid");view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.rubric.overallFeedback(),uuid).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})}};OpenAssessment.ResponseView=function(element,server,fileUploader,baseView){this.element=element;this.server=server;this.fileUploader=fileUploader;this.baseView=baseView;this.savedResponse=[];this.files=null;this.imageType=null;this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,MAX_FILE_SIZE:5242880,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.server.renderLatex($("#openassessment__response",view.element));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__part__text__value").on("change keyup drop paste",handleChange);var handlePrepareUpload=function(eventData){view.prepareUpload(eventData.target.files)};sel.find("input[type=file]").on("change",handlePrepareUpload);sel.find("#submission__preview__item").hide();sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()});sel.find("#submission__preview").click(function(eventObject){eventObject.preventDefault();var preview_text=sel.find("#submission__answer__value").val();var preview_container=sel.find("#preview_content");preview_container.html(preview_text.replace(/\r\n|\r|\n/g,"<br />"));sel.find("#submission__preview__item").show();MathJax.Hub.Queue(["Typeset",MathJax.Hub,preview_container[0]])});sel.find("#file__upload").click(function(eventObject){eventObject.preventDefault();$(".submission__answer__display__image",view.element).removeClass("is--hidden");view.fileUpload()})},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)}},previewEnabled:function(enabled){var sel=$("#submission__preview",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(texts){var sel=$(".submission__answer__part__text__value",this.element);if(typeof texts==="undefined"){return sel.map(function(){return $.trim($(this).val())}).get()}else{sel.map(function(index,element){$(this).val(texts[index])})}},responseChanged:function(){var savedResponse=this.savedResponse;return this.response().some(function(element,index,array){return element!==savedResponse[index]})},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isNotBlank=!this.response().every(function(element,index,array){return $.trim(element)==""});this.submitEnabled(isNotBlank);if(this.responseChanged()){this.saveEnabled(isNotBlank);this.previewEnabled(isNotBlank);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();var currentResponseIsEmpty=currentResponse.every(function(element,index,array){return element==""});view.submitEnabled(!currentResponseIsEmpty);var currentResponseEqualsSaved=currentResponse.every(function(element,index,array){return element===savedResponse[index]});if(currentResponseEqualsSaved){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=view.response();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=gettext("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()}})},prepareUpload:function(files){this.files=null;this.imageType=files[0].type;if(files[0].size>this.MAX_FILE_SIZE){this.baseView.toggleActionError("upload",gettext("File size must be 5MB or less."))}else if(this.imageType.substring(0,6)!="image/"){this.baseView.toggleActionError("upload",gettext("File must be an image."))}else{this.baseView.toggleActionError("upload",null);this.files=files}$("#file__upload").toggleClass("is--disabled",this.files===null)},fileUpload:function(){var view=this;var fileUpload=$("#file__upload");fileUpload.addClass("is--disabled");var handleError=function(errMsg){view.baseView.toggleActionError("upload",errMsg);fileUpload.removeClass("is--disabled")};this.server.getUploadUrl(view.imageType).done(function(url){var image=view.files[0];view.fileUploader.upload(url,image).done(function(){view.imageUrl();view.baseView.toggleActionError("upload",null)}).fail(handleError)}).fail(handleError)},imageUrl:function(){var view=this;var image=$("#submission__answer__image",view.element);view.server.getDownloadUrl().done(function(url){image.attr("src",url);return url})}};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},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)}},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){var rubric=this;callback(rubric.canSubmit());$(this.element).on("change keyup drop paste",function(){callback(rubric.canSubmit())})},canSubmit:function(){var numChecked=$("input[type=radio]:checked",this.element).length;var numAvailable=$(".field--radio.assessment__rubric__question.has--options",this.element).length;var completedRequiredComments=true;$("textarea[required]",this.element).each(function(){var trimmedText=$.trim($(this).val());if(trimmedText===""){completedRequiredComments=false}});return numChecked==numAvailable&&completedRequiredComments},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.server.renderLatex($("#openassessment__self-assessment",view.element));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);this.server.selfAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.rubric.overallFeedback()).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};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.server.renderLatex($("#openassessment__staff-info",view.element));view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_username=sel.find("#openassessment__student_username").val();this.server.studentInfo(student_username).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html);var selCancelSub=$("#openassessment__staff-info__cancel__submission",this.element);selCancelSub.on("click","#submit_cancel_submission",function(eventObject){eventObject.preventDefault();view.cancelSubmission($(this).data("submission-uuid"))});var handleChange=function(eventData){view.handleCommentChanged()};selCancelSub.find("#staff-info__cancel-submission__comments").on("change keyup drop paste",handleChange) if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){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 that=this;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()},renderLatex:function(element){element.filter(".allow--latex").each(function(){MathJax.Hub.Queue(["Typeset",MathJax.Hub,this])})},renderContinuedPeer:function(){var view=this;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_username){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_username:student_username}}).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,uuid){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback,submission_uuid:uuid});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,criterionFeedback,overallFeedback){var url=this.url("self_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.")])})})},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({prompts:kwargs.prompts,feedback_prompt:kwargs.feedbackPrompt,feedback_default_text:kwargs.feedback_default_text,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments,editor_assessments_order:kwargs.editorAssessmentsOrder,allow_file_upload:kwargs.imageSubmissionEnabled,allow_latex:kwargs.latexEnabled,leaderboard_show:kwargs.leaderboardNum});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()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()},cancelSubmission:function(submissionUUID,comments){var url=this.url("cancel_submission");var payload=JSON.stringify({submission_uuid:submissionUUID,comments:comments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The submission could not be removed from the grading pool.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.fileUploader=new OpenAssessment.FileUploader;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this.fileUploader,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.leaderboardView=new OpenAssessment.LeaderboardView(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",this.element),800,{offset:-50})}},setUpCollapseExpand:function(parentSel){parentSel.on("click",".ui-toggle-visibility__control",function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");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();this.leaderboardView.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"}else if(type=="upload"){container="#upload__error"}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.FileUploader=function(){this.upload=function(url,file){return $.Deferred(function(defer){$.ajax({url:url,type:"PUT",data:file,async:false,processData:false,contentType:file.type}).done(function(data,textStatus,jqXHR){Logger.log("openassessment.upload_file",{fileName:file.name,fileSize:file.size,fileType:file.type});defer.resolve()}).fail(function(data,textStatus,jqXHR){defer.rejectWith(this,[textStatus])})}).promise()}};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.server.renderLatex($("#openassessment__grade",view.element));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.LeaderboardView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.LeaderboardView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("leaderboard").done(function(html){$("#openassessment__leaderboard",view.element).replaceWith(html);view.server.renderLatex($("#openassessment__leaderboard",view.element))}).fail(function(errMsg){baseView.showLoadError("leaderboard",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);view.server.renderLatex($("#openassessment__message",view.element))}).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.server.renderLatex($("#openassessment__peer-assessment",view.element));view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;view.continueAssessmentEnabled(false);this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.server.renderLatex($("#openassessment__peer-assessment",view.element));view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment");view.continueAssessmentEnabled(true)})},continueAssessmentEnabled:function(enabled){var button=$("#peer-assessment__continue__grading",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);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()}});sel.find("#peer-assessment__continue__grading").click(function(eventObject){eventObject.preventDefault();view.loadContinuedAssessment()})},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(){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;var uuid=$("#openassessment__peer-assessment").data("submission-uuid");view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.rubric.overallFeedback(),uuid).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})}};OpenAssessment.ResponseView=function(element,server,fileUploader,baseView){this.element=element;this.server=server;this.fileUploader=fileUploader;this.baseView=baseView;this.savedResponse=[];this.files=null;this.imageType=null;this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,MAX_FILE_SIZE:5242880,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.server.renderLatex($("#openassessment__response",view.element));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__part__text__value").on("change keyup drop paste",handleChange);var handlePrepareUpload=function(eventData){view.prepareUpload(eventData.target.files)};sel.find("input[type=file]").on("change",handlePrepareUpload);sel.find("#submission__preview__item").hide();sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()});sel.find("#submission__preview").click(function(eventObject){eventObject.preventDefault();var preview_text=sel.find("#submission__answer__value").val();var preview_container=sel.find("#preview_content");preview_container.html(preview_text.replace(/\r\n|\r|\n/g,"<br />"));sel.find("#submission__preview__item").show();MathJax.Hub.Queue(["Typeset",MathJax.Hub,preview_container[0]])});sel.find("#file__upload").click(function(eventObject){eventObject.preventDefault();$(".submission__answer__display__image",view.element).removeClass("is--hidden");view.fileUpload()})},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)}},previewEnabled:function(enabled){var sel=$("#submission__preview",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(texts){var sel=$(".submission__answer__part__text__value",this.element);if(typeof texts==="undefined"){return sel.map(function(){return $.trim($(this).val())}).get()}else{sel.map(function(index,element){$(this).val(texts[index])})}},responseChanged:function(){var savedResponse=this.savedResponse;return this.response().some(function(element,index,array){return element!==savedResponse[index]})},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isNotBlank=!this.response().every(function(element,index,array){return $.trim(element)==""});this.submitEnabled(isNotBlank);if(this.responseChanged()){this.saveEnabled(isNotBlank);this.previewEnabled(isNotBlank);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();var currentResponseIsEmpty=currentResponse.every(function(element,index,array){return element==""});view.submitEnabled(!currentResponseIsEmpty);var currentResponseEqualsSaved=currentResponse.every(function(element,index,array){return element===savedResponse[index]});if(currentResponseEqualsSaved){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=view.response();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=gettext("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()}})},prepareUpload:function(files){this.files=null;this.imageType=files[0].type;if(files[0].size>this.MAX_FILE_SIZE){this.baseView.toggleActionError("upload",gettext("File size must be 5MB or less."))}else if(this.imageType.substring(0,6)!="image/"){this.baseView.toggleActionError("upload",gettext("File must be an image."))}else{this.baseView.toggleActionError("upload",null);this.files=files}$("#file__upload").toggleClass("is--disabled",this.files===null)},fileUpload:function(){var view=this;var fileUpload=$("#file__upload");fileUpload.addClass("is--disabled");var handleError=function(errMsg){view.baseView.toggleActionError("upload",errMsg);fileUpload.removeClass("is--disabled")};this.server.getUploadUrl(view.imageType).done(function(url){var image=view.files[0];view.fileUploader.upload(url,image).done(function(){view.imageUrl();view.baseView.toggleActionError("upload",null)}).fail(handleError)}).fail(handleError)},imageUrl:function(){var view=this;var image=$("#submission__answer__image",view.element);view.server.getDownloadUrl().done(function(url){image.attr("src",url);return url})}};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},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)}},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){var rubric=this;callback(rubric.canSubmit());$(this.element).on("change keyup drop paste",function(){callback(rubric.canSubmit())})},canSubmit:function(){var numChecked=$("input[type=radio]:checked",this.element).length;var numAvailable=$(".field--radio.assessment__rubric__question.has--options",this.element).length;var completedRequiredComments=true;$("textarea[required]",this.element).each(function(){var trimmedText=$.trim($(this).val());if(trimmedText===""){completedRequiredComments=false}});return numChecked==numAvailable&&completedRequiredComments},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.server.renderLatex($("#openassessment__self-assessment",view.element));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);this.server.selfAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.rubric.overallFeedback()).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};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.server.renderLatex($("#openassessment__staff-info",view.element));view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_username=sel.find("#openassessment__student_username").val();this.server.studentInfo(student_username).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html);var selCancelSub=$("#openassessment__staff-info__cancel__submission",this.element);selCancelSub.on("click","#submit_cancel_submission",function(eventObject){eventObject.preventDefault();view.cancelSubmission($(this).data("submission-uuid"))});var handleChange=function(eventData){view.handleCommentChanged()};selCancelSub.find("#staff-info__cancel-submission__comments").on("change keyup drop paste",handleChange)
}).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var selStudentInfo=$("#openassessment__student-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});this.baseView.setUpCollapseExpand(selStudentInfo,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_username").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)})},cancelSubmission:function(submissionUUID){this.cancelSubmissionEnabled(false);var view=this;var sel=$("#openassessment__student-info",this.element);var comments=sel.find("#staff-info__cancel-submission__comments").val();this.server.cancelSubmission(submissionUUID,comments).done(function(msg){$(".cancel-submission-error").html("");$("#openassessment__staff-info__cancel__submission",view.element).html(msg)}).fail(function(errMsg){$(".cancel-submission-error").html(errMsg)})},cancelSubmissionEnabled:function(enabled){var sel=$("#submit_cancel_submission",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},comment:function(text){var sel=$("#staff-info__cancel-submission__comments",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},handleCommentChanged:function(){var isBlank=$.trim(this.comment())!=="";this.cancelSubmissionEnabled(isBlank)}};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.server.renderLatex($("#openassessment__student-training",view.element));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)}}}; }).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var selStudentInfo=$("#openassessment__student-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});this.baseView.setUpCollapseExpand(selStudentInfo,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_username").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)})},cancelSubmission:function(submissionUUID){this.cancelSubmissionEnabled(false);var view=this;var sel=$("#openassessment__student-info",this.element);var comments=sel.find("#staff-info__cancel-submission__comments").val();this.server.cancelSubmission(submissionUUID,comments).done(function(msg){$(".cancel-submission-error").html("");$("#openassessment__staff-info__cancel__submission",view.element).html(msg)}).fail(function(errMsg){$(".cancel-submission-error").html(errMsg)})},cancelSubmissionEnabled:function(enabled){var sel=$("#submit_cancel_submission",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},comment:function(text){var sel=$("#staff-info__cancel-submission__comments",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},handleCommentChanged:function(){var isBlank=$.trim(this.comment())!=="";this.cancelSubmissionEnabled(isBlank)}};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.server.renderLatex($("#openassessment__student-training",view.element));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
if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){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 that=this;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()},renderLatex:function(element){element.filter(".allow--latex").each(function(){MathJax.Hub.Queue(["Typeset",MathJax.Hub,this])})},renderContinuedPeer:function(){var view=this;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_username){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_username:student_username}}).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,uuid){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback,submission_uuid:uuid});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,criterionFeedback,overallFeedback){var url=this.url("self_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.")])})})},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,feedback_default_text:kwargs.feedback_default_text,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments,editor_assessments_order:kwargs.editorAssessmentsOrder,allow_file_upload:kwargs.imageSubmissionEnabled,allow_latex:kwargs.latexEnabled,leaderboard_show:kwargs.leaderboardNum});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()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()},cancelSubmission:function(submissionUUID,comments){var url=this.url("cancel_submission");var payload=JSON.stringify({submission_uuid:submissionUUID,comments:comments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The submission could not be removed from the grading pool.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}OpenAssessment.Container=function(containerItem,kwargs){this.containerElement=kwargs.containerElement;this.templateElement=kwargs.templateElement;this.addButtonElement=kwargs.addButtonElement;this.removeButtonClass=kwargs.removeButtonClass;this.containerItemClass=kwargs.containerItemClass;this.notifier=kwargs.notifier;var container=this;this.createContainerItem=function(element){return new containerItem(element,container.notifier)}};OpenAssessment.Container.prototype={addEventListeners:function(){var container=this;$(this.addButtonElement).click($.proxy(this.add,this));$("."+this.removeButtonClass,this.containerElement).click(function(eventData){var item=container.createContainerItem(eventData.target);container.remove(item)});$("."+this.containerItemClass,this.containerElement).each(function(index,element){var item=container.createContainerItem(element);item.addEventListeners()})},add:function(){$(this.templateElement).children().first().clone().removeAttr("id").toggleClass("is--hidden",false).toggleClass(this.containerItemClass,true).appendTo($(this.containerElement));var container=this;var containerItem=$("."+this.containerItemClass,this.containerElement).last();containerItem.find("."+this.removeButtonClass).click(function(eventData){var containerItem=container.createContainerItem(eventData.target);container.remove(containerItem)});var handlerItem=container.createContainerItem(containerItem);handlerItem.addEventListeners();handlerItem.addHandler()},remove:function(item){var itemElement=$(item.element).closest("."+this.containerItemClass);var containerItem=this.createContainerItem(itemElement);containerItem.removeHandler();itemElement.remove()},getItemValues:function(){var values=[];var container=this;$("."+this.containerItemClass,this.containerElement).each(function(index,element){var containerItem=container.createContainerItem(element);var fieldValues=containerItem.getFieldValues();values.push(fieldValues)});return values},getItem:function(index){var element=$("."+this.containerItemClass,this.containerElement).get(index);return element!==undefined?this.createContainerItem(element):null},getAllItems:function(){var container=this;return $("."+this.containerItemClass,this.containerElement).map(function(){return container.createContainerItem(this)})}};OpenAssessment.ItemUtilities={createUniqueName:function(selector,nameAttribute){var index=0;while(index<=selector.length){if(selector.parent().find("*["+nameAttribute+"='"+index+"']").length===0){return index.toString()}index++}return index.toString()},refreshOptionString:function(element){var points=$(element).attr("data-points");var label=$(element).attr("data-label");var name=$(element).val();if(label===""){label=gettext("Unnamed Option")}var singularString=label+" - "+points+" point";var multipleString=label+" - "+points+" points";var finalLabel="";if(name===""){finalLabel=gettext("Not Selected")}else if(isNaN(points)){finalLabel=label}else{finalLabel=ngettext(singularString,multipleString,points)}$(element).text(finalLabel)}};OpenAssessment.RubricOption=function(element,notifier){this.element=element;this.notifier=notifier;this.pointsField=new OpenAssessment.IntField($(".openassessment_criterion_option_points",this.element),{min:0,max:999})};OpenAssessment.RubricOption.prototype={addEventListeners:function(){$(this.element).focusout($.proxy(this.updateHandler,this))},getFieldValues:function(){var fields={label:this.label(),points:this.points(),explanation:this.explanation()};var nameString=OpenAssessment.Fields.stringField($(".openassessment_criterion_option_name",this.element));if(nameString!==""){fields.name=nameString}return fields},label:function(label){var sel=$(".openassessment_criterion_option_label",this.element);return OpenAssessment.Fields.stringField(sel,label)},points:function(points){if(points!==undefined){this.pointsField.set(points)}return this.pointsField.get()},explanation:function(explanation){var sel=$(".openassessment_criterion_option_explanation",this.element);return OpenAssessment.Fields.stringField(sel,explanation)},addHandler:function(){var criterionElement=$(this.element).closest(".openassessment_criterion");var criterionName=$(criterionElement).data("criterion");var criterionLabel=$(".openassessment_criterion_label",criterionElement).val();var options=$(".openassessment_criterion_option",this.element.parent());var name=OpenAssessment.ItemUtilities.createUniqueName(options,"data-option");$(this.element).attr("data-criterion",criterionName).attr("data-option",name);$(".openassessment_criterion_option_name",this.element).attr("value",name);var fields=this.getFieldValues();this.notifier.notificationFired("optionAdd",{criterionName:criterionName,criterionLabel:criterionLabel,name:name,label:fields.label,points:fields.points})},removeHandler:function(){var criterionName=$(this.element).data("criterion");var optionName=$(this.element).data("option");this.notifier.notificationFired("optionRemove",{criterionName:criterionName,name:optionName})},updateHandler:function(){var fields=this.getFieldValues();var criterionName=$(this.element).data("criterion");var optionName=$(this.element).data("option");var optionLabel=fields.label;var optionPoints=fields.points;this.notifier.notificationFired("optionUpdated",{criterionName:criterionName,name:optionName,label:optionLabel,points:optionPoints})},validate:function(){return this.pointsField.validate()},validationErrors:function(){var hasError=this.pointsField.validationErrors().length>0;return hasError?["Option points are invalid"]:[]},clearValidationErrors:function(){this.pointsField.clearValidationErrors()}};OpenAssessment.RubricCriterion=function(element,notifier){this.element=element;this.notifier=notifier;this.labelSel=$(".openassessment_criterion_label",this.element);this.promptSel=$(".openassessment_criterion_prompt",this.element);this.optionContainer=new OpenAssessment.Container(OpenAssessment.RubricOption,{containerElement:$(".openassessment_criterion_option_list",this.element).get(0),templateElement:$("#openassessment_option_template").get(0),addButtonElement:$(".openassessment_criterion_add_option",this.element).get(0),removeButtonClass:"openassessment_criterion_option_remove_button",containerItemClass:"openassessment_criterion_option",notifier:this.notifier})};OpenAssessment.RubricCriterion.prototype={addEventListeners:function(){this.optionContainer.addEventListeners();$(this.element).focusout($.proxy(this.updateHandler,this))},getFieldValues:function(){var fields={label:this.label(),prompt:this.prompt(),feedback:this.feedback(),options:this.optionContainer.getItemValues()};var nameString=OpenAssessment.Fields.stringField($(".openassessment_criterion_name",this.element));if(nameString!==""){fields.name=nameString}return fields},label:function(label){return OpenAssessment.Fields.stringField(this.labelSel,label)},prompt:function(prompt){return OpenAssessment.Fields.stringField(this.promptSel,prompt)},feedback:function(){return $(".openassessment_criterion_feedback",this.element).val()},addOption:function(){this.optionContainer.add()},addHandler:function(){var criteria=$(".openassessment_criterion",this.element.parent());var name=OpenAssessment.ItemUtilities.createUniqueName(criteria,"data-criterion");$(this.element).attr("data-criterion",name);$(".openassessment_criterion_name",this.element).attr("value",name)},removeHandler:function(){var criterionName=$(this.element).data("criterion");this.notifier.notificationFired("criterionRemove",{criterionName:criterionName})},updateHandler:function(){var fields=this.getFieldValues();var criterionName=fields.name;var criterionLabel=fields.label;this.notifier.notificationFired("criterionUpdated",{criterionName:criterionName,criterionLabel:criterionLabel})},validate:function(){var isValid=this.prompt()!=="";if(!isValid){this.promptSel.addClass("openassessment_highlighted_field")}$.each(this.optionContainer.getAllItems(),function(){isValid=this.validate()&&isValid});return isValid},validationErrors:function(){var errors=[];if(this.promptSel.hasClass("openassessment_highlighted_field")){errors.push("Criterion prompt is invalid.")}$.each(this.optionContainer.getAllItems(),function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){this.promptSel.removeClass("openassessment_highlighted_field");$.each(this.optionContainer.getAllItems(),function(){this.clearValidationErrors()})}};OpenAssessment.TrainingExample=function(element){this.element=element;this.criteria=$(".openassessment_training_example_criterion_option",this.element);this.answer=$(".openassessment_training_example_essay",this.element).first()};OpenAssessment.TrainingExample.prototype={getFieldValues:function(){var optionsSelected=this.criteria.map(function(){return{criterion:$(this).data("criterion"),option:$(this).prop("value")}}).get();return{answer:this.answer.prop("value"),options_selected:optionsSelected}},addHandler:function(){$(".openassessment_training_example_criterion_option",this.element).each(function(){$("option",this).each(function(){OpenAssessment.ItemUtilities.refreshOptionString($(this))})})},addEventListeners:function(){},removeHandler:function(){},updateHandler:function(){},validate:function(){var isValid=true;this.criteria.each(function(){var isOptionValid=$(this).prop("value")!=="";isValid=isOptionValid&&isValid;if(!isOptionValid){$(this).addClass("openassessment_highlighted_field")}});return isValid},validationErrors:function(){var errors=[];this.criteria.each(function(){var hasError=$(this).hasClass("openassessment_highlighted_field");if(hasError){errors.push("Student training example is invalid.")}});return errors},clearValidationErrors:function(){this.criteria.each(function(){$(this).removeClass("openassessment_highlighted_field")})}};OpenAssessment.StudioView=function(runtime,element,server){this.element=element;this.runtime=runtime;this.server=server;this.fixModalHeight();this.initializeTabs();this.alert=(new OpenAssessment.ValidationAlert).install();this.promptView=new OpenAssessment.EditPromptView($("#oa_prompt_editor_wrapper",this.element).get(0));var studentTrainingView=new OpenAssessment.EditStudentTrainingView($("#oa_student_training_editor",this.element).get(0));var peerAssessmentView=new OpenAssessment.EditPeerAssessmentView($("#oa_peer_assessment_editor",this.element).get(0));var selfAssessmentView=new OpenAssessment.EditSelfAssessmentView($("#oa_self_assessment_editor",this.element).get(0));var exampleBasedAssessmentView=new OpenAssessment.EditExampleBasedAssessmentView($("#oa_ai_assessment_editor",this.element).get(0));var assessmentLookupDictionary={};assessmentLookupDictionary[studentTrainingView.getID()]=studentTrainingView;assessmentLookupDictionary[peerAssessmentView.getID()]=peerAssessmentView;assessmentLookupDictionary[selfAssessmentView.getID()]=selfAssessmentView;assessmentLookupDictionary[exampleBasedAssessmentView.getID()]=exampleBasedAssessmentView;this.settingsView=new OpenAssessment.EditSettingsView($("#oa_basic_settings_editor",this.element).get(0),assessmentLookupDictionary);this.rubricView=new OpenAssessment.EditRubricView($("#oa_rubric_editor_wrapper",this.element).get(0),new OpenAssessment.Notifier([new OpenAssessment.StudentTrainingListener]));$(".openassessment_save_button",this.element).click($.proxy(this.save,this));$(".openassessment_cancel_button",this.element).click($.proxy(this.cancel,this))};OpenAssessment.StudioView.prototype={fixModalHeight:function(){$(this.element).addClass("openassessment_full_height").parentsUntil(".modal-window").addClass("openassessment_full_height");$(this.element).closest(".modal-window").addClass("openassessment_modal_window")},initializeTabs:function(){if(typeof OpenAssessment.lastOpenEditingTab==="undefined"){OpenAssessment.lastOpenEditingTab=2}$(".openassessment_editor_content_and_tabs",this.element).tabs({active:OpenAssessment.lastOpenEditingTab})},saveTabState:function(){var tabElement=$(".openassessment_editor_content_and_tabs",this.element);OpenAssessment.lastOpenEditingTab=tabElement.tabs("option","active")},save:function(){var view=this;this.saveTabState();this.clearValidationErrors();if(!this.validate()){this.alert.setMessage(gettext("Couldn't Save This Assignment"),gettext("Please correct the outlined fields.")).show()}else{this.alert.hide();this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})}},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var view=this;this.server.updateEditorContext({prompt:view.promptView.promptText(),feedbackPrompt:view.rubricView.feedbackPrompt(),feedback_default_text:view.rubricView.feedback_default_text(),criteria:view.rubricView.criteriaDefinition(),title:view.settingsView.displayName(),submissionStart:view.settingsView.submissionStart(),submissionDue:view.settingsView.submissionDue(),assessments:view.settingsView.assessmentsDescription(),imageSubmissionEnabled:view.settingsView.imageSubmissionEnabled(),latexEnabled:view.settingsView.latexEnabled(),leaderboardNum:view.settingsView.leaderboardNum(),editorAssessmentsOrder:view.settingsView.editorAssessmentsOrder()}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.saveTabState();this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})},validate:function(){var settingsValid=this.settingsView.validate();var rubricValid=this.rubricView.validate();return settingsValid&&rubricValid},validationErrors:function(){return this.settingsView.validationErrors().concat(this.rubricView.validationErrors())},clearValidationErrors:function(){this.settingsView.clearValidationErrors();this.rubricView.clearValidationErrors()}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server)}OpenAssessment.EditPeerAssessmentView=function(element){this.element=element;this.name="peer-assessment";this.mustGradeField=new OpenAssessment.IntField($("#peer_assessment_must_grade",this.element),{min:0,max:99});this.mustBeGradedByField=new OpenAssessment.IntField($("#peer_assessment_graded_by",this.element),{min:0,max:99});new OpenAssessment.ToggleControl($("#include_peer_assessment",this.element),$("#peer_assessment_settings_editor",this.element),$("#peer_assessment_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install();this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#peer_assessment_start_date","#peer_assessment_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#peer_assessment_due_date","#peer_assessment_due_time").install()};OpenAssessment.EditPeerAssessmentView.prototype={description:function(){return{must_grade:this.mustGradeNum(),must_be_graded_by:this.mustBeGradedByNum(),start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_peer_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_peer_assessment",this.element).click()},mustGradeNum:function(num){if(num!==undefined){this.mustGradeField.set(num)}return this.mustGradeField.get()},mustBeGradedByNum:function(num){if(num!==undefined){this.mustBeGradedByField.set(num)}return this.mustBeGradedByField.get()},startDatetime:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},dueDatetime:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},getID:function(){return $(this.element).attr("id")},validate:function(){var startValid=this.startDatetimeControl.validate();var dueValid=this.dueDatetimeControl.validate();var mustGradeValid=this.mustGradeField.validate();var mustBeGradedByValid=this.mustBeGradedByField.validate();return startValid&&dueValid&&mustGradeValid&&mustBeGradedByValid},validationErrors:function(){var errors=[];if(this.startDatetimeControl.validationErrors().length>0){errors.push("Peer assessment start is invalid")}if(this.dueDatetimeControl.validationErrors().length>0){errors.push("Peer assessment due is invalid")}if(this.mustGradeField.validationErrors().length>0){errors.push("Peer assessment must grade is invalid")}if(this.mustBeGradedByField.validationErrors().length>0){errors.push("Peer assessment must be graded by is invalid")}return errors},clearValidationErrors:function(){this.startDatetimeControl.clearValidationErrors();this.dueDatetimeControl.clearValidationErrors();this.mustGradeField.clearValidationErrors();this.mustBeGradedByField.clearValidationErrors()}};OpenAssessment.EditSelfAssessmentView=function(element){this.element=element;this.name="self-assessment";new OpenAssessment.ToggleControl($("#include_self_assessment",this.element),$("#self_assessment_settings_editor",this.element),$("#self_assessment_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install();this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#self_assessment_start_date","#self_assessment_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#self_assessment_due_date","#self_assessment_due_time").install()};OpenAssessment.EditSelfAssessmentView.prototype={description:function(){return{start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_self_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_self_assessment",this.element).click()},startDatetime:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},dueDatetime:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},getID:function(){return $(this.element).attr("id")},validate:function(){var startValid=this.startDatetimeControl.validate();var dueValid=this.dueDatetimeControl.validate();return startValid&&dueValid},validationErrors:function(){var errors=[];if(this.startDatetimeControl.validationErrors().length>0){errors.push("Self assessment start is invalid")}if(this.dueDatetimeControl.validationErrors().length>0){errors.push("Self assessment due is invalid")}return errors},clearValidationErrors:function(){this.startDatetimeControl.clearValidationErrors();this.dueDatetimeControl.clearValidationErrors()}};OpenAssessment.EditStudentTrainingView=function(element){this.element=element;this.name="student-training";new OpenAssessment.ToggleControl($("#include_student_training",this.element),$("#student_training_settings_editor",this.element),$("#student_training_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install();this.exampleContainer=new OpenAssessment.Container(OpenAssessment.TrainingExample,{containerElement:$("#openassessment_training_example_list",this.element).get(0),templateElement:$("#openassessment_training_example_template",this.element).get(0),addButtonElement:$(".openassessment_add_training_example",this.element).get(0),removeButtonClass:"openassessment_training_example_remove",containerItemClass:"openassessment_training_example"});this.exampleContainer.addEventListeners()};OpenAssessment.EditStudentTrainingView.prototype={description:function(){return{examples:this.exampleContainer.getItemValues()}},isEnabled:function(isEnabled){var sel=$("#include_student_training",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_student_training",this.element).click()},getID:function(){return $(this.element).attr("id")},validate:function(){var isValid=true;$.each(this.exampleContainer.getAllItems(),function(){isValid=this.validate()&&isValid});return isValid},validationErrors:function(){var errors=[];$.each(this.exampleContainer.getAllItems(),function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){$.each(this.exampleContainer.getAllItems(),function(){this.clearValidationErrors()})},addTrainingExample:function(){this.exampleContainer.add()}};OpenAssessment.EditExampleBasedAssessmentView=function(element){this.element=element;this.name="example-based-assessment";new OpenAssessment.ToggleControl($("#include_ai_assessment",this.element),$("#ai_assessment_settings_editor",this.element),$("#ai_assessment_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install()};OpenAssessment.EditExampleBasedAssessmentView.prototype={description:function(){return{examples_xml:this.exampleDefinitions()}},isEnabled:function(isEnabled){var sel=$("#include_ai_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_ai_assessment",this.element).click()},exampleDefinitions:function(xml){var sel=$("#ai_training_examples",this.element);return OpenAssessment.Fields.stringField(sel,xml)},getID:function(){return $(this.element).attr("id")},validate:function(){return true},validationErrors:function(){return[]},clearValidationErrors:function(){}};OpenAssessment.Fields={stringField:function(sel,value){if(value!==undefined){sel.val(value)}return sel.val()},booleanField:function(sel,value){if(value!==undefined){sel.prop("checked",value)}return sel.prop("checked")}};OpenAssessment.IntField=function(inputSel,restrictions){this.max=restrictions.max;this.min=restrictions.min;this.input=$(inputSel)};OpenAssessment.IntField.prototype={get:function(){return parseInt(this.input.val().trim(),10)},set:function(val){this.input.val(val)},validate:function(){var value=this.get();var isValid=!isNaN(value)&&value>=this.min&&value<=this.max;if(this.input.val().indexOf(".")!==-1){isValid=false}if(!isValid){this.input.addClass("openassessment_highlighted_field")}return isValid},clearValidationErrors:function(){this.input.removeClass("openassessment_highlighted_field")},validationErrors:function(){var hasError=this.input.hasClass("openassessment_highlighted_field");return hasError?["Int field is invalid"]:[]}};OpenAssessment.ToggleControl=function(checkboxSel,shownSel,hiddenSel,notifier){this.checkbox=checkboxSel;this.shownSection=shownSel;this.hiddenSection=hiddenSel;this.notifier=notifier};OpenAssessment.ToggleControl.prototype={install:function(checkboxSelector){this.checkbox.change(this,function(event){var control=event.data;if(this.checked){control.notifier.notificationFired("toggleOn",{});control.show()}else{control.notifier.notificationFired("toggleOff",{});control.hide()}});return this},show:function(){this.shownSection.removeClass("is--hidden");this.hiddenSection.addClass("is--hidden")},hide:function(){this.shownSection.addClass("is--hidden");this.hiddenSection.removeClass("is--hidden")}};OpenAssessment.DatetimeControl=function(element,datePicker,timePicker){this.element=element;this.datePicker=datePicker;this.timePicker=timePicker};OpenAssessment.DatetimeControl.prototype={install:function(){var dateString=$(this.datePicker,this.element).val(); if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){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 that=this;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()},renderLatex:function(element){element.filter(".allow--latex").each(function(){MathJax.Hub.Queue(["Typeset",MathJax.Hub,this])})},renderContinuedPeer:function(){var view=this;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_username){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_username:student_username}}).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,uuid){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback,submission_uuid:uuid});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,criterionFeedback,overallFeedback){var url=this.url("self_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.")])})})},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({prompts:kwargs.prompts,feedback_prompt:kwargs.feedbackPrompt,feedback_default_text:kwargs.feedback_default_text,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments,editor_assessments_order:kwargs.editorAssessmentsOrder,allow_file_upload:kwargs.imageSubmissionEnabled,allow_latex:kwargs.latexEnabled,leaderboard_show:kwargs.leaderboardNum});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()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()},cancelSubmission:function(submissionUUID,comments){var url=this.url("cancel_submission");var payload=JSON.stringify({submission_uuid:submissionUUID,comments:comments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The submission could not be removed from the grading pool.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof window.ngetgext==="undefined"){window.ngettext=function(singular_text,plural_text,n){if(n>1){return plural_text}else{return singular_text}}}if(typeof window.Logger==="undefined"){window.Logger={log:function(event_type,data,kwargs){}}}if(typeof window.MathJax==="undefined"){window.MathJax={Hub:{Typeset:function(data){},Queue:function(list){}}}}OpenAssessment.Container=function(containerItem,kwargs){this.containerElement=kwargs.containerElement;this.templateElement=kwargs.templateElement;this.addButtonElement=kwargs.addButtonElement;this.removeButtonClass=kwargs.removeButtonClass;this.containerItemClass=kwargs.containerItemClass;this.notifier=kwargs.notifier;var container=this;this.createContainerItem=function(element){return new containerItem(element,container.notifier)}};OpenAssessment.Container.prototype={addEventListeners:function(){var container=this;$(this.addButtonElement).click($.proxy(this.add,this));$("."+this.removeButtonClass,this.containerElement).click(function(eventData){var item=container.createContainerItem(eventData.target);container.remove(item)});$("."+this.containerItemClass,this.containerElement).each(function(index,element){var item=container.createContainerItem(element);item.addEventListeners()})},add:function(){$(this.templateElement).children().first().clone().removeAttr("id").toggleClass("is--hidden",false).toggleClass(this.containerItemClass,true).appendTo($(this.containerElement));var container=this;var containerItem=$("."+this.containerItemClass,this.containerElement).last();containerItem.find("."+this.removeButtonClass).click(function(eventData){var containerItem=container.createContainerItem(eventData.target);container.remove(containerItem)});var handlerItem=container.createContainerItem(containerItem);handlerItem.addEventListeners();handlerItem.addHandler()},remove:function(item){var itemElement=$(item.element).closest("."+this.containerItemClass);var containerItem=this.createContainerItem(itemElement);containerItem.removeHandler();itemElement.remove()},getItemValues:function(){var values=[];var container=this;$("."+this.containerItemClass,this.containerElement).each(function(index,element){var containerItem=container.createContainerItem(element);var fieldValues=containerItem.getFieldValues();values.push(fieldValues)});return values},getItem:function(index){var element=$("."+this.containerItemClass,this.containerElement).get(index);return element!==undefined?this.createContainerItem(element):null},getAllItems:function(){var container=this;return $("."+this.containerItemClass,this.containerElement).map(function(){return container.createContainerItem(this)})}};OpenAssessment.ItemUtilities={createUniqueName:function(selector,nameAttribute){var index=0;while(index<=selector.length){if(selector.parent().find("*["+nameAttribute+"='"+index+"']").length===0){return index.toString()}index++}return index.toString()},refreshOptionString:function(element){var points=$(element).attr("data-points");var label=$(element).attr("data-label");var name=$(element).val();if(label===""){label=gettext("Unnamed Option")}var singularString=label+" - "+points+" point";var multipleString=label+" - "+points+" points";var finalLabel="";if(name===""){finalLabel=gettext("Not Selected")}else if(isNaN(points)){finalLabel=label}else{finalLabel=ngettext(singularString,multipleString,points)}$(element).text(finalLabel)}};OpenAssessment.Prompt=function(element,notifier){this.element=element;this.notifier=notifier};OpenAssessment.Prompt.prototype={getFieldValues:function(){var fields={description:this.description()};return fields},description:function(text){var sel=$(".openassessment_prompt_description",this.element);return OpenAssessment.Fields.stringField(sel,text)},addEventListeners:function(){},addHandler:function(){this.notifier.notificationFired("promptAdd",{index:this.element.index()})},removeHandler:function(){this.notifier.notificationFired("promptRemove",{index:this.element.index()})},updateHandler:function(){},validate:function(){return true},validationErrors:function(){return[]},clearValidationErrors:function(){}};OpenAssessment.RubricOption=function(element,notifier){this.element=element;this.notifier=notifier;this.pointsField=new OpenAssessment.IntField($(".openassessment_criterion_option_points",this.element),{min:0,max:999})};OpenAssessment.RubricOption.prototype={addEventListeners:function(){$(this.element).focusout($.proxy(this.updateHandler,this))},getFieldValues:function(){var fields={label:this.label(),points:this.points(),explanation:this.explanation()};var nameString=OpenAssessment.Fields.stringField($(".openassessment_criterion_option_name",this.element));if(nameString!==""){fields.name=nameString}return fields},label:function(label){var sel=$(".openassessment_criterion_option_label",this.element);return OpenAssessment.Fields.stringField(sel,label)},points:function(points){if(points!==undefined){this.pointsField.set(points)}return this.pointsField.get()},explanation:function(explanation){var sel=$(".openassessment_criterion_option_explanation",this.element);return OpenAssessment.Fields.stringField(sel,explanation)},addHandler:function(){var criterionElement=$(this.element).closest(".openassessment_criterion");var criterionName=$(criterionElement).data("criterion");var criterionLabel=$(".openassessment_criterion_label",criterionElement).val();var options=$(".openassessment_criterion_option",this.element.parent());var name=OpenAssessment.ItemUtilities.createUniqueName(options,"data-option");$(this.element).attr("data-criterion",criterionName).attr("data-option",name);$(".openassessment_criterion_option_name",this.element).attr("value",name);var fields=this.getFieldValues();this.notifier.notificationFired("optionAdd",{criterionName:criterionName,criterionLabel:criterionLabel,name:name,label:fields.label,points:fields.points})},removeHandler:function(){var criterionName=$(this.element).data("criterion");var optionName=$(this.element).data("option");this.notifier.notificationFired("optionRemove",{criterionName:criterionName,name:optionName})},updateHandler:function(){var fields=this.getFieldValues();var criterionName=$(this.element).data("criterion");var optionName=$(this.element).data("option");var optionLabel=fields.label;var optionPoints=fields.points;this.notifier.notificationFired("optionUpdated",{criterionName:criterionName,name:optionName,label:optionLabel,points:optionPoints})},validate:function(){return this.pointsField.validate()},validationErrors:function(){var hasError=this.pointsField.validationErrors().length>0;return hasError?["Option points are invalid"]:[]},clearValidationErrors:function(){this.pointsField.clearValidationErrors()}};OpenAssessment.RubricCriterion=function(element,notifier){this.element=element;this.notifier=notifier;this.labelSel=$(".openassessment_criterion_label",this.element);this.promptSel=$(".openassessment_criterion_prompt",this.element);this.optionContainer=new OpenAssessment.Container(OpenAssessment.RubricOption,{containerElement:$(".openassessment_criterion_option_list",this.element).get(0),templateElement:$("#openassessment_option_template").get(0),addButtonElement:$(".openassessment_criterion_add_option",this.element).get(0),removeButtonClass:"openassessment_criterion_option_remove_button",containerItemClass:"openassessment_criterion_option",notifier:this.notifier})};OpenAssessment.RubricCriterion.prototype={addEventListeners:function(){this.optionContainer.addEventListeners();$(this.element).focusout($.proxy(this.updateHandler,this))},getFieldValues:function(){var fields={label:this.label(),prompt:this.prompt(),feedback:this.feedback(),options:this.optionContainer.getItemValues()};var nameString=OpenAssessment.Fields.stringField($(".openassessment_criterion_name",this.element));if(nameString!==""){fields.name=nameString}return fields},label:function(label){return OpenAssessment.Fields.stringField(this.labelSel,label)},prompt:function(prompt){return OpenAssessment.Fields.stringField(this.promptSel,prompt)},feedback:function(){return $(".openassessment_criterion_feedback",this.element).val()},addOption:function(){this.optionContainer.add()},addHandler:function(){var criteria=$(".openassessment_criterion",this.element.parent());var name=OpenAssessment.ItemUtilities.createUniqueName(criteria,"data-criterion");$(this.element).attr("data-criterion",name);$(".openassessment_criterion_name",this.element).attr("value",name)},removeHandler:function(){var criterionName=$(this.element).data("criterion");this.notifier.notificationFired("criterionRemove",{criterionName:criterionName})},updateHandler:function(){var fields=this.getFieldValues();var criterionName=fields.name;var criterionLabel=fields.label;this.notifier.notificationFired("criterionUpdated",{criterionName:criterionName,criterionLabel:criterionLabel})},validate:function(){var isValid=this.prompt()!=="";if(!isValid){this.promptSel.addClass("openassessment_highlighted_field")}$.each(this.optionContainer.getAllItems(),function(){isValid=this.validate()&&isValid});return isValid},validationErrors:function(){var errors=[];if(this.promptSel.hasClass("openassessment_highlighted_field")){errors.push("Criterion prompt is invalid.")}$.each(this.optionContainer.getAllItems(),function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){this.promptSel.removeClass("openassessment_highlighted_field");$.each(this.optionContainer.getAllItems(),function(){this.clearValidationErrors()})}};OpenAssessment.TrainingExample=function(element){this.element=element;this.criteria=$(".openassessment_training_example_criterion_option",this.element);this.answer=$(".openassessment_training_example_essay_part textarea",this.element)};OpenAssessment.TrainingExample.prototype={getFieldValues:function(){var optionsSelected=this.criteria.map(function(){return{criterion:$(this).data("criterion"),option:$(this).prop("value")}}).get();return{answer:this.answer.map(function(){return $(this).prop("value")}).get(),options_selected:optionsSelected}},addHandler:function(){$(".openassessment_training_example_criterion_option",this.element).each(function(){$("option",this).each(function(){OpenAssessment.ItemUtilities.refreshOptionString($(this))})})},addEventListeners:function(){},removeHandler:function(){},updateHandler:function(){},validate:function(){var isValid=true;this.criteria.each(function(){var isOptionValid=$(this).prop("value")!=="";isValid=isOptionValid&&isValid;if(!isOptionValid){$(this).addClass("openassessment_highlighted_field")}});return isValid},validationErrors:function(){var errors=[];this.criteria.each(function(){var hasError=$(this).hasClass("openassessment_highlighted_field");if(hasError){errors.push("Student training example is invalid.")}});return errors},clearValidationErrors:function(){this.criteria.each(function(){$(this).removeClass("openassessment_highlighted_field")})}};OpenAssessment.StudioView=function(runtime,element,server){this.element=element;this.runtime=runtime;this.server=server;this.fixModalHeight();this.initializeTabs();this.alert=(new OpenAssessment.ValidationAlert).install();var studentTrainingListener=new OpenAssessment.StudentTrainingListener;this.promptsView=new OpenAssessment.EditPromptsView($("#oa_prompts_editor_wrapper",this.element).get(0),new OpenAssessment.Notifier([studentTrainingListener]));var studentTrainingView=new OpenAssessment.EditStudentTrainingView($("#oa_student_training_editor",this.element).get(0));var peerAssessmentView=new OpenAssessment.EditPeerAssessmentView($("#oa_peer_assessment_editor",this.element).get(0));var selfAssessmentView=new OpenAssessment.EditSelfAssessmentView($("#oa_self_assessment_editor",this.element).get(0));var exampleBasedAssessmentView=new OpenAssessment.EditExampleBasedAssessmentView($("#oa_ai_assessment_editor",this.element).get(0));var assessmentLookupDictionary={};assessmentLookupDictionary[studentTrainingView.getID()]=studentTrainingView;assessmentLookupDictionary[peerAssessmentView.getID()]=peerAssessmentView;assessmentLookupDictionary[selfAssessmentView.getID()]=selfAssessmentView;assessmentLookupDictionary[exampleBasedAssessmentView.getID()]=exampleBasedAssessmentView;this.settingsView=new OpenAssessment.EditSettingsView($("#oa_basic_settings_editor",this.element).get(0),assessmentLookupDictionary);this.rubricView=new OpenAssessment.EditRubricView($("#oa_rubric_editor_wrapper",this.element).get(0),new OpenAssessment.Notifier([studentTrainingListener]));$(".openassessment_save_button",this.element).click($.proxy(this.save,this));$(".openassessment_cancel_button",this.element).click($.proxy(this.cancel,this))};OpenAssessment.StudioView.prototype={fixModalHeight:function(){$(this.element).addClass("openassessment_full_height").parentsUntil(".modal-window").addClass("openassessment_full_height");$(this.element).closest(".modal-window").addClass("openassessment_modal_window")},initializeTabs:function(){if(typeof OpenAssessment.lastOpenEditingTab==="undefined"){OpenAssessment.lastOpenEditingTab=2}$(".openassessment_editor_content_and_tabs",this.element).tabs({active:OpenAssessment.lastOpenEditingTab})},saveTabState:function(){var tabElement=$(".openassessment_editor_content_and_tabs",this.element);OpenAssessment.lastOpenEditingTab=tabElement.tabs("option","active")},save:function(){var view=this;this.saveTabState();this.clearValidationErrors();if(!this.validate()){this.alert.setMessage(gettext("Couldn't Save This Assignment"),gettext("Please correct the outlined fields.")).show()}else{this.alert.hide();this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})}},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var view=this;this.server.updateEditorContext({prompts:view.promptsView.promptsDefinition(),feedbackPrompt:view.rubricView.feedbackPrompt(),feedback_default_text:view.rubricView.feedback_default_text(),criteria:view.rubricView.criteriaDefinition(),title:view.settingsView.displayName(),submissionStart:view.settingsView.submissionStart(),submissionDue:view.settingsView.submissionDue(),assessments:view.settingsView.assessmentsDescription(),imageSubmissionEnabled:view.settingsView.imageSubmissionEnabled(),latexEnabled:view.settingsView.latexEnabled(),leaderboardNum:view.settingsView.leaderboardNum(),editorAssessmentsOrder:view.settingsView.editorAssessmentsOrder()}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.saveTabState();this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})},validate:function(){var settingsValid=this.settingsView.validate();var rubricValid=this.rubricView.validate();var promptsValid=this.promptsView.validate();return settingsValid&&rubricValid&&promptsValid},validationErrors:function(){return this.settingsView.validationErrors().concat(this.rubricView.validationErrors().concat(this.promptsView.validationErrors()))},clearValidationErrors:function(){this.settingsView.clearValidationErrors();this.rubricView.clearValidationErrors();this.promptsView.clearValidationErrors()}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server)}OpenAssessment.EditPeerAssessmentView=function(element){this.element=element;this.name="peer-assessment";this.mustGradeField=new OpenAssessment.IntField($("#peer_assessment_must_grade",this.element),{min:0,max:99});this.mustBeGradedByField=new OpenAssessment.IntField($("#peer_assessment_graded_by",this.element),{min:0,max:99});new OpenAssessment.ToggleControl($("#include_peer_assessment",this.element),$("#peer_assessment_settings_editor",this.element),$("#peer_assessment_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install();this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#peer_assessment_start_date","#peer_assessment_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#peer_assessment_due_date","#peer_assessment_due_time").install()};OpenAssessment.EditPeerAssessmentView.prototype={description:function(){return{must_grade:this.mustGradeNum(),must_be_graded_by:this.mustBeGradedByNum(),start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_peer_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_peer_assessment",this.element).click()},mustGradeNum:function(num){if(num!==undefined){this.mustGradeField.set(num)}return this.mustGradeField.get()},mustBeGradedByNum:function(num){if(num!==undefined){this.mustBeGradedByField.set(num)}return this.mustBeGradedByField.get()},startDatetime:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},dueDatetime:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},getID:function(){return $(this.element).attr("id")},validate:function(){var startValid=this.startDatetimeControl.validate();var dueValid=this.dueDatetimeControl.validate();var mustGradeValid=this.mustGradeField.validate();var mustBeGradedByValid=this.mustBeGradedByField.validate();return startValid&&dueValid&&mustGradeValid&&mustBeGradedByValid},validationErrors:function(){var errors=[];if(this.startDatetimeControl.validationErrors().length>0){errors.push("Peer assessment start is invalid")}if(this.dueDatetimeControl.validationErrors().length>0){errors.push("Peer assessment due is invalid")}if(this.mustGradeField.validationErrors().length>0){errors.push("Peer assessment must grade is invalid")}if(this.mustBeGradedByField.validationErrors().length>0){errors.push("Peer assessment must be graded by is invalid")}return errors},clearValidationErrors:function(){this.startDatetimeControl.clearValidationErrors();this.dueDatetimeControl.clearValidationErrors();this.mustGradeField.clearValidationErrors();this.mustBeGradedByField.clearValidationErrors()}};OpenAssessment.EditSelfAssessmentView=function(element){this.element=element;this.name="self-assessment";new OpenAssessment.ToggleControl($("#include_self_assessment",this.element),$("#self_assessment_settings_editor",this.element),$("#self_assessment_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install();this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#self_assessment_start_date","#self_assessment_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#self_assessment_due_date","#self_assessment_due_time").install()};OpenAssessment.EditSelfAssessmentView.prototype={description:function(){return{start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_self_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_self_assessment",this.element).click()},startDatetime:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},dueDatetime:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},getID:function(){return $(this.element).attr("id")},validate:function(){var startValid=this.startDatetimeControl.validate();var dueValid=this.dueDatetimeControl.validate();return startValid&&dueValid},validationErrors:function(){var errors=[];if(this.startDatetimeControl.validationErrors().length>0){errors.push("Self assessment start is invalid")}if(this.dueDatetimeControl.validationErrors().length>0){errors.push("Self assessment due is invalid")}return errors},clearValidationErrors:function(){this.startDatetimeControl.clearValidationErrors();this.dueDatetimeControl.clearValidationErrors()}};OpenAssessment.EditStudentTrainingView=function(element){this.element=element;this.name="student-training";new OpenAssessment.ToggleControl($("#include_student_training",this.element),$("#student_training_settings_editor",this.element),$("#student_training_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install();this.exampleContainer=new OpenAssessment.Container(OpenAssessment.TrainingExample,{containerElement:$("#openassessment_training_example_list",this.element).get(0),templateElement:$("#openassessment_training_example_template",this.element).get(0),addButtonElement:$(".openassessment_add_training_example",this.element).get(0),removeButtonClass:"openassessment_training_example_remove",containerItemClass:"openassessment_training_example"});this.exampleContainer.addEventListeners()};OpenAssessment.EditStudentTrainingView.prototype={description:function(){return{examples:this.exampleContainer.getItemValues()}},isEnabled:function(isEnabled){var sel=$("#include_student_training",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_student_training",this.element).click()},getID:function(){return $(this.element).attr("id")},validate:function(){var isValid=true;$.each(this.exampleContainer.getAllItems(),function(){isValid=this.validate()&&isValid});return isValid},validationErrors:function(){var errors=[];$.each(this.exampleContainer.getAllItems(),function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){$.each(this.exampleContainer.getAllItems(),function(){this.clearValidationErrors()})},addTrainingExample:function(){this.exampleContainer.add()}};OpenAssessment.EditExampleBasedAssessmentView=function(element){this.element=element;this.name="example-based-assessment";new OpenAssessment.ToggleControl($("#include_ai_assessment",this.element),$("#ai_assessment_settings_editor",this.element),$("#ai_assessment_description_closed",this.element),new OpenAssessment.Notifier([new OpenAssessment.AssessmentToggleListener])).install()};OpenAssessment.EditExampleBasedAssessmentView.prototype={description:function(){return{examples_xml:this.exampleDefinitions()}},isEnabled:function(isEnabled){var sel=$("#include_ai_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},toggleEnabled:function(){$("#include_ai_assessment",this.element).click()},exampleDefinitions:function(xml){var sel=$("#ai_training_examples",this.element);return OpenAssessment.Fields.stringField(sel,xml)},getID:function(){return $(this.element).attr("id")},validate:function(){return true},validationErrors:function(){return[]},clearValidationErrors:function(){}};OpenAssessment.Fields={stringField:function(sel,value){if(value!==undefined){sel.val(value)}return sel.val()},booleanField:function(sel,value){if(value!==undefined){sel.prop("checked",value)}return sel.prop("checked")}};OpenAssessment.IntField=function(inputSel,restrictions){this.max=restrictions.max;this.min=restrictions.min;this.input=$(inputSel)};OpenAssessment.IntField.prototype={get:function(){return parseInt(this.input.val().trim(),10)},set:function(val){this.input.val(val)},validate:function(){var value=this.get();var isValid=!isNaN(value)&&value>=this.min&&value<=this.max;if(this.input.val().indexOf(".")!==-1){isValid=false}if(!isValid){this.input.addClass("openassessment_highlighted_field")}return isValid},clearValidationErrors:function(){this.input.removeClass("openassessment_highlighted_field")},validationErrors:function(){var hasError=this.input.hasClass("openassessment_highlighted_field");
$(this.datePicker,this.element).datepicker({showButtonPanel:true}).datepicker("option","dateFormat","yy-mm-dd").datepicker("setDate",dateString);$(this.timePicker,this.element).timepicker({timeFormat:"H:i",step:60});return this},datetime:function(dateString,timeString){var datePickerSel=$(this.datePicker,this.element);var timePickerSel=$(this.timePicker,this.element);if(typeof dateString!=="undefined"){datePickerSel.val(dateString)}if(typeof timeString!=="undefined"){timePickerSel.val(timeString)}return datePickerSel.val()+"T"+timePickerSel.val()},validate:function(){var dateString=$(this.datePicker,this.element).val();var timeString=$(this.timePicker,this.element).val();var isDateValid=false;try{var parsedDate=$.datepicker.parseDate($.datepicker.ISO_8601,dateString);isDateValid=parsedDate instanceof Date}catch(err){}if(!isDateValid){$(this.datePicker,this.element).addClass("openassessment_highlighted_field")}var matches=timeString.match(/^\d{2}:\d{2}$/g);var isTimeValid=matches!==null;if(!isTimeValid){$(this.timePicker,this.element).addClass("openassessment_highlighted_field")}return isDateValid&&isTimeValid},clearValidationErrors:function(){$(this.datePicker,this.element).removeClass("openassessment_highlighted_field");$(this.timePicker,this.element).removeClass("openassessment_highlighted_field")},validationErrors:function(){var errors=[];var dateHasError=$(this.datePicker,this.element).hasClass("openassessment_highlighted_field");var timeHasError=$(this.timePicker,this.element).hasClass("openassessment_highlighted_field");if(dateHasError){errors.push("Date is invalid")}if(timeHasError){errors.push("Time is invalid")}return errors}};OpenAssessment.StudentTrainingListener=function(){this.element=$("#oa_student_training_editor");this.alert=new OpenAssessment.ValidationAlert};OpenAssessment.StudentTrainingListener.prototype={optionUpdated:function(data){this._optionSel(data.criterionName).each(function(){var criterion=this;var option=$('option[value="'+data.name+'"]',criterion).attr("data-points",data.points).attr("data-label",data.label);OpenAssessment.ItemUtilities.refreshOptionString(option)})},optionAdd:function(data){var criterionAdded=false;if(this._optionSel(data.criterionName).length===0){this.criterionAdd(data);criterionAdded=true}this._optionSel(data.criterionName).each(function(){var criterion=this;var option=$("<option></option>").attr("value",data.name).attr("data-points",data.points).attr("data-label",data.label);OpenAssessment.ItemUtilities.refreshOptionString(option);$(criterion).append(option)});if(criterionAdded){this.displayAlertMsg(gettext("Criterion Added"),gettext("You've added a criterion. You'll need to select an option for the criterion in the Student Training step. To do this, click the Settings tab."))}},optionRemove:function(data){var handler=this;var invalidated=false;this._optionSel(data.criterionName).each(function(){var criterionOption=this;if($(criterionOption).val()===data.name.toString()){$(criterionOption).val("").addClass("openassessment_highlighted_field").click(function(){$(criterionOption).removeClass("openassessment_highlighted_field")});invalidated=true}$('option[value="'+data.name+'"]',criterionOption).remove();if($("option",criterionOption).length==1){handler.removeAllOptions(data);invalidated=false}});if(invalidated){this.displayAlertMsg(gettext("Option Deleted"),gettext("You've deleted an option. The system has removed that option from its criterion in the sample responses in the Student Training step. You may have to select a new option for the criterion."))}},_optionSel:function(criterionName){return $('.openassessment_training_example_criterion_option[data-criterion="'+criterionName+'"]',this.element)},removeAllOptions:function(data){var changed=false;$(".openassessment_training_example_criterion",this.element).each(function(){var criterion=this;if($(criterion).data("criterion")==data.criterionName){$(criterion).remove();changed=true}});if(changed){this.displayAlertMsg(gettext("Option Deleted"),gettext("You've deleted all the options for this criterion. The system has removed the criterion from the sample responses in the Student Training step."))}},criterionRemove:function(data){var changed=false;var sel='.openassessment_training_example_criterion[data-criterion="'+data.criterionName+'"]';$(sel,this.element).each(function(){$(this).remove();changed=true});if(changed){this.displayAlertMsg(gettext("Criterion Deleted"),gettext("You've deleted a criterion. The system has removed the criterion from the sample responses in the Student Training step."))}},displayAlertMsg:function(title,msg){if($("#include_student_training",this.element).is(":checked")&&$(".openassessment_training_example",this.element).length>1){this.alert.setMessage(title,msg).show()}},criterionUpdated:function(data){var sel='.openassessment_training_example_criterion[data-criterion="'+data.criterionName+'"]';$(sel,this.element).each(function(){$(".openassessment_training_example_criterion_name_wrapper",this).text(data.criterionLabel)})},criterionAdd:function(data){var view=this.element;var criterion=$("#openassessment_training_example_criterion_template").children().first().clone().removeAttr("id").attr("data-criterion",data.criterionName).toggleClass("is--hidden",false).appendTo(".openassessment_training_example_criteria_selections",view);criterion.find(".openassessment_training_example_criterion_option").attr("data-criterion",data.criterionName);criterion.find(".openassessment_training_example_criterion_name_wrapper").text(data.label)},examplesCriteriaLabels:function(){var examples=[];$(".openassessment_training_example_criteria_selections",this.element).each(function(){var exampleDescription={};$(".openassessment_training_example_criterion",this).each(function(){var criterionName=$(this).data("criterion");var criterionLabel=$(".openassessment_training_example_criterion_name_wrapper",this).text().trim();exampleDescription[criterionName]=criterionLabel});examples.push(exampleDescription)});return examples},examplesOptionsLabels:function(){var examples=[];$(".openassessment_training_example_criteria_selections",this.element).each(function(){var exampleDescription={};$(".openassessment_training_example_criterion_option",this).each(function(){var criterionName=$(this).data("criterion");exampleDescription[criterionName]={};$("option",this).each(function(){var optionName=$(this).val();var optionLabel=$(this).text().trim();exampleDescription[criterionName][optionName]=optionLabel})});examples.push(exampleDescription)});return examples}};OpenAssessment.AssessmentToggleListener=function(){this.alert=new OpenAssessment.ValidationAlert};OpenAssessment.AssessmentToggleListener.prototype={toggleOff:function(data){this.alert.setMessage(gettext("Warning"),gettext("Changes to steps that are not selected as part of the assignment will not be saved.")).show()},toggleOn:function(data){this.alert.hide()}};OpenAssessment.Notifier=function(listeners){this.listeners=listeners};OpenAssessment.Notifier.prototype={notificationFired:function(name,data){for(var i=0;i<this.listeners.length;i++){if(typeof this.listeners[i][name]==="function"){this.listeners[i][name](data)}}}};OpenAssessment.EditPromptView=function(element){this.element=element};OpenAssessment.EditPromptView.prototype={promptText:function(text){var sel=$("#openassessment_prompt_editor",this.element);return OpenAssessment.Fields.stringField(sel,text)}};OpenAssessment.EditRubricView=function(element,notifier){this.element=element;this.criterionAddButton=$("#openassessment_rubric_add_criterion",this.element);this.criteriaContainer=new OpenAssessment.Container(OpenAssessment.RubricCriterion,{containerElement:$("#openassessment_criterion_list",this.element).get(0),templateElement:$("#openassessment_criterion_template",this.element).get(0),addButtonElement:$("#openassessment_rubric_add_criterion",this.element).get(0),removeButtonClass:"openassessment_criterion_remove_button",containerItemClass:"openassessment_criterion",notifier:notifier});this.criteriaContainer.addEventListeners()};OpenAssessment.EditRubricView.prototype={criteriaDefinition:function(){var criteria=this.criteriaContainer.getItemValues();for(var criterion_idx=0;criterion_idx<criteria.length;criterion_idx++){var criterion=criteria[criterion_idx];criterion.order_num=criterion_idx;for(var option_idx=0;option_idx<criterion.options.length;option_idx++){var option=criterion.options[option_idx];option.order_num=option_idx}}return criteria},feedbackPrompt:function(text){var sel=$("#openassessment_rubric_feedback",this.element);return OpenAssessment.Fields.stringField(sel,text)},feedback_default_text:function(text){var sel=$("#openassessment_rubric_feedback_default_text",this.element);return OpenAssessment.Fields.stringField(sel,text)},addCriterion:function(){this.criteriaContainer.add()},removeCriterion:function(item){this.criteriaContainer.remove(item)},getAllCriteria:function(){return this.criteriaContainer.getAllItems()},getCriterionItem:function(index){return this.criteriaContainer.getItem(index)},addOption:function(criterionIndex){var criterionItem=this.getCriterionItem(criterionIndex);criterionItem.optionContainer.add()},removeOption:function(criterionIndex,item){var criterionItem=this.getCriterionItem(criterionIndex);criterionItem.optionContainer.remove(item)},getAllOptions:function(criterionIndex){var criterionItem=this.getCriterionItem(criterionIndex);return criterionItem.optionContainer.getAllItems()},getOptionItem:function(criterionIndex,optionIndex){var criterionItem=this.getCriterionItem(criterionIndex);return criterionItem.optionContainer.getItem(optionIndex)},validate:function(){var criteria=this.getAllCriteria();var isValid=criteria.length>0;if(!isValid){this.criterionAddButton.addClass("openassessment_highlighted_field").click(function(){$(this).removeClass("openassessment_highlighted_field")})}$.each(criteria,function(){isValid=this.validate()&&isValid});return isValid},validationErrors:function(){var errors=[];if(this.criterionAddButton.hasClass("openassessment_highlighted_field")){errors.push("The rubric must contain at least one criterion")}$.each(this.getAllCriteria(),function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){this.criterionAddButton.removeClass("openassessment_highlighted_field");$.each(this.getAllCriteria(),function(){this.clearValidationErrors()})}};OpenAssessment.EditSettingsView=function(element,assessmentViews){this.settingsElement=element;this.assessmentsElement=$(element).siblings("#openassessment_assessment_module_settings_editors").get(0);this.assessmentViews=assessmentViews;this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#openassessment_submission_start_date","#openassessment_submission_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#openassessment_submission_due_date","#openassessment_submission_due_time").install();this.leaderboardIntField=new OpenAssessment.IntField($("#openassessment_leaderboard_editor",this.element),{min:0,max:100});this.initializeSortableAssessments()};OpenAssessment.EditSettingsView.prototype={initializeSortableAssessments:function(){var view=this;$("#openassessment_assessment_module_settings_editors",view.element).sortable({start:function(event,ui){$(".openassessment_assessment_module_editor",view.element).hide();var targetHeight="auto";ui.placeholder.height(targetHeight);ui.helper.height(targetHeight);$("#openassessment_assessment_module_settings_editors",view.element).sortable("refresh").sortable("refreshPositions")},stop:function(event,ui){$(".openassessment_assessment_module_editor",view.element).show()},snap:true,axis:"y",handle:".drag-handle",cursorAt:{top:20}});$("#openassessment_assessment_module_settings_editors .drag-handle",view.element).disableSelection()},displayName:function(name){var sel=$("#openassessment_title_editor",this.settingsElement);return OpenAssessment.Fields.stringField(sel,name)},submissionStart:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},submissionDue:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},imageSubmissionEnabled:function(isEnabled){var sel=$("#openassessment_submission_image_editor",this.settingsElement);if(isEnabled!==undefined){if(isEnabled){sel.val(1)}else{sel.val(0)}}return sel.val()==1},latexEnabled:function(isEnabled){var sel=$("#openassessment_submission_latex_editor",this.settingsElement);if(isEnabled!==undefined){if(isEnabled){sel.val(1)}else{sel.val(0)}}return sel.val()==1},leaderboardNum:function(num){if(num!==undefined){this.leaderboardIntField.set(num)}return this.leaderboardIntField.get(num)},assessmentsDescription:function(){var assessmentDescList=[];var view=this;$(".openassessment_assessment_module_settings_editor",this.assessmentsElement).each(function(){var asmntView=view.assessmentViews[$(this).attr("id")];if(asmntView.isEnabled()){var description=asmntView.description();description["name"]=asmntView.name;assessmentDescList.push(description)}});return assessmentDescList},editorAssessmentsOrder:function(){var editorAssessments=[];var view=this;$(".openassessment_assessment_module_settings_editor",this.assessmentsElement).each(function(){var asmntView=view.assessmentViews[$(this).attr("id")];editorAssessments.push(asmntView.name)});return editorAssessments},validate:function(){var isValid=true;isValid=this.startDatetimeControl.validate()&&isValid;isValid=this.dueDatetimeControl.validate()&&isValid;isValid=this.leaderboardIntField.validate()&&isValid;$.each(this.assessmentViews,function(){if(this.isEnabled()){isValid=this.validate()&&isValid}});return isValid},validationErrors:function(){var errors=[];if(this.startDatetimeControl.validationErrors().length>0){errors.push("Submission start is invalid")}if(this.dueDatetimeControl.validationErrors().length>0){errors.push("Submission due is invalid")}if(this.leaderboardIntField.validationErrors().length>0){errors.push("Leaderboard number is invalid")}$.each(this.assessmentViews,function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){this.startDatetimeControl.clearValidationErrors();this.dueDatetimeControl.clearValidationErrors();this.leaderboardIntField.clearValidationErrors();$.each(this.assessmentViews,function(){this.clearValidationErrors()})}};OpenAssessment.ValidationAlert=function(){this.element=$("#openassessment_validation_alert");this.editorElement=$(this.element).parent();this.title=$(".openassessment_alert_title",this.element);this.message=$(".openassessment_alert_message",this.element);this.closeButton=$(".openassessment_alert_close",this.element);this.ALERT_YELLOW="rgb(192, 172, 0)";this.DARK_GREY="#323232"};OpenAssessment.ValidationAlert.prototype={install:function(){var alert=this;this.closeButton.click(function(eventObject){eventObject.preventDefault();alert.hide()});return this},hide:function(){var headerHeight=$("#openassessment_editor_header",this.editorElement).outerHeight();this.element.addClass("covered");var styles={height:"Calc(100% - "+headerHeight+"px)","border-top-right-radius":"3px","border-top-left-radius":"3px"};$(".oa_editor_content_wrapper",this.editorElement).each(function(){$(this).css(styles)});return this},show:function(){var view=this;if(this.isVisible()){$(this.element).animate({"background-color":view.ALERT_YELLOW},300,"swing",function(){$(this).animate({"background-color":view.DARK_GREY},700,"swing")})}else{this.element.removeClass("covered");var alertHeight=this.element.outerHeight();var headerHeight=$("#openassessment_editor_header",this.editorElement).outerHeight();var heightString="Calc(100% - "+(alertHeight+headerHeight)+"px)";var styles={height:heightString,"border-top-right-radius":"0px","border-top-left-radius":"0px"};$(".oa_editor_content_wrapper",this.editorElement).each(function(){$(this).css(styles)})}return this},setMessage:function(newTitle,newMessage){this.title.text(newTitle);this.message.text(newMessage);return this},isVisible:function(){return!this.element.hasClass("covered")},getTitle:function(){return this.title.text()},getMessage:function(){return this.message.text()}}; return hasError?["Int field is invalid"]:[]}};OpenAssessment.ToggleControl=function(checkboxSel,shownSel,hiddenSel,notifier){this.checkbox=checkboxSel;this.shownSection=shownSel;this.hiddenSection=hiddenSel;this.notifier=notifier};OpenAssessment.ToggleControl.prototype={install:function(checkboxSelector){this.checkbox.change(this,function(event){var control=event.data;if(this.checked){control.notifier.notificationFired("toggleOn",{});control.show()}else{control.notifier.notificationFired("toggleOff",{});control.hide()}});return this},show:function(){this.shownSection.removeClass("is--hidden");this.hiddenSection.addClass("is--hidden")},hide:function(){this.shownSection.addClass("is--hidden");this.hiddenSection.removeClass("is--hidden")}};OpenAssessment.DatetimeControl=function(element,datePicker,timePicker){this.element=element;this.datePicker=datePicker;this.timePicker=timePicker};OpenAssessment.DatetimeControl.prototype={install:function(){var dateString=$(this.datePicker,this.element).val();$(this.datePicker,this.element).datepicker({showButtonPanel:true}).datepicker("option","dateFormat","yy-mm-dd").datepicker("setDate",dateString);$(this.timePicker,this.element).timepicker({timeFormat:"H:i",step:60});return this},datetime:function(dateString,timeString){var datePickerSel=$(this.datePicker,this.element);var timePickerSel=$(this.timePicker,this.element);if(typeof dateString!=="undefined"){datePickerSel.val(dateString)}if(typeof timeString!=="undefined"){timePickerSel.val(timeString)}return datePickerSel.val()+"T"+timePickerSel.val()},validate:function(){var dateString=$(this.datePicker,this.element).val();var timeString=$(this.timePicker,this.element).val();var isDateValid=false;try{var parsedDate=$.datepicker.parseDate($.datepicker.ISO_8601,dateString);isDateValid=parsedDate instanceof Date}catch(err){}if(!isDateValid){$(this.datePicker,this.element).addClass("openassessment_highlighted_field")}var matches=timeString.match(/^\d{2}:\d{2}$/g);var isTimeValid=matches!==null;if(!isTimeValid){$(this.timePicker,this.element).addClass("openassessment_highlighted_field")}return isDateValid&&isTimeValid},clearValidationErrors:function(){$(this.datePicker,this.element).removeClass("openassessment_highlighted_field");$(this.timePicker,this.element).removeClass("openassessment_highlighted_field")},validationErrors:function(){var errors=[];var dateHasError=$(this.datePicker,this.element).hasClass("openassessment_highlighted_field");var timeHasError=$(this.timePicker,this.element).hasClass("openassessment_highlighted_field");if(dateHasError){errors.push("Date is invalid")}if(timeHasError){errors.push("Time is invalid")}return errors}};OpenAssessment.StudentTrainingListener=function(){this.element=$("#oa_student_training_editor");this.alert=new OpenAssessment.ValidationAlert};OpenAssessment.StudentTrainingListener.prototype={promptAdd:function(data){var view=this.element;var essay_part=$("#openassessment_training_example_part_template").children().first().clone().removeAttr("id").toggleClass("is--hidden",false).appendTo(".openassessment_training_example_essay",view)},promptRemove:function(data){var view=this.element;$(".openassessment_training_example_essay li:nth-child("+(data.index+1)+")",view).remove()},optionUpdated:function(data){this._optionSel(data.criterionName).each(function(){var criterion=this;var option=$('option[value="'+data.name+'"]',criterion).attr("data-points",data.points).attr("data-label",data.label);OpenAssessment.ItemUtilities.refreshOptionString(option)})},optionAdd:function(data){var criterionAdded=false;if(this._optionSel(data.criterionName).length===0){this.criterionAdd(data);criterionAdded=true}this._optionSel(data.criterionName).each(function(){var criterion=this;var option=$("<option></option>").attr("value",data.name).attr("data-points",data.points).attr("data-label",data.label);OpenAssessment.ItemUtilities.refreshOptionString(option);$(criterion).append(option)});if(criterionAdded){this.displayAlertMsg(gettext("Criterion Added"),gettext("You've added a criterion. You'll need to select an option for the criterion in the Student Training step. To do this, click the Settings tab."))}},optionRemove:function(data){var handler=this;var invalidated=false;this._optionSel(data.criterionName).each(function(){var criterionOption=this;if($(criterionOption).val()===data.name.toString()){$(criterionOption).val("").addClass("openassessment_highlighted_field").click(function(){$(criterionOption).removeClass("openassessment_highlighted_field")});invalidated=true}$('option[value="'+data.name+'"]',criterionOption).remove();if($("option",criterionOption).length==1){handler.removeAllOptions(data);invalidated=false}});if(invalidated){this.displayAlertMsg(gettext("Option Deleted"),gettext("You've deleted an option. The system has removed that option from its criterion in the sample responses in the Student Training step. You may have to select a new option for the criterion."))}},_optionSel:function(criterionName){return $('.openassessment_training_example_criterion_option[data-criterion="'+criterionName+'"]',this.element)},removeAllOptions:function(data){var changed=false;$(".openassessment_training_example_criterion",this.element).each(function(){var criterion=this;if($(criterion).data("criterion")==data.criterionName){$(criterion).remove();changed=true}});if(changed){this.displayAlertMsg(gettext("Option Deleted"),gettext("You've deleted all the options for this criterion. The system has removed the criterion from the sample responses in the Student Training step."))}},criterionRemove:function(data){var changed=false;var sel='.openassessment_training_example_criterion[data-criterion="'+data.criterionName+'"]';$(sel,this.element).each(function(){$(this).remove();changed=true});if(changed){this.displayAlertMsg(gettext("Criterion Deleted"),gettext("You've deleted a criterion. The system has removed the criterion from the sample responses in the Student Training step."))}},displayAlertMsg:function(title,msg){if($("#include_student_training",this.element).is(":checked")&&$(".openassessment_training_example",this.element).length>1){this.alert.setMessage(title,msg).show()}},criterionUpdated:function(data){var sel='.openassessment_training_example_criterion[data-criterion="'+data.criterionName+'"]';$(sel,this.element).each(function(){$(".openassessment_training_example_criterion_name_wrapper",this).text(data.criterionLabel)})},criterionAdd:function(data){var view=this.element;var criterion=$("#openassessment_training_example_criterion_template").children().first().clone().removeAttr("id").attr("data-criterion",data.criterionName).toggleClass("is--hidden",false).appendTo(".openassessment_training_example_criteria_selections",view);criterion.find(".openassessment_training_example_criterion_option").attr("data-criterion",data.criterionName);criterion.find(".openassessment_training_example_criterion_name_wrapper").text(data.label)},examplesCriteriaLabels:function(){var examples=[];$(".openassessment_training_example_criteria_selections",this.element).each(function(){var exampleDescription={};$(".openassessment_training_example_criterion",this).each(function(){var criterionName=$(this).data("criterion");var criterionLabel=$(".openassessment_training_example_criterion_name_wrapper",this).text().trim();exampleDescription[criterionName]=criterionLabel});examples.push(exampleDescription)});return examples},examplesOptionsLabels:function(){var examples=[];$(".openassessment_training_example_criteria_selections",this.element).each(function(){var exampleDescription={};$(".openassessment_training_example_criterion_option",this).each(function(){var criterionName=$(this).data("criterion");exampleDescription[criterionName]={};$("option",this).each(function(){var optionName=$(this).val();var optionLabel=$(this).text().trim();exampleDescription[criterionName][optionName]=optionLabel})});examples.push(exampleDescription)});return examples}};OpenAssessment.AssessmentToggleListener=function(){this.alert=new OpenAssessment.ValidationAlert};OpenAssessment.AssessmentToggleListener.prototype={toggleOff:function(data){this.alert.setMessage(gettext("Warning"),gettext("Changes to steps that are not selected as part of the assignment will not be saved.")).show()},toggleOn:function(data){this.alert.hide()}};OpenAssessment.Notifier=function(listeners){this.listeners=listeners};OpenAssessment.Notifier.prototype={notificationFired:function(name,data){for(var i=0;i<this.listeners.length;i++){if(typeof this.listeners[i][name]==="function"){this.listeners[i][name](data)}}}};OpenAssessment.EditPromptsView=function(element,notifier){this.element=element;this.promptsContainer=new OpenAssessment.Container(OpenAssessment.Prompt,{containerElement:$("#openassessment_prompts_list",this.element).get(0),templateElement:$("#openassessment_prompt_template",this.element).get(0),addButtonElement:$("#openassessment_prompts_add_prompt",this.element).get(0),removeButtonClass:"openassessment_prompt_remove_button",containerItemClass:"openassessment_prompt",notifier:notifier});this.promptsContainer.addEventListeners()};OpenAssessment.EditPromptsView.prototype={promptsDefinition:function(){var prompts=this.promptsContainer.getItemValues();return prompts},addPrompt:function(){this.promptsContainer.add()},removePrompt:function(item){this.promptsContainer.remove(item)},getAllPrompts:function(){return this.promptsContainer.getAllItems()},getPromptItem:function(index){return this.promptsContainer.getItem(index)},validate:function(){return true},validationErrors:function(){var errors=[];return errors},clearValidationErrors:function(){}};OpenAssessment.EditRubricView=function(element,notifier){this.element=element;this.criterionAddButton=$("#openassessment_rubric_add_criterion",this.element);this.criteriaContainer=new OpenAssessment.Container(OpenAssessment.RubricCriterion,{containerElement:$("#openassessment_criterion_list",this.element).get(0),templateElement:$("#openassessment_criterion_template",this.element).get(0),addButtonElement:$("#openassessment_rubric_add_criterion",this.element).get(0),removeButtonClass:"openassessment_criterion_remove_button",containerItemClass:"openassessment_criterion",notifier:notifier});this.criteriaContainer.addEventListeners()};OpenAssessment.EditRubricView.prototype={criteriaDefinition:function(){var criteria=this.criteriaContainer.getItemValues();for(var criterion_idx=0;criterion_idx<criteria.length;criterion_idx++){var criterion=criteria[criterion_idx];criterion.order_num=criterion_idx;for(var option_idx=0;option_idx<criterion.options.length;option_idx++){var option=criterion.options[option_idx];option.order_num=option_idx}}return criteria},feedbackPrompt:function(text){var sel=$("#openassessment_rubric_feedback",this.element);return OpenAssessment.Fields.stringField(sel,text)},feedback_default_text:function(text){var sel=$("#openassessment_rubric_feedback_default_text",this.element);return OpenAssessment.Fields.stringField(sel,text)},addCriterion:function(){this.criteriaContainer.add()},removeCriterion:function(item){this.criteriaContainer.remove(item)},getAllCriteria:function(){return this.criteriaContainer.getAllItems()},getCriterionItem:function(index){return this.criteriaContainer.getItem(index)},addOption:function(criterionIndex){var criterionItem=this.getCriterionItem(criterionIndex);criterionItem.optionContainer.add()},removeOption:function(criterionIndex,item){var criterionItem=this.getCriterionItem(criterionIndex);criterionItem.optionContainer.remove(item)},getAllOptions:function(criterionIndex){var criterionItem=this.getCriterionItem(criterionIndex);return criterionItem.optionContainer.getAllItems()},getOptionItem:function(criterionIndex,optionIndex){var criterionItem=this.getCriterionItem(criterionIndex);return criterionItem.optionContainer.getItem(optionIndex)},validate:function(){var criteria=this.getAllCriteria();var isValid=criteria.length>0;if(!isValid){this.criterionAddButton.addClass("openassessment_highlighted_field").click(function(){$(this).removeClass("openassessment_highlighted_field")})}$.each(criteria,function(){isValid=this.validate()&&isValid});return isValid},validationErrors:function(){var errors=[];if(this.criterionAddButton.hasClass("openassessment_highlighted_field")){errors.push("The rubric must contain at least one criterion")}$.each(this.getAllCriteria(),function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){this.criterionAddButton.removeClass("openassessment_highlighted_field");$.each(this.getAllCriteria(),function(){this.clearValidationErrors()})}};OpenAssessment.EditSettingsView=function(element,assessmentViews){this.settingsElement=element;this.assessmentsElement=$(element).siblings("#openassessment_assessment_module_settings_editors").get(0);this.assessmentViews=assessmentViews;this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#openassessment_submission_start_date","#openassessment_submission_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#openassessment_submission_due_date","#openassessment_submission_due_time").install();this.leaderboardIntField=new OpenAssessment.IntField($("#openassessment_leaderboard_editor",this.element),{min:0,max:100});this.initializeSortableAssessments()};OpenAssessment.EditSettingsView.prototype={initializeSortableAssessments:function(){var view=this;$("#openassessment_assessment_module_settings_editors",view.element).sortable({start:function(event,ui){$(".openassessment_assessment_module_editor",view.element).hide();var targetHeight="auto";ui.placeholder.height(targetHeight);ui.helper.height(targetHeight);$("#openassessment_assessment_module_settings_editors",view.element).sortable("refresh").sortable("refreshPositions")},stop:function(event,ui){$(".openassessment_assessment_module_editor",view.element).show()},snap:true,axis:"y",handle:".drag-handle",cursorAt:{top:20}});$("#openassessment_assessment_module_settings_editors .drag-handle",view.element).disableSelection()},displayName:function(name){var sel=$("#openassessment_title_editor",this.settingsElement);return OpenAssessment.Fields.stringField(sel,name)},submissionStart:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},submissionDue:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},imageSubmissionEnabled:function(isEnabled){var sel=$("#openassessment_submission_image_editor",this.settingsElement);if(isEnabled!==undefined){if(isEnabled){sel.val(1)}else{sel.val(0)}}return sel.val()==1},latexEnabled:function(isEnabled){var sel=$("#openassessment_submission_latex_editor",this.settingsElement);if(isEnabled!==undefined){if(isEnabled){sel.val(1)}else{sel.val(0)}}return sel.val()==1},leaderboardNum:function(num){if(num!==undefined){this.leaderboardIntField.set(num)}return this.leaderboardIntField.get(num)},assessmentsDescription:function(){var assessmentDescList=[];var view=this;$(".openassessment_assessment_module_settings_editor",this.assessmentsElement).each(function(){var asmntView=view.assessmentViews[$(this).attr("id")];if(asmntView.isEnabled()){var description=asmntView.description();description["name"]=asmntView.name;assessmentDescList.push(description)}});return assessmentDescList},editorAssessmentsOrder:function(){var editorAssessments=[];var view=this;$(".openassessment_assessment_module_settings_editor",this.assessmentsElement).each(function(){var asmntView=view.assessmentViews[$(this).attr("id")];editorAssessments.push(asmntView.name)});return editorAssessments},validate:function(){var isValid=true;isValid=this.startDatetimeControl.validate()&&isValid;isValid=this.dueDatetimeControl.validate()&&isValid;isValid=this.leaderboardIntField.validate()&&isValid;$.each(this.assessmentViews,function(){if(this.isEnabled()){isValid=this.validate()&&isValid}});return isValid},validationErrors:function(){var errors=[];if(this.startDatetimeControl.validationErrors().length>0){errors.push("Submission start is invalid")}if(this.dueDatetimeControl.validationErrors().length>0){errors.push("Submission due is invalid")}if(this.leaderboardIntField.validationErrors().length>0){errors.push("Leaderboard number is invalid")}$.each(this.assessmentViews,function(){errors=errors.concat(this.validationErrors())});return errors},clearValidationErrors:function(){this.startDatetimeControl.clearValidationErrors();this.dueDatetimeControl.clearValidationErrors();this.leaderboardIntField.clearValidationErrors();$.each(this.assessmentViews,function(){this.clearValidationErrors()})}};OpenAssessment.ValidationAlert=function(){this.element=$("#openassessment_validation_alert");this.editorElement=$(this.element).parent();this.title=$(".openassessment_alert_title",this.element);this.message=$(".openassessment_alert_message",this.element);this.closeButton=$(".openassessment_alert_close",this.element);this.ALERT_YELLOW="rgb(192, 172, 0)";this.DARK_GREY="#323232"};OpenAssessment.ValidationAlert.prototype={install:function(){var alert=this;this.closeButton.click(function(eventObject){eventObject.preventDefault();alert.hide()});return this},hide:function(){var headerHeight=$("#openassessment_editor_header",this.editorElement).outerHeight();this.element.addClass("covered");var styles={height:"Calc(100% - "+headerHeight+"px)","border-top-right-radius":"3px","border-top-left-radius":"3px"};$(".oa_editor_content_wrapper",this.editorElement).each(function(){$(this).css(styles)});return this},show:function(){var view=this;if(this.isVisible()){$(this.element).animate({"background-color":view.ALERT_YELLOW},300,"swing",function(){$(this).animate({"background-color":view.DARK_GREY},700,"swing")})}else{this.element.removeClass("covered");var alertHeight=this.element.outerHeight();var headerHeight=$("#openassessment_editor_header",this.editorElement).outerHeight();var heightString="Calc(100% - "+(alertHeight+headerHeight)+"px)";var styles={height:heightString,"border-top-right-radius":"0px","border-top-left-radius":"0px"};$(".oa_editor_content_wrapper",this.editorElement).each(function(){$(this).css(styles)})}return this},setMessage:function(newTitle,newMessage){this.title.text(newTitle);this.message.text(newMessage);return this},isVisible:function(){return!this.element.hasClass("covered")},getTitle:function(){return this.title.text()},getMessage:function(){return this.message.text()}};
\ No newline at end of file \ No newline at end of file
...@@ -30,7 +30,7 @@ describe("OpenAssessment.Server", function() { ...@@ -30,7 +30,7 @@ describe("OpenAssessment.Server", function() {
); );
}; };
var PROMPT = "Hello this is the prompt yes."; var PROMPTS = [{"description": "Hello this is the prompt yes."}];
var FEEDBACK_PROMPT = "Prompt for feedback"; var FEEDBACK_PROMPT = "Prompt for feedback";
var FEEDBACK_DEFAULT_TEXT = "Default feedback response text"; var FEEDBACK_DEFAULT_TEXT = "Default feedback response text";
...@@ -253,7 +253,7 @@ describe("OpenAssessment.Server", function() { ...@@ -253,7 +253,7 @@ describe("OpenAssessment.Server", function() {
it("updates the XBlock's editor context definition", function() { it("updates the XBlock's editor context definition", function() {
stubAjax(true, { success: true }); stubAjax(true, { success: true });
server.updateEditorContext({ server.updateEditorContext({
prompt: PROMPT, prompts: PROMPTS,
feedbackPrompt: FEEDBACK_PROMPT, feedbackPrompt: FEEDBACK_PROMPT,
feedback_default_text: FEEDBACK_DEFAULT_TEXT, feedback_default_text: FEEDBACK_DEFAULT_TEXT,
title: TITLE, title: TITLE,
...@@ -268,7 +268,7 @@ describe("OpenAssessment.Server", function() { ...@@ -268,7 +268,7 @@ describe("OpenAssessment.Server", function() {
expect($.ajax).toHaveBeenCalledWith({ expect($.ajax).toHaveBeenCalledWith({
type: "POST", url: '/update_editor_context', type: "POST", url: '/update_editor_context',
data: JSON.stringify({ data: JSON.stringify({
prompt: PROMPT, prompts: PROMPTS,
feedback_prompt: FEEDBACK_PROMPT, feedback_prompt: FEEDBACK_PROMPT,
feedback_default_text: FEEDBACK_DEFAULT_TEXT, feedback_default_text: FEEDBACK_DEFAULT_TEXT,
title: TITLE, title: TITLE,
......
...@@ -43,7 +43,7 @@ describe("OpenAssessment.StudioView", function() { ...@@ -43,7 +43,7 @@ describe("OpenAssessment.StudioView", function() {
var EXPECTED_SERVER_DATA = { var EXPECTED_SERVER_DATA = {
title: "The most important of all questions.", title: "The most important of all questions.",
prompt: "How much do you like waffles?", prompts: [{"description": "How much do you like waffles?"}, {description : 'How much do you like waffles 2?'}],
feedbackPrompt: "", feedbackPrompt: "",
submissionStart: "2014-01-02T12:15", submissionStart: "2014-01-02T12:15",
submissionDue: "2014-10-01T04:53", submissionDue: "2014-10-01T04:53",
...@@ -145,7 +145,7 @@ describe("OpenAssessment.StudioView", function() { ...@@ -145,7 +145,7 @@ describe("OpenAssessment.StudioView", function() {
// Top-level attributes // Top-level attributes
expect(server.receivedData.title).toEqual(EXPECTED_SERVER_DATA.title); expect(server.receivedData.title).toEqual(EXPECTED_SERVER_DATA.title);
expect(server.receivedData.prompt).toEqual(EXPECTED_SERVER_DATA.prompt); expect(server.receivedData.prompts).toEqual(EXPECTED_SERVER_DATA.prompts);
expect(server.receivedData.feedbackPrompt).toEqual(EXPECTED_SERVER_DATA.feedbackPrompt); expect(server.receivedData.feedbackPrompt).toEqual(EXPECTED_SERVER_DATA.feedbackPrompt);
expect(server.receivedData.submissionStart).toEqual(EXPECTED_SERVER_DATA.submissionStart); expect(server.receivedData.submissionStart).toEqual(EXPECTED_SERVER_DATA.submissionStart);
expect(server.receivedData.submissionDue).toEqual(EXPECTED_SERVER_DATA.submissionDue); expect(server.receivedData.submissionDue).toEqual(EXPECTED_SERVER_DATA.submissionDue);
......
...@@ -180,7 +180,7 @@ describe("OpenAssessment edit assessment views", function() { ...@@ -180,7 +180,7 @@ describe("OpenAssessment edit assessment views", function() {
expect(view.description()).toEqual({ expect(view.description()).toEqual({
examples: [ examples: [
{ {
answer: 'Test answer', answer: ['Test answer 1', 'Test answer 2'],
options_selected: [ options_selected: [
{ {
criterion: 'criterion_with_two_options', criterion: 'criterion_with_two_options',
...@@ -197,7 +197,7 @@ describe("OpenAssessment edit assessment views", function() { ...@@ -197,7 +197,7 @@ describe("OpenAssessment edit assessment views", function() {
expect(view.description()).toEqual({ expect(view.description()).toEqual({
examples: [ examples: [
{ {
answer: 'Test answer', answer: ['Test answer 1', 'Test answer 2'],
options_selected: [ options_selected: [
{ {
criterion: 'criterion_with_two_options', criterion: 'criterion_with_two_options',
...@@ -206,7 +206,7 @@ describe("OpenAssessment edit assessment views", function() { ...@@ -206,7 +206,7 @@ describe("OpenAssessment edit assessment views", function() {
] ]
}, },
{ {
answer: '', answer: ['', ''],
options_selected: [ options_selected: [
{ {
criterion: 'criterion_with_two_options', criterion: 'criterion_with_two_options',
......
...@@ -2,7 +2,20 @@ ...@@ -2,7 +2,20 @@
Tests for OpenAssessment prompt editing view. Tests for OpenAssessment prompt editing view.
**/ **/
describe("OpenAssessment.EditPromptView", function() { describe("OpenAssessment.EditPromptViews", function() {
// Use a stub notifier implementation that simply stores
// the notifications it receives.
var notifier = null;
var StubNotifier = function() {
this.notifications = [];
this.notificationFired = function(name, data) {
this.notifications.push({
name: name,
data: data
});
};
};
var view = null; var view = null;
...@@ -12,13 +25,39 @@ describe("OpenAssessment.EditPromptView", function() { ...@@ -12,13 +25,39 @@ describe("OpenAssessment.EditPromptView", function() {
// Create the view // Create the view
var element = $("#oa_prompt_editor_wrapper").get(0); var element = $("#oa_prompt_editor_wrapper").get(0);
view = new OpenAssessment.EditPromptView(element); notifier = new StubNotifier();
view = new OpenAssessment.EditPromptsView(element, notifier);
});
it("reads prompts from the editor", function() {
// This assumes a particular structure of the DOM,
// which is set by the HTML fixture.
var prompts = view.promptsDefinition();
expect(prompts.length).toEqual(2);
expect(prompts[0]).toEqual({
"description": "How much do you like waffles?"
});
}); });
it("sets and loads prompt text", function() { it("creates new prompts", function() {
view.promptText(""); // Delete all existing prompts
expect(view.promptText()).toEqual(""); // Then add new prompts (created from a client-side template)
view.promptText("This is a test prompt!"); $.each(view.getAllPrompts(), function() { view.removePrompt(this); });
expect(view.promptText()).toEqual("This is a test prompt!"); view.addPrompt();
view.addPrompt();
view.addPrompt();
var prompts = view.promptsDefinition();
expect(prompts.length).toEqual(3);
expect(prompts[0]).toEqual({
description: ""
});
expect(prompts[1]).toEqual({
description: ""
});
}); });
}); });
...@@ -445,7 +445,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) { ...@@ -445,7 +445,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) {
updateEditorContext: function(kwargs) { updateEditorContext: function(kwargs) {
var url = this.url('update_editor_context'); var url = this.url('update_editor_context');
var payload = JSON.stringify({ var payload = JSON.stringify({
prompt: kwargs.prompt, prompts: kwargs.prompts,
feedback_prompt: kwargs.feedbackPrompt, feedback_prompt: kwargs.feedbackPrompt,
feedback_default_text: kwargs.feedback_default_text, feedback_default_text: kwargs.feedback_default_text,
title: kwargs.title, title: kwargs.title,
......
...@@ -65,6 +65,113 @@ OpenAssessment.ItemUtilities = { ...@@ -65,6 +65,113 @@ OpenAssessment.ItemUtilities = {
}; };
/** /**
The Prompt Class is used to construct and maintain references to prompts from within a prompts
container object. Constructs a new Prompt element.
Args:
element (OpenAssessment.Container): The container that the prompt is a member of.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to prompts.
Returns:
OpenAssessment.Prompt
**/
OpenAssessment.Prompt = function(element, notifier) {
this.element = element;
this.notifier = notifier;
};
OpenAssessment.Prompt.prototype = {
/**
Finds the values currently entered in the Prompts's fields, and returns them.
Returns:
object literal of the form:
{
'description': 'Write a nice long essay about anything.'
}
**/
getFieldValues: function () {
var fields = {
description: this.description()
};
return fields;
},
/**
Get or set the description of the prompt.
Args:
text (string, optional): If provided, set the description of the prompt.
Returns:
string
**/
description: function(text) {
var sel = $('.openassessment_prompt_description', this.element);
return OpenAssessment.Fields.stringField(sel, text);
},
addEventListeners: function() {},
/**
Hook into the event handler for addition of a prompt.
*/
addHandler: function (){
this.notifier.notificationFired(
"promptAdd",
{
"index": this.element.index()
}
);
},
/**
Hook into the event handler for removal of a prompt.
*/
removeHandler: function (){
this.notifier.notificationFired(
"promptRemove",
{
"index": this.element.index()
}
);
},
updateHandler: function() {},
/**
Mark validation errors.
Returns:
Boolean indicating whether the option is valid.
**/
validate: function() {
return true;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of strings
**/
validationErrors: function() {
return [];
},
/**
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {}
};
/**
The RubricOption Class used to construct and maintain references to rubric options from within an options The RubricOption Class used to construct and maintain references to rubric options from within an options
container object. Constructs a new RubricOption element. container object. Constructs a new RubricOption element.
...@@ -506,7 +613,7 @@ OpenAssessment.RubricCriterion.prototype = { ...@@ -506,7 +613,7 @@ OpenAssessment.RubricCriterion.prototype = {
OpenAssessment.TrainingExample = function(element){ OpenAssessment.TrainingExample = function(element){
this.element = element; this.element = element;
this.criteria = $(".openassessment_training_example_criterion_option", this.element); this.criteria = $(".openassessment_training_example_criterion_option", this.element);
this.answer = $('.openassessment_training_example_essay', this.element).first(); this.answer = $('.openassessment_training_example_essay_part textarea', this.element)
}; };
OpenAssessment.TrainingExample.prototype = { OpenAssessment.TrainingExample.prototype = {
...@@ -527,7 +634,9 @@ OpenAssessment.TrainingExample.prototype = { ...@@ -527,7 +634,9 @@ OpenAssessment.TrainingExample.prototype = {
).get(); ).get();
return { return {
answer: this.answer.prop('value'), answer: this.answer.map(function() {
return $(this).prop('value');
}).get(),
options_selected: optionsSelected options_selected: optionsSelected
}; };
}, },
......
...@@ -25,9 +25,14 @@ OpenAssessment.StudioView = function(runtime, element, server) { ...@@ -25,9 +25,14 @@ OpenAssessment.StudioView = function(runtime, element, server) {
// Initialize the validation alert // Initialize the validation alert
this.alert = new OpenAssessment.ValidationAlert().install(); this.alert = new OpenAssessment.ValidationAlert().install();
var studentTrainingListener = new OpenAssessment.StudentTrainingListener();
// Initialize the prompt tab view // Initialize the prompt tab view
this.promptView = new OpenAssessment.EditPromptView( this.promptsView = new OpenAssessment.EditPromptsView(
$("#oa_prompt_editor_wrapper", this.element).get(0) $("#oa_prompts_editor_wrapper", this.element).get(0),
new OpenAssessment.Notifier([
studentTrainingListener
])
); );
// Initialize the settings tab view // Initialize the settings tab view
...@@ -57,7 +62,7 @@ OpenAssessment.StudioView = function(runtime, element, server) { ...@@ -57,7 +62,7 @@ OpenAssessment.StudioView = function(runtime, element, server) {
this.rubricView = new OpenAssessment.EditRubricView( this.rubricView = new OpenAssessment.EditRubricView(
$("#oa_rubric_editor_wrapper", this.element).get(0), $("#oa_rubric_editor_wrapper", this.element).get(0),
new OpenAssessment.Notifier([ new OpenAssessment.Notifier([
new OpenAssessment.StudentTrainingListener() studentTrainingListener
]) ])
); );
...@@ -185,7 +190,7 @@ OpenAssessment.StudioView.prototype = { ...@@ -185,7 +190,7 @@ OpenAssessment.StudioView.prototype = {
var view = this; var view = this;
this.server.updateEditorContext({ this.server.updateEditorContext({
prompt: view.promptView.promptText(), prompts: view.promptsView.promptsDefinition(),
feedbackPrompt: view.rubricView.feedbackPrompt(), feedbackPrompt: view.rubricView.feedbackPrompt(),
feedback_default_text: view.rubricView.feedback_default_text(), feedback_default_text: view.rubricView.feedback_default_text(),
criteria: view.rubricView.criteriaDefinition(), criteria: view.rubricView.criteriaDefinition(),
...@@ -236,7 +241,8 @@ OpenAssessment.StudioView.prototype = { ...@@ -236,7 +241,8 @@ OpenAssessment.StudioView.prototype = {
validate: function() { validate: function() {
var settingsValid = this.settingsView.validate(); var settingsValid = this.settingsView.validate();
var rubricValid = this.rubricView.validate(); var rubricValid = this.rubricView.validate();
return settingsValid && rubricValid; var promptsValid = this.promptsView.validate();
return settingsValid && rubricValid && promptsValid;
}, },
/** /**
...@@ -249,7 +255,9 @@ OpenAssessment.StudioView.prototype = { ...@@ -249,7 +255,9 @@ OpenAssessment.StudioView.prototype = {
**/ **/
validationErrors: function() { validationErrors: function() {
return this.settingsView.validationErrors().concat( return this.settingsView.validationErrors().concat(
this.rubricView.validationErrors() this.rubricView.validationErrors().concat(
this.promptsView.validationErrors()
)
); );
}, },
...@@ -259,6 +267,7 @@ OpenAssessment.StudioView.prototype = { ...@@ -259,6 +267,7 @@ OpenAssessment.StudioView.prototype = {
clearValidationErrors: function() { clearValidationErrors: function() {
this.settingsView.clearValidationErrors(); this.settingsView.clearValidationErrors();
this.rubricView.clearValidationErrors(); this.rubricView.clearValidationErrors();
this.promptsView.clearValidationErrors();
}, },
}; };
......
...@@ -421,7 +421,7 @@ OpenAssessment.EditStudentTrainingView.prototype = { ...@@ -421,7 +421,7 @@ OpenAssessment.EditStudentTrainingView.prototype = {
{ {
examples: [ examples: [
{ {
answer: "I love pokemon", answer: ("I love pokemon 1", "I love pokemon 2"),
options_selected: [ options_selected: [
{ {
criterion: "brevity", criterion: "brevity",
......
/** /**
Dynamically update student training examples based on Dynamically update student training examples based on
changes to the rubric. changes to the prompts or the rubric.
**/ **/
OpenAssessment.StudentTrainingListener = function() { OpenAssessment.StudentTrainingListener = function() {
this.element = $('#oa_student_training_editor'); this.element = $('#oa_student_training_editor');
...@@ -8,6 +8,28 @@ OpenAssessment.StudentTrainingListener = function() { ...@@ -8,6 +8,28 @@ OpenAssessment.StudentTrainingListener = function() {
}; };
OpenAssessment.StudentTrainingListener.prototype = { OpenAssessment.StudentTrainingListener.prototype = {
/**
Add a answer part in the training examples when a prompt is added.
*/
promptAdd: function(data) {
var view = this.element;
var essay_part = $("#openassessment_training_example_part_template")
.children().first()
.clone()
.removeAttr('id')
.toggleClass('is--hidden', false)
.appendTo(".openassessment_training_example_essay", view);
},
/**
Remove the answer part in the training examples when a prompt is removed.
*/
promptRemove: function(data) {
var view = this.element;
$(".openassessment_training_example_essay li:nth-child(" + (data.index + 1) + ")", view).remove();
},
/** /**
Event handler for updating training examples when a criterion option has Event handler for updating training examples when a criterion option has
been updated. been updated.
......
/**
Editing interface for the rubric prompt.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditPromptView
**/
OpenAssessment.EditPromptView = function(element) {
this.element = element;
};
OpenAssessment.EditPromptView.prototype = {
/**
Get or set the text of the prompt.
Args:
text (string, optional): If provided, set the text of the prompt.
Returns:
string
**/
promptText: function(text) {
var sel = $('#openassessment_prompt_editor', this.element);
return OpenAssessment.Fields.stringField(sel, text);
},
};
\ No newline at end of file
/**
Editing interface for the prompts.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditPromptsView
**/
OpenAssessment.EditPromptsView = function(element, notifier) {
this.element = element;
this.promptsContainer = new OpenAssessment.Container(
OpenAssessment.Prompt, {
containerElement: $("#openassessment_prompts_list", this.element).get(0),
templateElement: $("#openassessment_prompt_template", this.element).get(0),
addButtonElement: $("#openassessment_prompts_add_prompt", this.element).get(0),
removeButtonClass: "openassessment_prompt_remove_button",
containerItemClass: "openassessment_prompt",
notifier: notifier
}
);
this.promptsContainer.addEventListeners();
};
OpenAssessment.EditPromptsView.prototype = {
/**
Construct a list of prompts definitions from the editor UI.
Returns:
list of prompt objects
Example usage:
>>> editPromptsView.promptsDefinition();
[
{
uuid: "cfvgbh657",
description: "Description",
order_num: 0,
},
...
]
**/
promptsDefinition: function() {
var prompts = this.promptsContainer.getItemValues();
return prompts;
},
/**
Add a new prompt.
Uses a client-side template to create the new prompt.
**/
addPrompt: function() {
this.promptsContainer.add();
},
/**
Remove a prompt.
Args:
item (OpenAssessment.RubricCriterion): The criterion item to remove.
**/
removePrompt: function(item) {
this.promptsContainer.remove(item);
},
/**
Retrieve all prompts.
Returns:
Array of OpenAssessment.Prompt objects.
**/
getAllPrompts: function() {
return this.promptsContainer.getAllItems();
},
/**
Retrieve a prompt item from the prompts.
Args:
index (int): The index of the prompt, starting from 0.
Returns:
OpenAssessment.Prompt or null
**/
getPromptItem: function(index) {
return this.promptsContainer.getItem(index);
},
/**
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
**/
validate: function() {
return true;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
**/
validationErrors: function() {
var errors = [];
return errors;
},
/**
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {}
};
\ No newline at end of file
...@@ -331,26 +331,6 @@ ...@@ -331,26 +331,6 @@
-moz-transition: height 1s ease-in-out 0; -moz-transition: height 1s ease-in-out 0;
} }
#openassessment_prompt_editor {
width: 100%;
height: 100%;
resize: none;
border: none;
@include border-radius(4px);
padding: 10px;
font-family: $f-sans-serif;
textarea{
font-size: 14px;
border: none;
overflow: auto;
outline: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
}
#openassessment_rubric_editor { #openassessment_rubric_editor {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -493,30 +473,19 @@ ...@@ -493,30 +473,19 @@
bottom: 0; bottom: 0;
} }
#oa_rubric_editor_wrapper{ .openassessment_tab_instructions {
.wrapper-comp-settings{
display: block;
}
#openassessment_rubric_instructions{
background-color: $edx-gray-t1; background-color: $edx-gray-t1;
border-bottom: 1px solid $edx-gray-d1; border-bottom: 1px solid $edx-gray-d1;
padding: 10px; padding: 10px;
} }
.openassessment_criterion { .openassessment_container_header {
margin: ($baseline-v/2) ($baseline-h/4);
.openassessment_criterion_remove_button{ padding-bottom: $baseline-v/4;
@extend .openassessment_rubric_remove_button;
}
.openassessment_criterion_header {
margin: 10px;
padding-bottom: 5px;
border-bottom: 1px solid; border-bottom: 1px solid;
overflow: auto; overflow: auto;
color: $edx-gray-d2; color: $edx-gray-d2;
}
.action.expand-collapse { .action.expand-collapse {
@include float(left); @include float(left);
...@@ -530,30 +499,112 @@ ...@@ -530,30 +499,112 @@
} }
} }
.openassessment_criterion_header_title_box { .openassessment_container_header_title_box {
@include float(left); @include float(left);
width: 80%; width: 80%;
display: inline-block; display: inline-block;
} }
.openassessment_criterion_header_title { .openassessment_container_header_title {
@include float(left);
text-transform: uppercase; text-transform: uppercase;
width: 50%;
display: inline-block;
cursor: default; cursor: default;
padding-top: 2px; padding-top: 2px;
} }
.openassessment_criterion_guide { .openassessment_container_guide {
@extend %t-small; @extend %t-small;
} }
.openassessment_criterion_header_remove { .openassessment_container_remove_button{
@extend .openassessment_rubric_remove_button; cursor: pointer;
h2:after{
font-family: FontAwesome;
content: "\f00d";
display: inline-block;
color: inherit;
margin: 0 5px;
}
h2{
text-transform: uppercase;
font-size: 80%;
float: right;
display: inline-block;
padding: 3px 8px 3px 13px;
}
@include float(right);
}
.openassessment_container_remove_button:hover{
background-color: $edx-gray-d2;
border-radius: 4px;
color: white;
}
.openassessment_container_add_button {
h6:before{
font-family: "FontAwesome";
display: inline-block;
@include margin-left(5px);
@include margin-right(10px);
width: auto;
height: auto;
content: "\f067";
}
background-color: white;
border: 1px solid;
border-radius: 4px;
text-align: center;
color: #009fe6;
padding: 10px;
margin: 15px 10px;
}
.openassessment_container_add_button.openassessment_highlighted_field {
color: red;
border-width: 2px;
}
.openassessment_container_add_button:hover {
color: white;
background-color: #009fe6;
cursor: pointer;
}
#oa_prompts_editor_wrapper {
.wrapper-comp-settings {
display: block;
}
.openassessment_prompt_description {
width: 100%;
min-height: 100px;
resize: none;
border: 1px solid #b2b2b2;
border-radius: 4px;
padding: 10px;
font-family: $f-sans-serif;
font-size: 14px;
overflow: auto;
outline: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.openassessment_prompt_description.openassessment_highlighted_field {
border: 2px solid red;
} }
} }
#oa_rubric_editor_wrapper{
.wrapper-comp-settings{
display: block;
}
.openassessment_criterion {
.openassessment_criterion_add_option { .openassessment_criterion_add_option {
h2:before { h2:before {
font-family: FontAwesome; font-family: FontAwesome;
...@@ -653,7 +704,7 @@ ...@@ -653,7 +704,7 @@
@include padding(5px, 5px, 5px, 15px); @include padding(5px, 5px, 5px, 15px);
.openassessment_criterion_option_remove_button{ .openassessment_criterion_option_remove_button{
@extend .openassessment_rubric_remove_button; @extend .openassessment_container_remove_button;
} }
.openassessment_option_header{ .openassessment_option_header{
...@@ -670,7 +721,7 @@ ...@@ -670,7 +721,7 @@
} }
.openassessment_option_header_remove{ .openassessment_option_header_remove{
@extend .openassessment_rubric_remove_button; @extend .openassessment_container_remove_button;
} }
} }
...@@ -767,30 +818,6 @@ ...@@ -767,30 +818,6 @@
outline: 0; outline: 0;
} }
.openassessment_rubric_remove_button{
cursor: pointer;
h2:after{
font-family: FontAwesome;
content: "\f00d";
display: inline-block;
color: inherit;
margin: 0 5px;
}
h2{
text-transform: uppercase;
font-size: 80%;
@include float(right);
display: inline-block;
@include padding(3px, 8px, 3px, 13px);
}
@include float(right);
}
.openassessment_rubric_remove_button:hover{
background-color: $edx-gray-d2;
border-radius: 4px;
color: white;
}
#openassessment_rubric_feedback_wrapper{ #openassessment_rubric_feedback_wrapper{
padding: 0; padding: 0;
...@@ -813,39 +840,6 @@ ...@@ -813,39 +840,6 @@
@include float(right); @include float(right);
} }
} }
#openassessment_rubric_add_criterion{
h6:before{
font-family: "FontAwesome";
display: inline-block;
@include margin-left(5px);
@include margin-right(10px);
width: auto;
height: auto;
content: "\f067";
}
background-color: white;
border: 1px solid;
border-radius: 4px;
@include text-align(center);
color: #009fe6;
padding: 10px;
margin: 15px 10px;
}
#openassessment_rubric_add_criterion.openassessment_highlighted_field{
color: red;
border-width: 2px;
}
#openassessment_rubric_add_criterion:hover{
color: white;
background-color: #009fe6;
cursor: pointer;
}
} }
...@@ -940,7 +934,7 @@ ...@@ -940,7 +934,7 @@
.openassessment_training_example_body { .openassessment_training_example_body {
@include padding(0, 15px, 15px, 15px); @include padding(0, 15px, 15px, 15px);
position: relative; position: relative;
overflow: hidden; overflow: scroll;
.openassessment_training_example_essay_wrapper { .openassessment_training_example_essay_wrapper {
width: 58%; width: 58%;
display: inline-block; display: inline-block;
......
""" """
Studio editing view for OpenAssessment XBlock. Studio editing view for OpenAssessment XBlock.
""" """
import pkg_resources
import copy import copy
import logging import logging
import pkg_resources
from uuid import uuid4
from django.template import Context from django.template import Context
from django.template.loader import get_template from django.template.loader import get_template
from voluptuous import MultipleInvalid from voluptuous import MultipleInvalid
...@@ -12,7 +14,7 @@ from xblock.fields import List, Scope ...@@ -12,7 +14,7 @@ from xblock.fields import List, Scope
from xblock.fragment import Fragment from xblock.fragment import Fragment
from openassessment.xblock.defaults import DEFAULT_EDITOR_ASSESSMENTS_ORDER, DEFAULT_RUBRIC_FEEDBACK_TEXT from openassessment.xblock.defaults import DEFAULT_EDITOR_ASSESSMENTS_ORDER, DEFAULT_RUBRIC_FEEDBACK_TEXT
from openassessment.xblock.validation import validator from openassessment.xblock.validation import validator
from openassessment.xblock.data_conversion import create_rubric_dict, make_django_template_key from openassessment.xblock.data_conversion import create_rubric_dict, make_django_template_key, update_assessments_format
from openassessment.xblock.schema import EDITOR_UPDATE_SCHEMA from openassessment.xblock.schema import EDITOR_UPDATE_SCHEMA
from openassessment.xblock.resolve_dates import resolve_dates from openassessment.xblock.resolve_dates import resolve_dates
from openassessment.xblock.xml import serialize_examples_to_xml_str, parse_examples_from_xml_str from openassessment.xblock.xml import serialize_examples_to_xml_str, parse_examples_from_xml_str
...@@ -112,7 +114,7 @@ class StudioMixin(object): ...@@ -112,7 +114,7 @@ class StudioMixin(object):
feedback_default_text = DEFAULT_RUBRIC_FEEDBACK_TEXT feedback_default_text = DEFAULT_RUBRIC_FEEDBACK_TEXT
return { return {
'prompt': self.prompt, 'prompts': self.prompts,
'title': self.title, 'title': self.title,
'submission_due': submission_due, 'submission_due': submission_due,
'submission_start': submission_start, 'submission_start': submission_start,
...@@ -189,10 +191,14 @@ class StudioMixin(object): ...@@ -189,10 +191,14 @@ class StudioMixin(object):
)} )}
# This is where we default to EASE for problems which are edited in the GUI # This is where we default to EASE for problems which are edited in the GUI
assessment['algorithm_id'] = 'ease' assessment['algorithm_id'] = 'ease'
if assessment['name'] == 'student-training':
for example in assessment['examples']:
example['answer'] = {'parts': [{'text': text} for text in example['answer']]}
xblock_validator = validator(self, self._) xblock_validator = validator(self, self._)
success, msg = xblock_validator( success, msg = xblock_validator(
create_rubric_dict(data['prompt'], data['criteria']), create_rubric_dict(data['prompts'], data['criteria']),
data['assessments'], data['assessments'],
submission_start=data['submission_start'], submission_start=data['submission_start'],
submission_due=data['submission_due'], submission_due=data['submission_due'],
...@@ -205,7 +211,7 @@ class StudioMixin(object): ...@@ -205,7 +211,7 @@ class StudioMixin(object):
# so we can safely modify the XBlock fields. # so we can safely modify the XBlock fields.
self.title = data['title'] self.title = data['title']
self.display_name = data['title'] self.display_name = data['title']
self.prompt = data['prompt'] self.prompts = data['prompts']
self.rubric_criteria = data['criteria'] self.rubric_criteria = data['criteria']
self.rubric_assessments = data['assessments'] self.rubric_assessments = data['assessments']
self.editor_assessments_order = data['editor_assessments_order'] self.editor_assessments_order = data['editor_assessments_order']
...@@ -267,13 +273,20 @@ class StudioMixin(object): ...@@ -267,13 +273,20 @@ class StudioMixin(object):
# could be accomplished within the template, we are opting to remove logic from the template. # could be accomplished within the template, we are opting to remove logic from the template.
student_training_module = self.get_assessment_module('student-training') student_training_module = self.get_assessment_module('student-training')
student_training_template = {'answer': ""} student_training_template = {
'answer': {
'parts': [
{'text': ''} for prompt in self.prompts
]
}
}
criteria_list = copy.deepcopy(self.rubric_criteria_with_labels) criteria_list = copy.deepcopy(self.rubric_criteria_with_labels)
for criterion in criteria_list: for criterion in criteria_list:
criterion['option_selected'] = "" criterion['option_selected'] = ""
student_training_template['criteria'] = criteria_list student_training_template['criteria'] = criteria_list
if student_training_module: if student_training_module:
student_training_module = update_assessments_format([student_training_module])[0]
example_list = [] example_list = []
# Adds each example to a modified version of the student training module dictionary. # Adds each example to a modified version of the student training module dictionary.
for example in student_training_module['examples']: for example in student_training_module['examples']:
......
{ {
"missing_feedback": { "missing_feedback": {
"rubric": {
"prompt": "Test Prompt",
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
"name": "Test criterion", "name": "Test criterion",
"label": "Test criterion label",
"prompt": "Test criterion prompt", "prompt": "Test criterion prompt",
"options": [ "options": [
{ {
"order_num": 0, "order_num": 0,
"points": 0, "points": 0,
"name": "No", "name": "No",
"label": "No label",
"explanation": "No explanation" "explanation": "No explanation"
} }
] ]
} }
] ],
}, "prompts": [{"description": "My new prompt."}],
"prompt": "My new prompt.",
"submission_due": "4014-02-27T09:46:28", "submission_due": "4014-02-27T09:46:28",
"submission_start": "4014-02-10T09:46:28", "submission_start": "4014-02-10T09:46:28",
"title": "My new title.", "title": "My new title.",
...@@ -36,9 +35,59 @@ ...@@ -36,9 +35,59 @@
"start": "", "start": "",
"due": "" "due": ""
} }
]
},
"prompts_is_string": {
"title": "Foo",
"prompts": "My new prompt.",
"feedback_prompt": "Test Feedback Prompt",
"feedback_default_text": "Test default text...",
"submission_start": null,
"submission_due": null,
"allow_file_upload": true,
"leaderboard_show": true,
"allow_latex": false,
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"label": "Test criterion label",
"prompt": "Test criterion prompt",
"feedback": "optional",
"options": [
{
"order_num": 0,
"points": 0,
"label": "No label",
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"label": "Yes label",
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
],
"assessments": [
{
"name": "peer-assessment",
"start": "2014-02-27T09:46:28",
"due": "2014-03-01T00:00:00",
"must_grade": 5,
"must_be_graded_by": 3
},
{
"name": "self-assessment",
"start": "2014-04-01T00:00:00",
"due": "2014-06-01T00:00:00"
}
], ],
"expected-assessment": "peer-assessment", "editor_assessments_order": ["student-training", "peer-assessment", "self-assessment"]
"expected-criterion-prompt": "Test criterion prompt"
} }
} }
{ {
"zero_criteria": { "zero_criteria": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [] "criteria": []
} }
}, },
"negative_points": { "negative_points": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
"duplicate_criteria_names": { "duplicate_criteria_names": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
"duplicate_option_names": { "duplicate_option_names": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -88,9 +88,62 @@ ...@@ -88,9 +88,62 @@
} }
}, },
"change_prompts_number_after_release": {
"rubric": {
"prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}, {"description": "Test Prompt 3."}],
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
]
},
"current_rubric": {
"prompts": [{"description": "Test Prompt 3."}, {"description": "Test Prompt 4."}],
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
]
},
"is_released": true
},
"change_points_after_release": { "change_points_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -114,7 +167,7 @@ ...@@ -114,7 +167,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -142,7 +195,7 @@ ...@@ -142,7 +195,7 @@
"add_criteria_after_release": { "add_criteria_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -166,7 +219,7 @@ ...@@ -166,7 +219,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -213,7 +266,7 @@ ...@@ -213,7 +266,7 @@
"remove_criteria_after_release": { "remove_criteria_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -256,7 +309,7 @@ ...@@ -256,7 +309,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -284,7 +337,7 @@ ...@@ -284,7 +337,7 @@
"add_options_after_release": { "add_options_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -308,7 +361,7 @@ ...@@ -308,7 +361,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -330,7 +383,7 @@ ...@@ -330,7 +383,7 @@
"remove_options_after_release": { "remove_options_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -348,7 +401,7 @@ ...@@ -348,7 +401,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -376,7 +429,7 @@ ...@@ -376,7 +429,7 @@
"rename_criterion_name_after_release": { "rename_criterion_name_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -400,7 +453,7 @@ ...@@ -400,7 +453,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -428,7 +481,7 @@ ...@@ -428,7 +481,7 @@
"rename_multiple_criteria_after_release": { "rename_multiple_criteria_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -465,7 +518,7 @@ ...@@ -465,7 +518,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -507,7 +560,7 @@ ...@@ -507,7 +560,7 @@
"example_based_duplicate_option_points": { "example_based_duplicate_option_points": {
"is_example_based": true, "is_example_based": true,
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -534,7 +587,7 @@ ...@@ -534,7 +587,7 @@
"zero_options_feedback_optional": { "zero_options_feedback_optional": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -549,7 +602,7 @@ ...@@ -549,7 +602,7 @@
"zero_options_feedback_disabled": { "zero_options_feedback_disabled": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -564,7 +617,7 @@ ...@@ -564,7 +617,7 @@
"zero_options_no_feedback": { "zero_options_no_feedback": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
......
{ {
"no_criteria": { "no_criteria": {
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"title": "My new title.", "title": "My new title.",
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
}, },
"no_feedback_prompt": { "no_feedback_prompt": {
"prompt": "Test prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -130,7 +130,7 @@ ...@@ -130,7 +130,7 @@
"no_submission_due": { "no_submission_due": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -181,7 +181,7 @@ ...@@ -181,7 +181,7 @@
"invalid_dates": { "invalid_dates": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
"invalid_dates_two": { "invalid_dates_two": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -287,7 +287,7 @@ ...@@ -287,7 +287,7 @@
"order_num_is_string": { "order_num_is_string": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -332,7 +332,7 @@ ...@@ -332,7 +332,7 @@
"feedback_missing": { "feedback_missing": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -376,7 +376,7 @@ ...@@ -376,7 +376,7 @@
"criterion_not_a_dict": { "criterion_not_a_dict": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "prompty", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -399,7 +399,7 @@ ...@@ -399,7 +399,7 @@
"criteria_missing_keys": { "criteria_missing_keys": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -443,7 +443,7 @@ ...@@ -443,7 +443,7 @@
"options_not_a_list": { "options_not_a_list": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -473,7 +473,7 @@ ...@@ -473,7 +473,7 @@
"option_not_a_dictionary": { "option_not_a_dictionary": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -512,7 +512,7 @@ ...@@ -512,7 +512,7 @@
"option_missing_keys": { "option_missing_keys": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -556,7 +556,7 @@ ...@@ -556,7 +556,7 @@
"option_points_must_be_int": { "option_points_must_be_int": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false, "allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
...@@ -599,7 +599,7 @@ ...@@ -599,7 +599,7 @@
"allow_file_upload_must_be_boolean": { "allow_file_upload_must_be_boolean": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": 6, "allow_file_upload": 6,
"allow_latex": false, "allow_latex": false,
"criteria": [ "criteria": [
...@@ -641,7 +641,7 @@ ...@@ -641,7 +641,7 @@
"allow_file_upload_null": { "allow_file_upload_null": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"allow_file_upload": null, "allow_file_upload": null,
"allow_latex": false, "allow_latex": false,
"criteria": [ "criteria": [
...@@ -708,7 +708,7 @@ ...@@ -708,7 +708,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -765,7 +765,7 @@ ...@@ -765,7 +765,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -820,7 +820,7 @@ ...@@ -820,7 +820,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -878,7 +878,7 @@ ...@@ -878,7 +878,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -936,7 +936,7 @@ ...@@ -936,7 +936,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -988,7 +988,7 @@ ...@@ -988,7 +988,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -1002,7 +1002,7 @@ ...@@ -1002,7 +1002,7 @@
"name": "student-training", "name": "student-training",
"examples": [ "examples": [
{ {
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ", "answer": ["Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 1", "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 2"],
"options_selected": [ "options_selected": [
{ "criterion": "Not a criterion!", "option": "Ṅö" } { "criterion": "Not a criterion!", "option": "Ṅö" }
] ]
...@@ -1047,7 +1047,7 @@ ...@@ -1047,7 +1047,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -1098,7 +1098,7 @@ ...@@ -1098,7 +1098,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -1150,7 +1150,7 @@ ...@@ -1150,7 +1150,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -1181,7 +1181,7 @@ ...@@ -1181,7 +1181,7 @@
}, },
"no_criteria_name": { "no_criteria_name": {
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
...@@ -1232,7 +1232,7 @@ ...@@ -1232,7 +1232,7 @@
}, },
"no_option_name": { "no_option_name": {
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
...@@ -1283,7 +1283,7 @@ ...@@ -1283,7 +1283,7 @@
}, },
"criteria_names_not_unique": { "criteria_names_not_unique": {
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
...@@ -1357,7 +1357,7 @@ ...@@ -1357,7 +1357,7 @@
"option_names_not_unique": { "option_names_not_unique": {
"expected_error": "validation error: options", "expected_error": "validation error: options",
"prompt": "Test Prompt", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
......
...@@ -90,7 +90,11 @@ ...@@ -90,7 +90,11 @@
"due": "2014-06-01T00:00:00", "due": "2014-06-01T00:00:00",
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -127,7 +131,11 @@ ...@@ -127,7 +131,11 @@
"due": "2014-06-01T00:00:00", "due": "2014-06-01T00:00:00",
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -140,7 +148,11 @@ ...@@ -140,7 +148,11 @@
] ]
}, },
{ {
"answer": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Another test criterion", "criterion": "Another test criterion",
......
...@@ -10,7 +10,11 @@ ...@@ -10,7 +10,11 @@
], ],
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -25,12 +29,18 @@ ...@@ -25,12 +29,18 @@
"xml": [ "xml": [
"<examples>", "<examples>",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>ẗëṡẗ äṅṡẅëṛ 1</part>",
"<part>ẗëṡẗ äṅṡẅëṛ 2</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
"<select criterion=\"Another test criterion\" option=\"No\" />", "<select criterion=\"Another test criterion\" option=\"No\" />",
"</example>", "</example>",
"<example>", "<example>",
"<answer>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 1</part>",
"<part>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 2</part>",
"</answer>",
"<select criterion=\"Another test criterion\" option=\"Yes\" />", "<select criterion=\"Another test criterion\" option=\"Yes\" />",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"</example>", "</example>",
...@@ -38,7 +48,12 @@ ...@@ -38,7 +48,12 @@
], ],
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ 1"},
{"text": "ẗëṡẗ äṅṡẅëṛ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -51,7 +66,12 @@ ...@@ -51,7 +66,12 @@
] ]
}, },
{ {
"answer": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 1"},
{"text": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Another test criterion", "criterion": "Another test criterion",
......
...@@ -1059,7 +1059,9 @@ ...@@ -1059,7 +1059,9 @@
"<assessments>", "<assessments>",
"<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">", "<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>ẗëṡẗ äṅṡẅëṛ</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"<select criterion=\"Another test criterion\" option=\"Yes\" />", "<select criterion=\"Another test criterion\" option=\"Yes\" />",
"</example>", "</example>",
...@@ -1147,7 +1149,12 @@ ...@@ -1147,7 +1149,12 @@
"due": "2014-03-01T00:00:00", "due": "2014-03-01T00:00:00",
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ 1"},
{"text": "ẗëṡẗ äṅṡẅëṛ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -1160,7 +1167,12 @@ ...@@ -1160,7 +1167,12 @@
] ]
}, },
{ {
"answer": "śéćőńd téśt áńśẃéŕ", "answer": {
"parts": [
{"text": "śéćőńd téśt áńśẃéŕ 1"},
{"text": "śéćőńd téśt áńśẃéŕ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -1181,12 +1193,18 @@ ...@@ -1181,12 +1193,18 @@
"<assessments>", "<assessments>",
"<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">", "<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>ẗëṡẗ äṅṡẅëṛ 1</part>",
"<part>ẗëṡẗ äṅṡẅëṛ 2</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"<select criterion=\"Another test criterion\" option=\"Yes\" />", "<select criterion=\"Another test criterion\" option=\"Yes\" />",
"</example>", "</example>",
"<example>", "<example>",
"<answer>śéćőńd téśt áńśẃéŕ</answer>", "<answer>",
"<part>śéćőńd téśt áńśẃéŕ 1</part>",
"<part>śéćőńd téśt áńśẃéŕ 2</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
"<select criterion=\"Another test criterion\" option=\"No\" />", "<select criterion=\"Another test criterion\" option=\"No\" />",
"</example>", "</example>",
...@@ -1292,11 +1310,15 @@ ...@@ -1292,11 +1310,15 @@
"<assessments>", "<assessments>",
"<assessment name=\"example-based-assessment\" algorithm_id=\"sample-algorithm-id\">", "<assessment name=\"example-based-assessment\" algorithm_id=\"sample-algorithm-id\">",
"<example>", "<example>",
"<answer>тєѕт αηѕωєя</answer>", "<answer>",
"<part>тєѕт αηѕωєя</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"</example>", "</example>",
"<example>", "<example>",
"<answer>тєѕт αηѕωєя TWO</answer>", "<answer>",
"<part>тєѕт αηѕωєя TWO</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
"</example>", "</example>",
"</assessment>", "</assessment>",
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "Ṁÿ ṅëẅ ṗṛöṁṗẗ.", "prompts": [{"description": "Ṁÿ ṅëẅ ṗṛöṁṗẗ 1."}, {"description": "Ṁÿ ṅëẅ ṗṛöṁṗẗ 2."}],
"feedback_prompt": "ḟëëḋḅäċḳ ṗṛöṁṗẗ", "feedback_prompt": "ḟëëḋḅäċḳ ṗṛöṁṗẗ",
"feedback_default_text": "Ṫëṡẗ ḋëḟäüḷẗ ẗëẍẗ", "feedback_default_text": "Ṫëṡẗ ḋëḟäüḷẗ ẗëẍẗ",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
...@@ -143,13 +143,13 @@ ...@@ -143,13 +143,13 @@
"name": "student-training", "name": "student-training",
"examples": [ "examples": [
{ {
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ", "answer": ["Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 1", "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 2"],
"options_selected": [ "options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση", "option": "Ṅö" } { "criterion": "тєѕт ¢яιтєяιση", "option": "Ṅö" }
] ]
}, },
{ {
"answer": "This is another answer", "answer": ["This is another answer 1", "This is another answer 2"],
"options_selected": [ "options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση", "option": "sǝʎ" } { "criterion": "тєѕт ¢яιтєяιση", "option": "sǝʎ" }
] ]
...@@ -193,7 +193,7 @@ ...@@ -193,7 +193,7 @@
"feedback": "required" "feedback": "required"
} }
], ],
"prompt": "My new prompt.", "prompts": [{"description": "My new prompt 1."}, {"description": "My new prompt 2."}],
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
......
{ {
"simple": { "simple": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
"unicode": { "unicode": {
"rubric": { "rubric": {
"prompt": "☃", "prompts": [{"description": "Test Prompt 1 ☃."}, {"description": "Test Prompt 2 ☃."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -53,9 +53,61 @@ ...@@ -53,9 +53,61 @@
} }
}, },
"change_prompts_number_before_release": {
"rubric": {
"prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}, {"description": "Test Prompt 3."}],
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
]
},
"current_rubric": {
"prompts": [{"description": "Test Prompt 3."}, {"description": "Test Prompt 4."}],
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
]
},
"is_released": false
},
"change_points_before_release": { "change_points_before_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -79,7 +131,7 @@ ...@@ -79,7 +131,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -107,7 +159,7 @@ ...@@ -107,7 +159,7 @@
"add_criteria_before_release": { "add_criteria_before_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -131,7 +183,7 @@ ...@@ -131,7 +183,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -178,7 +230,7 @@ ...@@ -178,7 +230,7 @@
"remove_criteria_before_release": { "remove_criteria_before_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -221,7 +273,7 @@ ...@@ -221,7 +273,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -249,7 +301,7 @@ ...@@ -249,7 +301,7 @@
"add_options_before_release": { "add_options_before_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -273,7 +325,7 @@ ...@@ -273,7 +325,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -294,7 +346,7 @@ ...@@ -294,7 +346,7 @@
"remove_options_before_release": { "remove_options_before_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -312,7 +364,7 @@ ...@@ -312,7 +364,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -340,7 +392,7 @@ ...@@ -340,7 +392,7 @@
"change_text_before_release": { "change_text_before_release": {
"rubric": { "rubric": {
"prompt": "Changed Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -364,7 +416,7 @@ ...@@ -364,7 +416,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -390,9 +442,61 @@ ...@@ -390,9 +442,61 @@
"is_released": false "is_released": false
}, },
"change_prompts_description_after_release": {
"rubric": {
"prompts": [{"description": "Test Prompt 3."}, {"description": "Test Prompt 4."}],
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
]
},
"current_rubric": {
"prompts": [{"description": "Test Prompt 3."}, {"description": "Test Prompt 4."}],
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
]
},
"is_released": true
},
"change_criteria_prompt_after_release": { "change_criteria_prompt_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -416,7 +520,7 @@ ...@@ -416,7 +520,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -444,7 +548,7 @@ ...@@ -444,7 +548,7 @@
"change_option_name_after_release": { "change_option_name_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -468,7 +572,7 @@ ...@@ -468,7 +572,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -496,7 +600,7 @@ ...@@ -496,7 +600,7 @@
"change_option_explanation_after_release": { "change_option_explanation_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -520,7 +624,7 @@ ...@@ -520,7 +624,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -548,7 +652,7 @@ ...@@ -548,7 +652,7 @@
"rename_options_after_release": { "rename_options_after_release": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -572,7 +676,7 @@ ...@@ -572,7 +676,7 @@
] ]
}, },
"current_rubric": { "current_rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -600,7 +704,7 @@ ...@@ -600,7 +704,7 @@
"zero_options": { "zero_options": {
"rubric": { "rubric": {
"prompt": "Test Prompt", "prompts": [{"description": "Test Prompt 1."}, {"description": "Test Prompt 2."}],
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
......
...@@ -18,7 +18,7 @@ class StudioViewTest(XBlockHandlerTestCase): ...@@ -18,7 +18,7 @@ class StudioViewTest(XBlockHandlerTestCase):
""" """
UPDATE_EDITOR_DATA = { UPDATE_EDITOR_DATA = {
"title": "Test title", "title": "Test title",
"prompt": "Test prompt", "prompts": [{"description": "Test prompt"}],
"feedback_prompt": "Test feedback prompt", "feedback_prompt": "Test feedback prompt",
"feedback_default_text": "Test feedback default text", "feedback_default_text": "Test feedback default text",
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
...@@ -205,10 +205,13 @@ class StudioViewTest(XBlockHandlerTestCase): ...@@ -205,10 +205,13 @@ class StudioViewTest(XBlockHandlerTestCase):
# Store old XBlock fields for later verification # Store old XBlock fields for later verification
old_title = xblock.title old_title = xblock.title
old_prompt = xblock.prompt old_prompts = xblock.prompts
old_assessments = xblock.rubric_assessments old_assessments = xblock.rubric_assessments
old_criteria = xblock.rubric_criteria old_criteria = xblock.rubric_criteria
xblock.runtime.modulestore = MagicMock()
xblock.runtime.modulestore.has_published_version.return_value = False
# Verify the response fails # Verify the response fails
resp = self.request(xblock, 'update_editor_context', request, response_format='json') resp = self.request(xblock, 'update_editor_context', request, response_format='json')
self.assertFalse(resp['success']) self.assertFalse(resp['success'])
...@@ -218,7 +221,7 @@ class StudioViewTest(XBlockHandlerTestCase): ...@@ -218,7 +221,7 @@ class StudioViewTest(XBlockHandlerTestCase):
# We don't need to be exhaustive here, because we have other unit tests # We don't need to be exhaustive here, because we have other unit tests
# that verify this extensively. # that verify this extensively.
self.assertEqual(xblock.title, old_title) self.assertEqual(xblock.title, old_title)
self.assertEqual(xblock.prompt, old_prompt) self.assertEqual(xblock.prompts, old_prompts)
self.assertItemsEqual(xblock.rubric_assessments, old_assessments) self.assertItemsEqual(xblock.rubric_assessments, old_assessments)
self.assertItemsEqual(xblock.rubric_criteria, old_criteria) self.assertItemsEqual(xblock.rubric_criteria, old_criteria)
......
...@@ -81,7 +81,7 @@ class AssessmentValidationTest(TestCase): ...@@ -81,7 +81,7 @@ class AssessmentValidationTest(TestCase):
class RubricValidationTest(TestCase): class RubricValidationTest(TestCase):
@ddt.file_data('data/valid_rubrics.json') @ddt.file_data('data/valid_rubrics.json')
def test_valid_assessment(self, data): def test_valid_rubric(self, data):
current_rubric = data.get('current_rubric') current_rubric = data.get('current_rubric')
is_released = data.get('is_released', False) is_released = data.get('is_released', False)
is_example_based = data.get('is_example_based', False) is_example_based = data.get('is_example_based', False)
...@@ -92,7 +92,7 @@ class RubricValidationTest(TestCase): ...@@ -92,7 +92,7 @@ class RubricValidationTest(TestCase):
self.assertEqual(msg, u'') self.assertEqual(msg, u'')
@ddt.file_data('data/invalid_rubrics.json') @ddt.file_data('data/invalid_rubrics.json')
def test_invalid_assessment(self, data): def test_invalid_rubric(self, data):
current_rubric = data.get('current_rubric') current_rubric = data.get('current_rubric')
is_released = data.get('is_released', False) is_released = data.get('is_released', False)
is_example_based = data.get('is_example_based', False) is_example_based = data.get('is_example_based', False)
......
...@@ -11,7 +11,7 @@ import dateutil.parser ...@@ -11,7 +11,7 @@ import dateutil.parser
from django.test import TestCase from django.test import TestCase
import ddt import ddt
from openassessment.xblock.data_conversion import create_prompts_list from openassessment.xblock.data_conversion import create_prompts_list, update_assessments_format
from openassessment.xblock.openassessmentblock import OpenAssessmentBlock from openassessment.xblock.openassessmentblock import OpenAssessmentBlock
from openassessment.xblock.xml import ( from openassessment.xblock.xml import (
serialize_content, parse_from_xml_str, _parse_prompts_xml, parse_rubric_xml, serialize_content, parse_from_xml_str, _parse_prompts_xml, parse_rubric_xml,
...@@ -120,7 +120,9 @@ class TestSerializeContent(TestCase): ...@@ -120,7 +120,9 @@ class TestSerializeContent(TestCase):
self.oa_block.submission_start = data.get('submission_start') self.oa_block.submission_start = data.get('submission_start')
self.oa_block.submission_due = data.get('submission_due') self.oa_block.submission_due = data.get('submission_due')
self.oa_block.rubric_criteria = data.get('criteria', copy.deepcopy(self.BASIC_CRITERIA)) self.oa_block.rubric_criteria = data.get('criteria', copy.deepcopy(self.BASIC_CRITERIA))
self.oa_block.rubric_assessments = data.get('assessments', copy.deepcopy(self.BASIC_ASSESSMENTS)) self.oa_block.rubric_assessments = update_assessments_format(
data.get('assessments', copy.deepcopy(self.BASIC_ASSESSMENTS))
)
self.oa_block.allow_file_upload = data.get('allow_file_upload') self.oa_block.allow_file_upload = data.get('allow_file_upload')
self.oa_block.allow_latex = data.get('allow_latex') self.oa_block.allow_latex = data.get('allow_latex')
self.oa_block.leaderboard_show = data.get('leaderboard_show', 0) self.oa_block.leaderboard_show = data.get('leaderboard_show', 0)
...@@ -183,7 +185,8 @@ class TestSerializeContent(TestCase): ...@@ -183,7 +185,8 @@ class TestSerializeContent(TestCase):
for assessment in data['assessments']: for assessment in data['assessments']:
if 'student-training' == assessment['name'] and assessment['examples']: if 'student-training' == assessment['name'] and assessment['examples']:
xml_str = serialize_examples_to_xml_str(assessment) xml_str = serialize_examples_to_xml_str(assessment)
self.assertIn(assessment['examples'][0]['answer'], xml_str) for part in assessment['examples'][0]['answer']['parts']:
self.assertIn(part['text'], xml_str)
@ddt.file_data('data/serialize.json') @ddt.file_data('data/serialize.json')
def test_serialize_assessments(self, data): def test_serialize_assessments(self, data):
...@@ -228,7 +231,7 @@ class TestSerializeContent(TestCase): ...@@ -228,7 +231,7 @@ class TestSerializeContent(TestCase):
def test_mutated_assessments_dict(self): def test_mutated_assessments_dict(self):
self._configure_xblock({}) self._configure_xblock({})
for assessment_dict in self.BASIC_ASSESSMENTS: for assessment_dict in update_assessments_format(self.BASIC_ASSESSMENTS):
for mutated_dict in self._dict_mutations(assessment_dict): for mutated_dict in self._dict_mutations(assessment_dict):
self.oa_block.rubric_assessments = [mutated_dict] self.oa_block.rubric_assessments = [mutated_dict]
xml = serialize_content(self.oa_block) xml = serialize_content(self.oa_block)
......
...@@ -214,6 +214,10 @@ def validate_rubric(rubric_dict, current_rubric, is_released, is_example_based, ...@@ -214,6 +214,10 @@ def validate_rubric(rubric_dict, current_rubric, is_released, is_example_based,
# but nothing that would change the point value of a rubric. # but nothing that would change the point value of a rubric.
if is_released: if is_released:
# Number of prompts must be the same
if len(rubric_dict['prompts']) != len(current_rubric['prompts']):
return (False, _(u'Prompts cannot be created or deleted after a problem is released.'))
# Number of criteria must be the same # Number of criteria must be the same
if len(rubric_dict['criteria']) != len(current_rubric['criteria']): if len(rubric_dict['criteria']) != len(current_rubric['criteria']):
return (False, _(u'The number of criteria cannot be changed after a problem is released.')) return (False, _(u'The number of criteria cannot be changed after a problem is released.'))
...@@ -330,7 +334,7 @@ def validator(oa_block, _, strict_post_release=True): ...@@ -330,7 +334,7 @@ def validator(oa_block, _, strict_post_release=True):
# Rubric # Rubric
is_example_based = 'example-based-assessment' in [asmnt.get('name') for asmnt in assessments] is_example_based = 'example-based-assessment' in [asmnt.get('name') for asmnt in assessments]
current_rubric = { current_rubric = {
'prompt': oa_block.prompt, 'prompts': oa_block.prompts,
'criteria': oa_block.rubric_criteria 'criteria': oa_block.rubric_criteria
} }
success, msg = validate_rubric(rubric_dict, current_rubric, is_released, is_example_based, _) success, msg = validate_rubric(rubric_dict, current_rubric, is_released, is_example_based, _)
......
...@@ -464,11 +464,21 @@ def parse_examples_xml(examples): ...@@ -464,11 +464,21 @@ def parse_examples_xml(examples):
for example_el in examples: for example_el in examples:
example_dict = dict() example_dict = dict()
# Retrieve the answer from the training example # Retrieve the answers from the training example
answers_list = list()
answer_elements = example_el.findall('answer') answer_elements = example_el.findall('answer')
if len(answer_elements) != 1: if len(answer_elements) != 1:
raise UpdateFromXmlError(u'Each "example" element must contain exactly one "answer" element') raise UpdateFromXmlError(u'Each "example" element must contain exactly one "answer" element')
example_dict['answer'] = _safe_get_text(answer_elements[0])
answer_part_elements = answer_elements[0].findall('part')
if len(answer_part_elements) > 0:
for answer_part_element in answer_part_elements:
answers_list.append(_safe_get_text(answer_part_element))
else:
# Initially example answers had only one part.
answers_list.append(_safe_get_text(answer_elements[0]))
example_dict['answer'] = {"parts": [{"text": text} for text in answers_list]}
# Retrieve the options selected from the training example # Retrieve the options selected from the training example
example_dict['options_selected'] = [] example_dict['options_selected'] = []
...@@ -595,7 +605,9 @@ def serialize_training_examples(examples, assessment_el): ...@@ -595,7 +605,9 @@ def serialize_training_examples(examples, assessment_el):
# Answer provided in the example (default to empty string) # Answer provided in the example (default to empty string)
answer_el = etree.SubElement(example_el, 'answer') answer_el = etree.SubElement(example_el, 'answer')
answer_el.text = unicode(example_dict.get('answer', '')) for part in example_dict.get('answer', {}).get('parts', []):
part_el = etree.SubElement(answer_el, 'part')
part_el.text = unicode(part.get('text', u''))
# Options selected from the rubric # Options selected from the rubric
options_selected = example_dict.get('options_selected', []) options_selected = example_dict.get('options_selected', [])
......
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