Commit bbf6cfbc by gradyward Committed by Will Daly

A first pass at containers.

Restructred the container to be heavily reliant on DOM structure,
largely ignoring all unique identifiers and shrinking the implicit size
of the Container Item classes

Completed the initial pass of the Container Item Class.

Added tests and fixed major and minor issues.
parent 86a5d3be
if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this);this.trainingView=new OpenAssessment.StudentTrainingView(this.element,this.server,this);this.selfView=new OpenAssessment.SelfView(this.element,this.server,this);this.peerView=new OpenAssessment.PeerView(this.element,this.server,this);this.gradeView=new OpenAssessment.GradeView(this.element,this.server,this);this.messageView=new OpenAssessment.MessageView(this.element,this.server,this);this.staffInfoView=new OpenAssessment.StaffInfoView(this.element,this.server,this)};OpenAssessment.BaseView.prototype={scrollToTop:function(){if($.scrollTo instanceof Function){$(window).scrollTo($("#openassessment__steps"),800,{offset:-50})}},setUpCollapseExpand:function(parentSel,onExpand){parentSel.find(".ui-toggle-visibility__control").click(function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");if(sel.hasClass("is--collapsed")&&onExpand!==undefined){onExpand()}sel.toggleClass("is--collapsed")})},load:function(){this.responseView.load();this.loadAssessmentModules();this.staffInfoView.load()},loadAssessmentModules:function(){this.trainingView.load();this.peerView.load();this.selfView.load();this.gradeView.load()},loadMessageView:function(){this.messageView.load()},toggleActionError:function(type,msg){var element=this.element;var container=null;if(type=="save"){container=".response__submission__actions"}else if(type=="submit"||type=="peer"||type=="self"||type=="student-training"){container=".step__actions"}else if(type=="feedback_assess"){container=".submission__feedback__actions"}if(container===null){if(msg!==null){console.log(msg)}}else{var msgHtml=msg===null?"":msg;$(container+" .message__content",element).html("<p>"+msgHtml+"</p>");$(container,element).toggleClass("has--error",msg!==null)}},showLoadError:function(step){var container="#openassessment__"+step;$(container).toggleClass("has--error",true);$(container+" .step__status__value i").removeClass().addClass("ico icon-warning-sign");$(container+" .step__status__value .copy").html(gettext("Unable to Load"))}};function OpenAssessmentBlock(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.BaseView(runtime,element,server);view.load()}OpenAssessment.StudioView=function(runtime,element,server){this.runtime=runtime;this.server=server;this.liveElement=$(element);var liveElement=this.liveElement;this.settingsFieldSelectors={promptBox:$("#openassessment_prompt_editor",liveElement),titleField:$("#openassessment_title_editor",liveElement),submissionStartField:$("#openassessment_submission_start_editor",liveElement),submissionDueField:$("#openassessment_submission_due_editor",liveElement),hasPeer:$("#include_peer_assessment",liveElement),hasSelf:$("#include_self_assessment",liveElement),hasAI:$("#include_ai_assessment",liveElement),hasTraining:$("#include_student_training",liveElement),peerMustGrade:$("#peer_assessment_must_grade",liveElement),peerGradedBy:$("#peer_assessment_graded_by",liveElement),peerStart:$("#peer_assessment_start_date",liveElement),peerDue:$("#peer_assessment_due_date",liveElement),selfStart:$("#self_assessment_start_date",liveElement),selfDue:$("#self_assessment_due_date",liveElement)};var criterionHtml=$("#openassessment_criterion_1",liveElement).parent().html();this.criterionHtmlTemplate=criterionHtml.replace(new RegExp("1","g"),"C-C-C");var optionHtml=$("#openassessment_criterion_1_option_1",liveElement).parent().html();var criteriaReplaced=optionHtml.replace(new RegExp("criterion_1","g"),"criterion_C-C-C");this.optionHtmlTemplate=criteriaReplaced.replace(new RegExp("option_1","g"),"option_O-O-O");this.numberOfCriteria=0;this.numberOfOptions=[];this.rubricCriteriaSelectors=[];this.rubricFeedbackPrompt=$("#openassessment_rubric_feedback",liveElement);$("#openassessment_criterion_list",liveElement).empty();this.addNewCriterionToRubric();var view=this;$(".openassessment_save_button",liveElement).click(function(eventData){view.save()});$(".openassessment_cancel_button",liveElement).click(function(eventData){view.cancel()});$(".openassessment_editor_content_and_tabs",liveElement).tabs();view.addSettingsAssessmentCheckboxListener("ai_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("self_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("peer_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("student_training",liveElement);$("#openassessment_rubric_add_criterion",liveElement).click(function(eventData){view.addNewCriterionToRubric(liveElement)})};OpenAssessment.StudioView.prototype={load:function(){var view=this},save:function(){var view=this;this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})},addSettingsAssessmentCheckboxListener:function(name,liveElement){$("#include_"+name,liveElement).change(function(){$("#"+name+"_description_closed",liveElement).toggleClass("is--hidden",this.checked);$("#"+name+"_settings_editor",liveElement).toggleClass("is--hidden",!this.checked)})},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},addNewCriterionToRubric:function(){var view=this;var liveElement=this.liveElement;var newCriterionID=this.numberOfCriteria+1;this.numberOfCriteria+=1;this.numberOfOptions[newCriterionID]=0;var criterionHtml=this.criterionHtmlTemplate.replace(new RegExp("C-C-C","g"),""+newCriterionID);$("#openassessment_criterion_list",liveElement).append(criterionHtml);liveElement=$("#openassessment_criterion_"+newCriterionID);$(".openassessment_criterion_option_list",liveElement).empty();view.rubricCriteriaSelectors[newCriterionID]={criterion:liveElement,name:$(".openassessment_criterion_name",liveElement).first(),prompt:$(".openassessment_criterion_prompt",liveElement).first(),options:[],feedback:"disabled"};$("input:radio[value=disabled]",liveElement).prop("checked",true);view.addNewOptionToCriterion(liveElement,newCriterionID);$("#openassessment_display_criterion_"+newCriterionID,liveElement).change(function(){if(this.checked){$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeIn()}else{$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeOut()}});$("#openassessment_criterion_"+newCriterionID+"_remove",liveElement).click(function(eventData){view.removeCriterionFromRubric(newCriterionID)});$("#openassessment_criterion_"+newCriterionID+"_add_option",liveElement).click(function(eventData){view.addNewOptionToCriterion(liveElement,newCriterionID)});$(".openassessment_feedback_remove_button",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_open",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeIn();$(".openassessment_feedback_remove_button",liveElement).fadeOut();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=false});$(".openassessment_criterion_feedback_header_closed",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_open",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeOut();$(".openassessment_feedback_remove_button",liveElement).fadeIn();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=true});$(".openassessment_criterion_feedback_header_closed",liveElement).hide()},removeCriterionFromRubric:function(criterionToRemove){var view=this;var numCriteria=view.numberOfCriteria;var selectors=view.rubricCriteriaSelectors;for(var i=criterionToRemove;i<numCriteria;i++){selectors[i].name.prop("value",selectors[i+1].name.prop("value"));selectors[i].prompt.prop("value",selectors[i+1].prompt.prop("value"));selectors[i].feedback=selectors[i+1].feedback;$('input:radio[value="disabled"]',selectors[i].criterion).prop("checked",true);while(view.numberOfOptions[i]<view.numberOfOptions[i+1]){view.addNewOptionToCriterion(selectors[i].criteria,i)}while(view.numberOfOptions[i]>view.numberOfOptions[i+1]){view.removeOptionFromCriterion(selectors[i].criteria,i,1)}var options1=selectors[i].options;var options2=selectors[i+1].options;var numOptions2=view.numberOfOptions[i+1];for(var j=1;j<numOptions2;j++){options1[j].points.prop("value",options2[j].points.prop("value"));options1[j].name.prop("value",options2[j].name.prop("value"));options1[j].explanation.prop("value",options2[j].explanation.prop("value"))}}view.rubricCriteriaSelectors[view.rubricCriteriaSelectors.length-1].criterion.remove();view.rubricCriteriaSelectors=view.rubricCriteriaSelectors.slice(0,numCriteria);view.numberOfOptions=view.numberOfOptions.slice(0,numCriteria);view.numberOfCriteria-=1},addNewOptionToCriterion:function(liveElement,criterionID){var view=this;var newOptionID=this.numberOfOptions[criterionID]+1;this.numberOfOptions[criterionID]+=1;var optionHtml=this.optionHtmlTemplate;optionHtml=optionHtml.replace(new RegExp("C-C-C","g"),""+criterionID);optionHtml=optionHtml.replace(new RegExp("O-O-O","g"),""+newOptionID);$("#openassessment_criterion_"+criterionID+"_options",liveElement).append(optionHtml);liveElement=$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID);view.rubricCriteriaSelectors[criterionID].options[newOptionID]={option:liveElement,points:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_points",liveElement),name:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_name",liveElement),explanation:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_explanation",liveElement)};$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_remove",liveElement).click(function(eventData){view.removeOptionFromCriterion(liveElement,criterionID,newOptionID)})},removeOptionFromCriterion:function(liveElement,criterionID,optionToRemove){var view=this;var numberOfOptions=view.numberOfOptions[criterionID];var optionSelectors=view.rubricCriteriaSelectors[criterionID].options;for(var i=optionToRemove;i<numberOfOptions;i++){optionSelectors[i].points.prop("value",optionSelectors[i+1].points.prop("value"));optionSelectors[i].name.prop("value",optionSelectors[i+1].name.prop("value"));optionSelectors[i].explanation.prop("value",optionSelectors[i+1].explanation.prop("value"))}optionSelectors[optionSelectors.length-1].option.remove();view.rubricCriteriaSelectors[criterionID].options=view.rubricCriteriaSelectors[criterionID].options.slice(0,optionSelectors.length-1);view.numberOfOptions[criterionID]-=1},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var rubricCriteria=[];for(var i=1;i<=this.numberOfCriteria;i++){var selectorDict=this.rubricCriteriaSelectors[i];var criterionValueDict={order_num:i-1,name:selectorDict.name.prop("value"),prompt:selectorDict.prompt.prop("value"),feedback:$("#openassessment_criterion_"+i+"_feedback").val()};var optionSelectorList=selectorDict.options;var optionValueList=[];for(var j=1;j<=this.numberOfOptions[i];j++){var optionSelectors=optionSelectorList[j];optionValueList=optionValueList.concat([{order_num:j-1,points:this._getInt(optionSelectors.points),name:optionSelectors.name.val(),explanation:optionSelectors.explanation.val()}])}criterionValueDict.options=optionValueList;rubricCriteria=rubricCriteria.concat([criterionValueDict])}var assessments=[];if(this.settingsFieldSelectors.hasTraining.prop("checked")){assessments.push({name:"student-training",examples:this.studentTrainingExamplesCodeBox.getValue()})}if(this.settingsFieldSelectors.hasPeer.prop("checked")){assessments.push({name:"peer-assessment",must_grade:this._getInt(this.settingsFieldSelectors.peerMustGrade),must_be_graded_by:this._getInt(this.settingsFieldSelectors.peerGradedBy),start:this._getDateTime(this.settingsFieldSelectors.peerStart),due:this._getDateTime(this.settingsFieldSelectors.peerDue)})}if(this.settingsFieldSelectors.hasSelf.prop("checked")){assessments.push({name:"self-assessment",start:this._getDateTime(this.settingsFieldSelectors.selfStart),due:this._getDateTime(this.settingsFieldSelectors.selfDue)})}if(this.settingsFieldSelectors.hasAI.prop("checked")){assessments.push({name:"example-based-assessment",examples:this.aiTrainingExamplesCodeBox.getValue()})}var view=this;this.server.updateEditorContext({title:this.settingsFieldSelectors.titleField.val(),prompt:this.settingsFieldSelectors.promptBox.val(),feedbackPrompt:this.rubricFeedbackPrompt.val(),submissionStart:this._getDateTime(this.settingsFieldSelectors.submissionStartField),submissionDue:this._getDateTime(this.settingsFieldSelectors.submissionDueField),criteria:rubricCriteria,assessments:assessments}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})},_getDateTime:function(selector){var dateStr=selector.val();if(dateStr===""){return null}var timestamp=Date.parse(dateStr);if(isNaN(timestamp)){return null}return new Date(timestamp).toISOString()},_getInt:function(selector){return parseInt(selector.val(),10)}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server);view.load()}OpenAssessment.GradeView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.GradeView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("grade").done(function(html){$("#openassessment__grade",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){baseView.showLoadError("grade",errMsg)})},installHandlers:function(){var sel=$("#openassessment__grade",this.element);this.baseView.setUpCollapseExpand(sel);var view=this;sel.find("#feedback__submit").click(function(eventObject){eventObject.preventDefault();view.submitFeedbackOnAssessment()})},feedbackText:function(text){if(typeof text==="undefined"){return $("#feedback__remarks__value",this.element).val()}else{$("#feedback__remarks__value",this.element).val(text)}},feedbackOptions:function(options){var view=this;if(typeof options==="undefined"){return $.map($(".feedback__overall__value:checked",view.element),function(element,index){return $(element).val()})}else{$(".feedback__overall__value",this.element).prop("checked",false);$.each(options,function(index,opt){$("#feedback__overall__value--"+opt,view.element).prop("checked",true)})}},setHidden:function(sel,hidden){sel.toggleClass("is--hidden",hidden);sel.attr("aria-hidden",hidden?"true":"false")},isHidden:function(sel){return sel.hasClass("is--hidden")&&sel.attr("aria-hidden")=="true"},feedbackState:function(newState){var containerSel=$(".submission__feedback__content",this.element);var instructionsSel=containerSel.find(".submission__feedback__instructions");var fieldsSel=containerSel.find(".submission__feedback__fields");var actionsSel=containerSel.find(".submission__feedback__actions");var transitionSel=containerSel.find(".transition__status");var messageSel=containerSel.find(".message--complete");if(typeof newState==="undefined"){var isSubmitting=containerSel.hasClass("is--transitioning")&&containerSel.hasClass("is--submitting")&&!this.isHidden(transitionSel)&&this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var hasSubmitted=containerSel.hasClass("is--submitted")&&this.isHidden(transitionSel)&&!this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var isOpen=!containerSel.hasClass("is--submitted")&&!containerSel.hasClass("is--transitioning")&&!containerSel.hasClass("is--submitting")&&this.isHidden(transitionSel)&&this.isHidden(messageSel)&&!this.isHidden(instructionsSel)&&!this.isHidden(fieldsSel)&&!this.isHidden(actionsSel);if(isOpen){return"open"}else if(isSubmitting){return"submitting"}else if(hasSubmitted){return"submitted"}else{throw"Invalid feedback state"}}else{if(newState=="open"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,false);this.setHidden(fieldsSel,false);this.setHidden(actionsSel,false);this.setHidden(transitionSel,true);this.setHidden(messageSel,true)}else if(newState=="submitting"){containerSel.toggleClass("is--transitioning",true);containerSel.toggleClass("is--submitting",true);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,false);this.setHidden(messageSel,true)}else if(newState=="submitted"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",true);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,true);this.setHidden(messageSel,false)}}},submitFeedbackOnAssessment:function(){var view=this;var baseView=this.baseView;$("#feedback__submit",this.element).toggleClass("is--disabled",true);view.feedbackState("submitting");this.server.submitFeedbackOnAssessment(this.feedbackText(),this.feedbackOptions()).done(function(){view.feedbackState("submitted")}).fail(function(errMsg){baseView.toggleActionError("feedback_assess",errMsg)})}};OpenAssessment.MessageView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.MessageView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("message").done(function(html){$("#openassessment__message",view.element).replaceWith(html)}).fail(function(errMsg){baseView.showLoadError("message",errMsg)})}};OpenAssessment.PeerView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.PeerView.prototype={load:function(){var view=this;this.server.render("peer_assessment").done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")})},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel,$.proxy(view.loadContinuedAssessment,view));var rubricSelector=$("#peer-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(view.peerSubmitEnabled,view))}sel.find("#peer-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();if(!isContinuedAssessment){view.peerAssess()}else{view.continuedPeerAssess()}})},peerSubmitEnabled:function(enabled){var button=$("#peer-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},peerAssess:function(){var view=this;var baseView=view.baseView;this.peerAssessRequest(function(){view.load();baseView.loadAssessmentModules();baseView.scrollToTop()})},continuedPeerAssess:function(){var view=this;var gradeView=this.baseView.gradeView;var baseView=view.baseView;view.peerAssessRequest(function(){view.loadContinuedAssessment();gradeView.load();baseView.scrollToTop()})},peerAssessRequest:function(successFunction){var view=this;view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.overallFeedback()).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})},overallFeedback:function(overallFeedback){var selector="#assessment__rubric__question--feedback__value";if(typeof overallFeedback==="undefined"){return $(selector,this.element).val()}else{$(selector,this.element).val(overallFeedback)}}};OpenAssessment.ResponseView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.savedResponse="";this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.installHandlers();view.setAutoSaveEnabled(true)}).fail(function(errMsg){view.baseView.showLoadError("response")})},installHandlers:function(){var sel=$("#openassessment__response",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);this.savedResponse=this.response();var handleChange=function(eventData){view.handleResponseChanged()};sel.find("#submission__answer__value").on("change keyup drop paste",handleChange);sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()})},setAutoSaveEnabled:function(enabled){if(enabled){if(this.autoSaveTimerId===null){this.autoSaveTimerId=setInterval($.proxy(this.autoSave,this),this.AUTO_SAVE_POLL_INTERVAL)}}else{if(this.autoSaveTimerId!==null){clearInterval(this.autoSaveTimerId)}}},submitEnabled:function(enabled){var sel=$("#step--response__submit",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveEnabled:function(enabled){var sel=$("#submission__save",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveStatus:function(msg){var sel=$("#response__save_status h3",this.element);if(typeof msg==="undefined"){return sel.text()}else{var label=gettext("Status of Your Response");sel.html('<span class="sr">'+label+":"+"</span>\n"+msg)}},unsavedWarningEnabled:function(enabled){if(typeof enabled==="undefined"){return window.onbeforeunload!==null}else{if(enabled){window.onbeforeunload=function(){return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.")}}else{window.onbeforeunload=null}}},response:function(text){var sel=$("#submission__answer__value",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},responseChanged:function(){var currentResponse=$.trim(this.response());var savedResponse=$.trim(this.savedResponse);return savedResponse!==currentResponse},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isBlank=$.trim(this.response())!=="";this.submitEnabled(isBlank);if(this.responseChanged()){this.saveEnabled(isBlank);this.saveStatus(gettext("This response has not been saved."));this.unsavedWarningEnabled(true)}this.lastChangeTime=Date.now()},save:function(){this.errorOnLastSave=false;this.saveStatus(gettext("Saving..."));this.baseView.toggleActionError("save",null);this.unsavedWarningEnabled(false);var view=this;var savedResponse=this.response();this.server.save(savedResponse).done(function(){view.savedResponse=savedResponse;var currentResponse=view.response();view.submitEnabled(currentResponse!=="");if(currentResponse==savedResponse){view.saveEnabled(false);view.saveStatus(gettext("This response has been saved but not submitted."))}}).fail(function(errMsg){view.saveStatus(gettext("Error"));view.baseView.toggleActionError("save",errMsg);view.errorOnLastSave=true})},submit:function(){this.submitEnabled(false);var view=this;var baseView=this.baseView;this.confirmSubmission().pipe(function(){var submission=$("#submission__answer__value",view.element).val();baseView.toggleActionError("response",null);return view.server.submit(submission)}).done($.proxy(view.moveToNextStep,view)).fail(function(errCode,errMsg){if(errCode=="ENOMULTI"){view.moveToNextStep()}else{if(errMsg){baseView.toggleActionError("submit",errMsg)}view.submitEnabled(true)}})},moveToNextStep:function(){this.load();this.baseView.loadAssessmentModules();this.unsavedWarningEnabled(false)},confirmSubmission:function(){var msg="You're about to submit your response for this assignment. "+"After you submit this response, you can't change it or submit a new response.";return $.Deferred(function(defer){if(confirm(msg)){defer.resolve()}else{defer.reject()}})}};OpenAssessment.Rubric=function(element){this.element=element};OpenAssessment.Rubric.prototype={criterionFeedback:function(criterionFeedback){var selector="textarea.answer__value";var feedback={};$(selector,this.element).each(function(index,sel){if(typeof criterionFeedback!=="undefined"){$(sel).val(criterionFeedback[sel.name]);feedback[sel.name]=criterionFeedback[sel.name]}else{feedback[sel.name]=$(sel).val()}});return feedback},optionsSelected:function(optionsSelected){var selector="input[type=radio]";if(typeof optionsSelected==="undefined"){var options={};$(selector+":checked",this.element).each(function(index,sel){options[sel.name]=sel.value});return options}else{$(selector,this.element).prop("checked",false);$(selector,this.element).each(function(index,sel){if(optionsSelected.hasOwnProperty(sel.name)){if(sel.value==optionsSelected[sel.name]){$(sel).prop("checked",true)}}})}},canSubmitCallback:function(callback){$(this.element).change(function(){var numChecked=$("input[type=radio]:checked",this).length;var numAvailable=$(".field--radio.assessment__rubric__question",this).length;var canSubmit=numChecked==numAvailable;callback(canSubmit)})},showCorrections:function(corrections){var selector="input[type=radio]";var hasErrors=false;$(selector,this.element).each(function(index,sel){var listItem=$(sel).parents(".assessment__rubric__question");if(corrections.hasOwnProperty(sel.name)){hasErrors=true;listItem.find(".message--incorrect").removeClass("is--hidden");listItem.find(".message--correct").addClass("is--hidden")}else{listItem.find(".message--correct").removeClass("is--hidden");listItem.find(".message--incorrect").addClass("is--hidden")}});return hasErrors}};OpenAssessment.SelfView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.SelfView.prototype={load:function(){var view=this;this.server.render("self_assessment").done(function(html){$("#openassessment__self-assessment",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.showLoadError("self-assessment")})},installHandlers:function(){var view=this;var sel=$("#openassessment__self-assessment",view.element);this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#self-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.selfSubmitEnabled,this))}sel.find("#self-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.selfAssess()})},selfSubmitEnabled:function(enabled){var button=$("#self-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},selfAssess:function(){var view=this;var baseView=this.baseView;baseView.toggleActionError("self",null);view.selfSubmitEnabled(false);var options=this.rubric.optionsSelected();this.server.selfAssess(options).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");
var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()}};if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.StaffInfoView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.StaffInfoView.prototype={load:function(){var view=this;if($("#openassessment__staff-info",view.element).length>0){this.server.render("staff_info").done(function(html){$("#openassessment__staff-info",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_id=sel.find("#openassessment__student_id").val();this.server.studentInfo(student_id).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html)}).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_id").click(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#schedule_training").click(function(eventObject){eventObject.preventDefault();view.scheduleTraining()});sel.find("#reschedule_unfinished_tasks").click(function(eventObject){eventObject.preventDefault();view.rescheduleUnfinishedTasks()})},scheduleTraining:function(){var view=this;this.server.scheduleTraining().done(function(msg){$("#schedule_training_message",this.element).text(msg)}).fail(function(errMsg){$("#schedule_training_message",this.element).text(errMsg)})},rescheduleUnfinishedTasks:function(){var view=this;this.server.rescheduleUnfinishedTasks().done(function(msg){$("#reschedule_unfinished_tasks_message",this.element).text(msg)}).fail(function(errMsg){$("#reschedule_unfinished_tasks_message",this.element).text(errMsg)})}};OpenAssessment.StudentTrainingView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.StudentTrainingView.prototype={load:function(){var view=this;this.server.render("student_training").done(function(html){$("#openassessment__student-training",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("student-training")})},installHandlers:function(){var sel=$("#openassessment__student-training",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#student-training--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.assessButtonEnabled,this))}sel.find("#student-training--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.assess()})},assess:function(){this.assessButtonEnabled(false);var options={};if(this.rubric!==null){options=this.rubric.optionsSelected()}var view=this;var baseView=this.baseView;this.server.trainingAssess(options).done(function(corrections){var incorrect=$("#openassessment__student-training--incorrect",this.element);var instructions=$("#openassessment__student-training--instructions",this.element);if(!view.rubric.showCorrections(corrections)){view.load();baseView.loadAssessmentModules();incorrect.addClass("is--hidden");instructions.removeClass("is--hidden")}else{instructions.addClass("is--hidden");incorrect.removeClass("is--hidden")}baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("student-training",errMsg);view.assessButtonEnabled(true)})},assessButtonEnabled:function(isEnabled){var button=$("#student-training--001__assessment__submit",this.element);if(typeof isEnabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!isEnabled)}}};
\ No newline at end of file
if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this);this.trainingView=new OpenAssessment.StudentTrainingView(this.element,this.server,this);this.selfView=new OpenAssessment.SelfView(this.element,this.server,this);this.peerView=new OpenAssessment.PeerView(this.element,this.server,this);this.gradeView=new OpenAssessment.GradeView(this.element,this.server,this);this.messageView=new OpenAssessment.MessageView(this.element,this.server,this);this.staffInfoView=new OpenAssessment.StaffInfoView(this.element,this.server,this)};OpenAssessment.BaseView.prototype={scrollToTop:function(){if($.scrollTo instanceof Function){$(window).scrollTo($("#openassessment__steps"),800,{offset:-50})}},setUpCollapseExpand:function(parentSel,onExpand){parentSel.find(".ui-toggle-visibility__control").click(function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");if(sel.hasClass("is--collapsed")&&onExpand!==undefined){onExpand()}sel.toggleClass("is--collapsed")})},load:function(){this.responseView.load();this.loadAssessmentModules();this.staffInfoView.load()},loadAssessmentModules:function(){this.trainingView.load();this.peerView.load();this.selfView.load();this.gradeView.load()},loadMessageView:function(){this.messageView.load()},toggleActionError:function(type,msg){var element=this.element;var container=null;if(type=="save"){container=".response__submission__actions"}else if(type=="submit"||type=="peer"||type=="self"||type=="student-training"){container=".step__actions"}else if(type=="feedback_assess"){container=".submission__feedback__actions"}if(container===null){if(msg!==null){console.log(msg)}}else{var msgHtml=msg===null?"":msg;$(container+" .message__content",element).html("<p>"+msgHtml+"</p>");$(container,element).toggleClass("has--error",msg!==null)}},showLoadError:function(step){var container="#openassessment__"+step;$(container).toggleClass("has--error",true);$(container+" .step__status__value i").removeClass().addClass("ico icon-warning-sign");$(container+" .step__status__value .copy").html(gettext("Unable to Load"))}};function OpenAssessmentBlock(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.BaseView(runtime,element,server);view.load()}OpenAssessment.Container=function(element,selectorDictionary){this.element=element;this.selectorDictionary=selectorDictionary;this.installDeleteButtons(element)};OpenAssessment.Container.prototype={add:function(selectorString){var type=this.selectorDictionary[selectorString];if(type==undefined){throw"The string: ("+selectorString+") is not known by this container."}this.element.append(this.getHtmlTemplate(selectorString))},remove:function(index){var count=0;$(this.element).children().each(function(){if(count==index){$(this).remove();return}count++})},installDeleteButtons:function(liveElement){$(".openassessment_delete_button",liveElement).each(function(){$(this).click(function(){liveElement.closest(".openassessment_deletable").remove()})})},getItemValues:function(){var values=[];var container=this;$(this.element).children().each(function(){var classes=$(this).attr("class").split(/\s+/);var type=undefined;for(var i=0;i<classes.length;i++){var c=classes[i];if(container.selectorDictionary[c]!=undefined){type=container.selectorDictionary[c]}}if(type==undefined){throw"An item with classes ("+classes.join(" ")+") was not found in a dict of known container items."}var item=new type($(this));var value=item.getFieldValues();values.push(value)});return values},getHtmlTemplate:function(selectorString){var selector="."+selectorString+".openassessment_template";var element=$(selector,this.element);if(element.length==0){throw"There is not an element which matches the selector ("+selector+")"}return element.parent().html()}};OpenAssessment.RubricOption=function(element){this.element=element};OpenAssessment.RubricOption.prototype={getFieldValues:function(){var name=$(".openassessment_criterion_option_name",this.element).prop("value");var points=$(".openassessment_criterion_option_points",this.element).prop("value");var explanation=$(".openassessment_criterion_option_explanation",this.element).prop("value");return{name:name,points:points,explanation:explanation}}};OpenAssessment.RubricCriterion=function(element){this.element=element;this.optionContainer=new OpenAssessment.Container($(".openassessment_criterion_option_list"),{openassessment_criterion_option:OpenAssessment.RubricOption})};OpenAssessment.RubricCriterion.prototype={getFieldValues:function(){var name=$(".openassessment_criterion_name",this.element).prop("value");var prompt=$(".openassessment_criterion_prompt",this.element).prop("value");var feedback=$(".openassessment_criterion_feedback",this.element).prop("value");var options=this.optionContainer.getItemValues();return{name:name,prompt:prompt,options:options,feedback:feedback}}};OpenAssessment.StudioView=function(runtime,element,server){this.runtime=runtime;this.server=server;this.liveElement=$(element);var liveElement=this.liveElement;this.settingsFieldSelectors={promptBox:$("#openassessment_prompt_editor",liveElement),titleField:$("#openassessment_title_editor",liveElement),submissionStartField:$("#openassessment_submission_start_editor",liveElement),submissionDueField:$("#openassessment_submission_due_editor",liveElement),hasPeer:$("#include_peer_assessment",liveElement),hasSelf:$("#include_self_assessment",liveElement),hasAI:$("#include_ai_assessment",liveElement),hasTraining:$("#include_student_training",liveElement),peerMustGrade:$("#peer_assessment_must_grade",liveElement),peerGradedBy:$("#peer_assessment_graded_by",liveElement),peerStart:$("#peer_assessment_start_date",liveElement),peerDue:$("#peer_assessment_due_date",liveElement),selfStart:$("#self_assessment_start_date",liveElement),selfDue:$("#self_assessment_due_date",liveElement)};var criterionHtml=$(".openassessment_criterion",liveElement).parent().html();this.criterionHtmlTemplate=criterionHtml.replace(new RegExp("1","g"),"C-C-C");var optionHtml=$(".openassessment_criterion_option",liveElement).parent().html();var criteriaReplaced=optionHtml.replace(new RegExp("criterion_1","g"),"criterion_C-C-C");this.optionHtmlTemplate=criteriaReplaced.replace(new RegExp("option_1","g"),"option_O-O-O");this.numberOfCriteria=0;this.numberOfOptions=[];this.rubricCriteriaSelectors=[];this.rubricFeedbackPrompt=$("#openassessment_rubric_feedback",liveElement);$("#openassessment_criterion_list",liveElement).empty();this.addNewCriterionToRubric();var view=this;$(".openassessment_save_button",liveElement).click(function(eventData){view.save()});$(".openassessment_cancel_button",liveElement).click(function(eventData){view.cancel()});$(".openassessment_editor_content_and_tabs",liveElement).tabs();view.addSettingsAssessmentCheckboxListener("ai_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("self_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("peer_assessment",liveElement);view.addSettingsAssessmentCheckboxListener("student_training",liveElement);$("#openassessment_rubric_add_criterion",liveElement).click(function(eventData){view.addNewCriterionToRubric(liveElement)})};OpenAssessment.StudioView.prototype={load:function(){var view=this},save:function(){var view=this;this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})},addSettingsAssessmentCheckboxListener:function(name,liveElement){$("#include_"+name,liveElement).change(function(){$("#"+name+"_description_closed",liveElement).toggleClass("is--hidden",this.checked);$("#"+name+"_settings_editor",liveElement).toggleClass("is--hidden",!this.checked)})},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},addNewCriterionToRubric:function(){var view=this;var liveElement=this.liveElement;var newCriterionID=this.numberOfCriteria+1;this.numberOfCriteria+=1;this.numberOfOptions[newCriterionID]=0;var criterionHtml=this.criterionHtmlTemplate.replace(new RegExp("C-C-C","g"),""+newCriterionID);$("#openassessment_criterion_list",liveElement).append(criterionHtml);liveElement=$("#openassessment_criterion_"+newCriterionID);$(".openassessment_criterion_option_list",liveElement).empty();view.rubricCriteriaSelectors[newCriterionID]={criterion:liveElement,name:$(".openassessment_criterion_name",liveElement).first(),prompt:$(".openassessment_criterion_prompt",liveElement).first(),options:[],feedback:"disabled"};$("input:radio[value=disabled]",liveElement).prop("checked",true);view.addNewOptionToCriterion(liveElement,newCriterionID);$("#openassessment_display_criterion_"+newCriterionID,liveElement).change(function(){if(this.checked){$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeIn()}else{$("#openassessment_criterion_body_"+newCriterionID,liveElement).fadeOut()}});$("#openassessment_criterion_"+newCriterionID+"_remove",liveElement).click(function(eventData){view.removeCriterionFromRubric(newCriterionID)});$("#openassessment_criterion_"+newCriterionID+"_add_option",liveElement).click(function(eventData){view.addNewOptionToCriterion(liveElement,newCriterionID)});$(".openassessment_feedback_remove_button",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_open",liveElement).fadeOut();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeIn();$(".openassessment_feedback_remove_button",liveElement).fadeOut();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=false});$(".openassessment_criterion_feedback_header_closed",liveElement).click(function(eventData){$(".openassessment_criterion_feedback_direction",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_open",liveElement).fadeIn();$(".openassessment_criterion_feedback_header_closed",liveElement).fadeOut();$(".openassessment_feedback_remove_button",liveElement).fadeIn();view.rubricCriteriaSelectors[newCriterionID].hasFeedback=true});$(".openassessment_criterion_feedback_header_closed",liveElement).hide()},removeCriterionFromRubric:function(criterionToRemove){var view=this;var numCriteria=view.numberOfCriteria;var selectors=view.rubricCriteriaSelectors;for(var i=criterionToRemove;i<numCriteria;i++){selectors[i].name.prop("value",selectors[i+1].name.prop("value"));selectors[i].prompt.prop("value",selectors[i+1].prompt.prop("value"));selectors[i].feedback=selectors[i+1].feedback;$('input:radio[value="disabled"]',selectors[i].criterion).prop("checked",true);while(view.numberOfOptions[i]<view.numberOfOptions[i+1]){view.addNewOptionToCriterion(selectors[i].criteria,i)}while(view.numberOfOptions[i]>view.numberOfOptions[i+1]){view.removeOptionFromCriterion(selectors[i].criteria,i,1)}var options1=selectors[i].options;var options2=selectors[i+1].options;var numOptions2=view.numberOfOptions[i+1];for(var j=1;j<numOptions2;j++){options1[j].points.prop("value",options2[j].points.prop("value"));options1[j].name.prop("value",options2[j].name.prop("value"));options1[j].explanation.prop("value",options2[j].explanation.prop("value"))}}view.rubricCriteriaSelectors[view.rubricCriteriaSelectors.length-1].criterion.remove();view.rubricCriteriaSelectors=view.rubricCriteriaSelectors.slice(0,numCriteria);view.numberOfOptions=view.numberOfOptions.slice(0,numCriteria);view.numberOfCriteria-=1},addNewOptionToCriterion:function(liveElement,criterionID){var view=this;var newOptionID=this.numberOfOptions[criterionID]+1;this.numberOfOptions[criterionID]+=1;var optionHtml=this.optionHtmlTemplate;optionHtml=optionHtml.replace(new RegExp("C-C-C","g"),""+criterionID);optionHtml=optionHtml.replace(new RegExp("O-O-O","g"),""+newOptionID);$("#openassessment_criterion_"+criterionID+"_options",liveElement).append(optionHtml);liveElement=$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID);view.rubricCriteriaSelectors[criterionID].options[newOptionID]={option:liveElement,points:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_points",liveElement),name:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_name",liveElement),explanation:$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_explanation",liveElement)};$("#openassessment_criterion_"+criterionID+"_option_"+newOptionID+"_remove",liveElement).click(function(eventData){view.removeOptionFromCriterion(liveElement,criterionID,newOptionID)})},removeOptionFromCriterion:function(liveElement,criterionID,optionToRemove){var view=this;var numberOfOptions=view.numberOfOptions[criterionID];var optionSelectors=view.rubricCriteriaSelectors[criterionID].options;for(var i=optionToRemove;i<numberOfOptions;i++){optionSelectors[i].points.prop("value",optionSelectors[i+1].points.prop("value"));optionSelectors[i].name.prop("value",optionSelectors[i+1].name.prop("value"));optionSelectors[i].explanation.prop("value",optionSelectors[i+1].explanation.prop("value"))}optionSelectors[optionSelectors.length-1].option.remove();view.rubricCriteriaSelectors[criterionID].options=view.rubricCriteriaSelectors[criterionID].options.slice(0,optionSelectors.length-1);view.numberOfOptions[criterionID]-=1},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var rubricCriteria=[];for(var i=1;i<=this.numberOfCriteria;i++){var selectorDict=this.rubricCriteriaSelectors[i];var criterionValueDict={order_num:i-1,name:selectorDict.name.prop("value"),prompt:selectorDict.prompt.prop("value"),feedback:$("#openassessment_criterion_"+i+"_feedback").val()};var optionSelectorList=selectorDict.options;var optionValueList=[];for(var j=1;j<=this.numberOfOptions[i];j++){var optionSelectors=optionSelectorList[j];optionValueList=optionValueList.concat([{order_num:j-1,points:this._getInt(optionSelectors.points),name:optionSelectors.name.val(),explanation:optionSelectors.explanation.val()}])}criterionValueDict.options=optionValueList;rubricCriteria=rubricCriteria.concat([criterionValueDict])}var assessments=[];if(this.settingsFieldSelectors.hasTraining.prop("checked")){assessments.push({name:"student-training",examples:this.studentTrainingExamplesCodeBox.getValue()})}if(this.settingsFieldSelectors.hasPeer.prop("checked")){assessments.push({name:"peer-assessment",must_grade:this._getInt(this.settingsFieldSelectors.peerMustGrade),must_be_graded_by:this._getInt(this.settingsFieldSelectors.peerGradedBy),start:this._getDateTime(this.settingsFieldSelectors.peerStart),due:this._getDateTime(this.settingsFieldSelectors.peerDue)})}if(this.settingsFieldSelectors.hasSelf.prop("checked")){assessments.push({name:"self-assessment",start:this._getDateTime(this.settingsFieldSelectors.selfStart),due:this._getDateTime(this.settingsFieldSelectors.selfDue)})}if(this.settingsFieldSelectors.hasAI.prop("checked")){assessments.push({name:"example-based-assessment",examples:this.aiTrainingExamplesCodeBox.getValue()})}var view=this;this.server.updateEditorContext({title:this.settingsFieldSelectors.titleField.val(),prompt:this.settingsFieldSelectors.promptBox.val(),feedbackPrompt:this.rubricFeedbackPrompt.val(),submissionStart:this._getDateTime(this.settingsFieldSelectors.submissionStartField),submissionDue:this._getDateTime(this.settingsFieldSelectors.submissionDueField),criteria:rubricCriteria,assessments:assessments}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})},_getDateTime:function(selector){var dateStr=selector.val();if(dateStr===""){return null}var timestamp=Date.parse(dateStr);if(isNaN(timestamp)){return null}return new Date(timestamp).toISOString()},_getInt:function(selector){return parseInt(selector.val(),10)}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server);view.load()}OpenAssessment.GradeView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.GradeView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("grade").done(function(html){$("#openassessment__grade",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){baseView.showLoadError("grade",errMsg)})},installHandlers:function(){var sel=$("#openassessment__grade",this.element);this.baseView.setUpCollapseExpand(sel);var view=this;sel.find("#feedback__submit").click(function(eventObject){eventObject.preventDefault();view.submitFeedbackOnAssessment()})},feedbackText:function(text){if(typeof text==="undefined"){return $("#feedback__remarks__value",this.element).val()}else{$("#feedback__remarks__value",this.element).val(text)}},feedbackOptions:function(options){var view=this;if(typeof options==="undefined"){return $.map($(".feedback__overall__value:checked",view.element),function(element,index){return $(element).val()})}else{$(".feedback__overall__value",this.element).prop("checked",false);$.each(options,function(index,opt){$("#feedback__overall__value--"+opt,view.element).prop("checked",true)})}},setHidden:function(sel,hidden){sel.toggleClass("is--hidden",hidden);sel.attr("aria-hidden",hidden?"true":"false")},isHidden:function(sel){return sel.hasClass("is--hidden")&&sel.attr("aria-hidden")=="true"},feedbackState:function(newState){var containerSel=$(".submission__feedback__content",this.element);var instructionsSel=containerSel.find(".submission__feedback__instructions");var fieldsSel=containerSel.find(".submission__feedback__fields");var actionsSel=containerSel.find(".submission__feedback__actions");var transitionSel=containerSel.find(".transition__status");var messageSel=containerSel.find(".message--complete");if(typeof newState==="undefined"){var isSubmitting=containerSel.hasClass("is--transitioning")&&containerSel.hasClass("is--submitting")&&!this.isHidden(transitionSel)&&this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var hasSubmitted=containerSel.hasClass("is--submitted")&&this.isHidden(transitionSel)&&!this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var isOpen=!containerSel.hasClass("is--submitted")&&!containerSel.hasClass("is--transitioning")&&!containerSel.hasClass("is--submitting")&&this.isHidden(transitionSel)&&this.isHidden(messageSel)&&!this.isHidden(instructionsSel)&&!this.isHidden(fieldsSel)&&!this.isHidden(actionsSel);if(isOpen){return"open"}else if(isSubmitting){return"submitting"}else if(hasSubmitted){return"submitted"}else{throw"Invalid feedback state"}}else{if(newState=="open"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,false);this.setHidden(fieldsSel,false);this.setHidden(actionsSel,false);this.setHidden(transitionSel,true);this.setHidden(messageSel,true)}else if(newState=="submitting"){containerSel.toggleClass("is--transitioning",true);containerSel.toggleClass("is--submitting",true);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,false);this.setHidden(messageSel,true)}else if(newState=="submitted"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",true);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,true);this.setHidden(messageSel,false)}}},submitFeedbackOnAssessment:function(){var view=this;var baseView=this.baseView;$("#feedback__submit",this.element).toggleClass("is--disabled",true);view.feedbackState("submitting");this.server.submitFeedbackOnAssessment(this.feedbackText(),this.feedbackOptions()).done(function(){view.feedbackState("submitted")}).fail(function(errMsg){baseView.toggleActionError("feedback_assess",errMsg)})}};OpenAssessment.MessageView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.MessageView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("message").done(function(html){$("#openassessment__message",view.element).replaceWith(html)}).fail(function(errMsg){baseView.showLoadError("message",errMsg)})}};OpenAssessment.PeerView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.PeerView.prototype={load:function(){var view=this;this.server.render("peer_assessment").done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")})},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel,$.proxy(view.loadContinuedAssessment,view));var rubricSelector=$("#peer-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(view.peerSubmitEnabled,view))}sel.find("#peer-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();if(!isContinuedAssessment){view.peerAssess()}else{view.continuedPeerAssess()}})},peerSubmitEnabled:function(enabled){var button=$("#peer-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},peerAssess:function(){var view=this;var baseView=view.baseView;this.peerAssessRequest(function(){view.load();baseView.loadAssessmentModules();baseView.scrollToTop()})},continuedPeerAssess:function(){var view=this;var gradeView=this.baseView.gradeView;var baseView=view.baseView;view.peerAssessRequest(function(){view.loadContinuedAssessment();gradeView.load();baseView.scrollToTop()})},peerAssessRequest:function(successFunction){var view=this;view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.overallFeedback()).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})},overallFeedback:function(overallFeedback){var selector="#assessment__rubric__question--feedback__value";if(typeof overallFeedback==="undefined"){return $(selector,this.element).val()}else{$(selector,this.element).val(overallFeedback)}}};OpenAssessment.ResponseView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.savedResponse="";this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.installHandlers();view.setAutoSaveEnabled(true)}).fail(function(errMsg){view.baseView.showLoadError("response")})},installHandlers:function(){var sel=$("#openassessment__response",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);this.savedResponse=this.response();var handleChange=function(eventData){view.handleResponseChanged()};sel.find("#submission__answer__value").on("change keyup drop paste",handleChange);sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()})},setAutoSaveEnabled:function(enabled){if(enabled){if(this.autoSaveTimerId===null){this.autoSaveTimerId=setInterval($.proxy(this.autoSave,this),this.AUTO_SAVE_POLL_INTERVAL)}}else{if(this.autoSaveTimerId!==null){clearInterval(this.autoSaveTimerId)}}},submitEnabled:function(enabled){var sel=$("#step--response__submit",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveEnabled:function(enabled){var sel=$("#submission__save",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveStatus:function(msg){var sel=$("#response__save_status h3",this.element);if(typeof msg==="undefined"){return sel.text()}else{var label=gettext("Status of Your Response");sel.html('<span class="sr">'+label+":"+"</span>\n"+msg)}},unsavedWarningEnabled:function(enabled){if(typeof enabled==="undefined"){return window.onbeforeunload!==null}else{if(enabled){window.onbeforeunload=function(){return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.")}}else{window.onbeforeunload=null}}},response:function(text){var sel=$("#submission__answer__value",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},responseChanged:function(){var currentResponse=$.trim(this.response());var savedResponse=$.trim(this.savedResponse);return savedResponse!==currentResponse},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isBlank=$.trim(this.response())!=="";this.submitEnabled(isBlank);if(this.responseChanged()){this.saveEnabled(isBlank);this.saveStatus(gettext("This response has not been saved."));this.unsavedWarningEnabled(true)}this.lastChangeTime=Date.now()},save:function(){this.errorOnLastSave=false;this.saveStatus(gettext("Saving..."));this.baseView.toggleActionError("save",null);this.unsavedWarningEnabled(false);var view=this;var savedResponse=this.response();this.server.save(savedResponse).done(function(){view.savedResponse=savedResponse;var currentResponse=view.response();view.submitEnabled(currentResponse!=="");if(currentResponse==savedResponse){view.saveEnabled(false);view.saveStatus(gettext("This response has been saved but not submitted."))}}).fail(function(errMsg){view.saveStatus(gettext("Error"));view.baseView.toggleActionError("save",errMsg);view.errorOnLastSave=true})},submit:function(){this.submitEnabled(false);var view=this;var baseView=this.baseView;this.confirmSubmission().pipe(function(){var submission=$("#submission__answer__value",view.element).val();baseView.toggleActionError("response",null);return view.server.submit(submission)}).done($.proxy(view.moveToNextStep,view)).fail(function(errCode,errMsg){if(errCode=="ENOMULTI"){view.moveToNextStep()}else{if(errMsg){baseView.toggleActionError("submit",errMsg)}view.submitEnabled(true)}})},moveToNextStep:function(){this.load();this.baseView.loadAssessmentModules();this.unsavedWarningEnabled(false)},confirmSubmission:function(){var msg="You're about to submit your response for this assignment. "+"After you submit this response, you can't change it or submit a new response.";return $.Deferred(function(defer){if(confirm(msg)){defer.resolve()}else{defer.reject()}})}};OpenAssessment.Rubric=function(element){this.element=element};OpenAssessment.Rubric.prototype={criterionFeedback:function(criterionFeedback){var selector="textarea.answer__value";var feedback={};$(selector,this.element).each(function(index,sel){if(typeof criterionFeedback!=="undefined"){$(sel).val(criterionFeedback[sel.name]);feedback[sel.name]=criterionFeedback[sel.name]}else{feedback[sel.name]=$(sel).val()}});return feedback},optionsSelected:function(optionsSelected){var selector="input[type=radio]";if(typeof optionsSelected==="undefined"){var options={};$(selector+":checked",this.element).each(function(index,sel){options[sel.name]=sel.value});return options}else{$(selector,this.element).prop("checked",false);$(selector,this.element).each(function(index,sel){if(optionsSelected.hasOwnProperty(sel.name)){if(sel.value==optionsSelected[sel.name]){$(sel).prop("checked",true)}}})}},canSubmitCallback:function(callback){$(this.element).change(function(){var numChecked=$("input[type=radio]:checked",this).length;var numAvailable=$(".field--radio.assessment__rubric__question",this).length;var canSubmit=numChecked==numAvailable;callback(canSubmit)})},showCorrections:function(corrections){var selector="input[type=radio]";var hasErrors=false;$(selector,this.element).each(function(index,sel){var listItem=$(sel).parents(".assessment__rubric__question");if(corrections.hasOwnProperty(sel.name)){hasErrors=true;listItem.find(".message--incorrect").removeClass("is--hidden");listItem.find(".message--correct").addClass("is--hidden")}else{listItem.find(".message--correct").removeClass("is--hidden");listItem.find(".message--incorrect").addClass("is--hidden")}});return hasErrors}};OpenAssessment.SelfView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.SelfView.prototype={load:function(){var view=this;this.server.render("self_assessment").done(function(html){$("#openassessment__self-assessment",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.showLoadError("self-assessment")})},installHandlers:function(){var view=this;var sel=$("#openassessment__self-assessment",view.element);this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#self-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.selfSubmitEnabled,this))}sel.find("#self-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.selfAssess()})},selfSubmitEnabled:function(enabled){var button=$("#self-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},selfAssess:function(){var view=this;var baseView=this.baseView;baseView.toggleActionError("self",null);view.selfSubmitEnabled(false);var options=this.rubric.optionsSelected();this.server.selfAssess(options).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])
})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()}};if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.StaffInfoView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.StaffInfoView.prototype={load:function(){var view=this;if($("#openassessment__staff-info",view.element).length>0){this.server.render("staff_info").done(function(html){$("#openassessment__staff-info",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_id=sel.find("#openassessment__student_id").val();this.server.studentInfo(student_id).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html)}).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_id").click(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#schedule_training").click(function(eventObject){eventObject.preventDefault();view.scheduleTraining()});sel.find("#reschedule_unfinished_tasks").click(function(eventObject){eventObject.preventDefault();view.rescheduleUnfinishedTasks()})},scheduleTraining:function(){var view=this;this.server.scheduleTraining().done(function(msg){$("#schedule_training_message",this.element).text(msg)}).fail(function(errMsg){$("#schedule_training_message",this.element).text(errMsg)})},rescheduleUnfinishedTasks:function(){var view=this;this.server.rescheduleUnfinishedTasks().done(function(msg){$("#reschedule_unfinished_tasks_message",this.element).text(msg)}).fail(function(errMsg){$("#reschedule_unfinished_tasks_message",this.element).text(errMsg)})}};OpenAssessment.StudentTrainingView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.StudentTrainingView.prototype={load:function(){var view=this;this.server.render("student_training").done(function(html){$("#openassessment__student-training",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("student-training")})},installHandlers:function(){var sel=$("#openassessment__student-training",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#student-training--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.assessButtonEnabled,this))}sel.find("#student-training--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.assess()})},assess:function(){this.assessButtonEnabled(false);var options={};if(this.rubric!==null){options=this.rubric.optionsSelected()}var view=this;var baseView=this.baseView;this.server.trainingAssess(options).done(function(corrections){var incorrect=$("#openassessment__student-training--incorrect",this.element);var instructions=$("#openassessment__student-training--instructions",this.element);if(!view.rubric.showCorrections(corrections)){view.load();baseView.loadAssessmentModules();incorrect.addClass("is--hidden");instructions.removeClass("is--hidden")}else{instructions.addClass("is--hidden");incorrect.removeClass("is--hidden")}baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("student-training",errMsg);view.assessButtonEnabled(true)})},assessButtonEnabled:function(isEnabled){var button=$("#student-training--001__assessment__submit",this.element);if(typeof isEnabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!isEnabled)}}};
\ No newline at end of file
/**
Tests for the Openassessment Container Object.
**/
describe("OpenAssessment.Container", function () {
var container = null;
beforeEach(function () {
jasmine.getFixtures().fixturesPath = 'base/fixtures';
loadFixtures('oa_edit.html');
container = new OpenAssessment.Container(
$('#openassessment_criterion_list'),
{
'openassessment_criterion': OpenAssessment.RubricCriterion
}
)
});
it("adds a criterion", function () {
var previousSize = $('.openassessment_criterion').length;
container.add('openassessment_criterion');
var newSize = $('.openassessment_criterion').length;
expect(newSize).toEqual(previousSize + 1);
});
it("removes a criterion", function () {
container.add('openassessment_criterion');
var previousSize = $('.openassessment_criterion').length;
container.remove(1);
var newSize = $('.openassessment_criterion').length;
expect(newSize).toEqual(previousSize - 1);
});
it("requests an invalid template", function () {
var error = false;
try{
container.getHtmlTemplate('not_a_template');
} catch (e) {
error = true;
}
expect(error).toBe(true);
});
it("installs delete buttons", function () {
container.installDeleteButtons($('#openassessment_criterion_list'));
});
it("parses out unacceptable container items", function () {
container.element.append("<p> Hello, not an element here. </p>");
var error = false;
try{
container.getItemValues();
} catch (e) {
error = true;
}
expect(error).toBe(true);
});
it("returns correct item dictionary", function () {
var items = container.getItemValues();
var item = items[0];
expect(item.name).toEqual(jasmine.any(String));
expect(item.prompt).toEqual(jasmine.any(String));
expect(item.feedback).toEqual(jasmine.any(String));
expect(item.options).toEqual(jasmine.any(Array));
expect(item.options[0].name).toEqual(jasmine.any(String));
expect(parseInt(item.options[0].points)).toEqual(jasmine.any(Number));
expect(item.options[0].explanation).toEqual(jasmine.any(String));
});
it("checks for undefined selection type", function () {
var error = false;
try{
container.add("lolz this isn't a valid selection type");
} catch (e) {
error = true;
}
expect(error).toBe(true);
});
});
\ No newline at end of file
/**
* Created by gward on 7/9/14.
*/
/**
Container to store arbitrary DOM elements for insertion, deletion and installation of self-delete buttons
Args:
element (DOM element): The DOM element representing the container (usually an OL or a UL)
selectorDictionary (dict): Has keys which map element (str) to Container Item classes to which they are related
Returns:
OpenAssessment.Container
**/
OpenAssessment.Container = function(element, selectorDictionary){
this.element = element;
this.selectorDictionary = selectorDictionary;
this.installDeleteButtons(element);
};
OpenAssessment.Container.prototype = {
/**
Adds a new item of the specified type to the DOM.
If the type is unrecognized,
Throws:
An error that alerts the user that an unknown type was attempted to be added to the container.
**/
add: function(selectorString){
var type = this.selectorDictionary[selectorString];
if (type == undefined){
throw 'The string: ('+ selectorString + ') is not known by this container.';
}
this.element.append(this.getHtmlTemplate(selectorString));
},
/**
Removes a specified item from the DOM. This is distinct from (and not used by) delete buttons.
Args:
index(int): The index of the specified item to remove.
**/
remove: function(index){
var count = 0;
$(this.element).children().each(function(){
if (count == index){
$(this).remove();
return;
}
count++;
});
},
/**
Installs delete buttons on all sections of a certain element.
Called both when we create a container, and when we add new elements.
Args:
liveElement (Jquery Element): an element that allows us to define the scope of delete button creation.
**/
installDeleteButtons: function(liveElement){
$('.openassessment_delete_button', liveElement).each(function() {
$(this).click(function () {
liveElement.closest('.openassessment_deletable').remove();
});
});
},
/**
Gets the values that each container defines for itself, in the order in which they are
presented in the DOM.
Returns:
(list of ...): The list of the values that each container item associates with itself.
Throws:
An exception which notifies the user if there is an element in their container that is not
recognized as a part of the containers definition.
**/
getItemValues: function () {
var values = [];
var container = this;
$(this.element).children().each(function(){
//Attempts to find the type of a given element
var classes = $(this).attr('class').split(/\s+/);
var type = undefined;
for(var i = 0; i < classes.length; i++){
var c = classes[i];
if (container.selectorDictionary[c] != undefined){
type = container.selectorDictionary[c];
}
}
// If we couldn't resolve the type, we throw an exception.
if (type == undefined){
throw 'An item with classes (' + classes.join(' ') +
') was not found in a dict of known container items.';
}
var item = new type($(this));
var value = item.getFieldValues();
values.push(value);
});
return values;
},
/**
Returns the specific HTML template that is defined for its container items.
Returns:
(str): The HTML template associated with the container item's type.
**/
getHtmlTemplate: function(selectorString){
var selector = '.' + selectorString + '.openassessment_template';
var element = $(selector, this.element);
if (element.length == 0){
throw "There is not an element which matches the selector (" + selector + ")";
}
// Because we are assuming each template will be found within a div which it is the sole occupant of,
// we can make this call safely to get the body and enclosing tab.
return element.parent().html();
}
};
/**
The RubricOption Class used to construct and maintain references to rubric options from within an options
container object. Constructs a new RubricOption element.
Args:
parent (OpenAssessment.Container): The container that the option is a member of.
Returns:
OpenAssessment.RubricOption
**/
OpenAssessment.RubricOption = function(element){
this.element = element;
};
OpenAssessment.RubricOption.prototype = {
/**
Finds the values currently entered in the Option's fields, and returns them in a dictionary to the user.
Returns:
(dict) of the form:
{
'name': 'Real Bad',
'points': 1,
'explanation': 'Essay was primarily composed of emojis.'
}
**/
getFieldValues: function (){
var name = $('.openassessment_criterion_option_name', this.element).prop('value');
var points = $('.openassessment_criterion_option_points', this.element).prop('value');
var explanation = $('.openassessment_criterion_option_explanation', this.element).prop('value');
return {
'name': name,
'points': points,
'explanation': explanation
};
}
};
/**
The RubricCriterion Class is used to construct and get information from a rubric element within
the DOM.
Args:
element (JQuery Object): The selection which describes the scope of the criterion.
Returns:
OpenAssessment.RubricCriterion
**/
OpenAssessment.RubricCriterion = function(element){
this.element = element;
this.optionContainer = new OpenAssessment.Container(
$('.openassessment_criterion_option_list'),
{
'openassessment_criterion_option': OpenAssessment.RubricOption
}
);
};
OpenAssessment.RubricCriterion.prototype = {
/**
Finds the values currently entered in the Criterion's fields, and returns them in a dictionary to the user.
Returns:
(dict) of the form:
{
'name': 'Emoji Content',
'prompt': 'How expressive was the author with their words, and how much did they rely on emojis?',
'feedback': 'optional',
'options': [
{
'name': 'Real Bad',
'points': 1,
'explanation': 'Essay was primarily composed of emojis.'
}
...
]
}
**/
getFieldValues: function (){
var name = $('.openassessment_criterion_name', this.element).prop('value');
var prompt = $('.openassessment_criterion_prompt', this.element).prop('value');
var feedback = $('.openassessment_criterion_feedback', this.element).prop('value');
var options = this.optionContainer.getItemValues();
return {
'name': name,
'prompt': prompt,
'options': options,
'feedback': feedback
};
}
};
\ No newline at end of file
......@@ -39,7 +39,7 @@ OpenAssessment.StudioView = function(runtime, element, server) {
// Captures the HTML definition of the original criterion element. This will be the template
// used for all other criterion creations
var criterionHtml = $("#openassessment_criterion_1", liveElement).parent().html();
var criterionHtml = $(".openassessment_criterion", liveElement).parent().html();
// Replaces all instances of the original ID (1) with the new fake ID in the string
// representation of the Criterion LI. This is our new template, with a C-C-C marker to replace.
......@@ -47,7 +47,7 @@ OpenAssessment.StudioView = function(runtime, element, server) {
// Captures the HTML definition of the original option element. Note that there are TWO template
// tags that need to be replaced "C-C-C" for the Criterion ID, and "O-O-O" for the option ID.
var optionHtml = $("#openassessment_criterion_1_option_1", liveElement).parent().html();
var optionHtml = $(".openassessment_criterion_option", liveElement).parent().html();
var criteriaReplaced = optionHtml.replace(new RegExp("criterion_1", "g"), "criterion_C-C-C");
this.optionHtmlTemplate = criteriaReplaced.replace(new RegExp("option_1", "g"), "option_O-O-O");
......
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