From 62a7e2b4b1fb1d665706a6cedb12d73b7bde5d1d Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Tue, 3 Jan 2012 15:18:38 +0100 Subject: [PATCH] OO-30: show the feedback after the last question of a test --- .../ims/qti/navigator/DefaultNavigator.java | 14 ++- .../olat/modules/iq/IQComponentRenderer.java | 61 ++++++---- .../olat/modules/iq/IQDisplayController.java | 108 +++++++++++------- .../java/org/olat/modules/iq/IQStatus.java | 4 + .../org/olat/modules/iq/_content/qti.html | 6 + 5 files changed, 130 insertions(+), 63 deletions(-) diff --git a/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java b/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java index 2d95158e067..1b68770c63f 100644 --- a/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java +++ b/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java @@ -142,14 +142,26 @@ public class DefaultNavigator implements Serializable { * @see org.olat.qti.process.Navigator#submitAssessment() */ public void submitAssessment() { + Output pendingOutput = null; + boolean pendingFeedback = getInfo().isFeedback(); + if(pendingFeedback && getAssessmentInstance().getAssessmentContext().getCurrentSectionContext() != null) { + ItemContext itc = getAssessmentInstance().getAssessmentContext().getCurrentSectionContext().getCurrentItemContext(); + pendingOutput = itc.getOutput(); + } + getAssessmentInstance().close(); AssessmentContext ac = getAssessmentContext(); + + info.clear(); if (ac.isFeedbackavailable()) { Output outp = ac.getOutput(); getInfo().setCurrentOutput(outp); getInfo().setFeedback(true); + } else if (pendingFeedback) { + getInfo().setCurrentOutput(pendingOutput); + getInfo().setFeedback(true); } - info.clear(); + //info.clear(); info.setMessage(QTIConstants.MESSAGE_ASSESSMENT_SUBMITTED); info.setStatus(QTIConstants.ASSESSMENT_FINISHED); info.setRenderItems(false); diff --git a/src/main/java/org/olat/modules/iq/IQComponentRenderer.java b/src/main/java/org/olat/modules/iq/IQComponentRenderer.java index 8bc709b1445..44d302fd4b9 100644 --- a/src/main/java/org/olat/modules/iq/IQComponentRenderer.java +++ b/src/main/java/org/olat/modules/iq/IQComponentRenderer.java @@ -25,7 +25,6 @@ package org.olat.modules.iq; -import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Iterator; import java.util.List; @@ -116,23 +115,8 @@ public class IQComponentRenderer implements ComponentRenderer { displayFeedback(sb, el_solution, ai, translator.getLocale()); } // item fb? - if (info.isFeedback()) { - if (info.getCurrentOutput().hasItem_Responses()) { - int fbcount = info.getCurrentOutput().getFeedbackCount(); - int i=0; - while (i < fbcount) { - Element el_anschosen = info.getCurrentOutput().getItemAnswerChosen(i); - if (el_anschosen != null) { - sb.append("<br /><br /><i>"); - displayFeedback(sb, new Material(el_anschosen), ai, translator.getLocale()); - sb.append("</i>"); - } - Element el_resp= info.getCurrentOutput().getItemFeedback(i); - displayFeedback(sb, new ItemFeedback(el_resp), ai, translator.getLocale()); - i++; - } - } - } + renderFeedback(info, sb, ai, translator); + if(!comp.getMenuDisplayConf().isEnabledMenu() && comp.getMenuDisplayConf().isItemPageSequence() && !info.isRenderItems()) { //if item was submitted and sequence is pageSequence and menu not enabled and isRenderItems returns false show section info SectionContext sc = ai.getAssessmentContext().getCurrentSectionContext(); @@ -146,7 +130,11 @@ public class IQComponentRenderer implements ComponentRenderer { if (info.isFeedback()) { Output outp = info.getCurrentOutput(); GenericQTIElement el_feedback = outp.getEl_response(); - if (el_feedback != null) displayFeedback(sb, el_feedback, ai, translator.getLocale()); + if (el_feedback != null) { + displayFeedback(sb, el_feedback, ai, translator.getLocale()); + } else { + renderFeedback(info, sb, ai, translator); + } } if(!comp.getMenuDisplayConf().isEnabledMenu() && !comp.getMenuDisplayConf().isItemPageSequence()) { SectionContext sc = ai.getAssessmentContext().getCurrentSectionContext(); @@ -275,11 +263,44 @@ public class IQComponentRenderer implements ComponentRenderer { if (info.isFeedback()) { Output outp = info.getCurrentOutput(); GenericQTIElement el_feedback = outp.getEl_response(); - if (el_feedback != null) displayFeedback(sb, el_feedback, ai, null); + if (el_feedback != null) { + displayFeedback(sb, el_feedback, ai, null); + } else { + renderFeedback(info, sb, ai, translator); + + //add the next button + sb.append("<a class=\"b_button\" onclick=\"return o2cl()\" href=\""); + ubu.buildURI(sb, new String[] { VelocityContainer.COMMAND_ID }, new String[] { "sitsec" }); + String title = translator.translate("next"); + sb.append("\" title=\"" + StringEscapeUtils.escapeHtml(title) + "\">"); + sb.append("<span>").append(title).append("</title>"); + sb.append("</a>"); + } } } return sb; } + + protected void renderFeedback(Info info, StringOutput sb, AssessmentInstance ai, Translator translator) { + if (info.isFeedback()) { + if (info.getCurrentOutput().hasItem_Responses()) { + int fbcount = info.getCurrentOutput().getFeedbackCount(); + int i=0; + while (i < fbcount) { + Element el_anschosen = info.getCurrentOutput().getItemAnswerChosen(i); + if (el_anschosen != null) { + sb.append("<br /><br /><i>"); + displayFeedback(sb, new Material(el_anschosen), ai, translator.getLocale()); + sb.append("</i>"); + } + Element el_resp= info.getCurrentOutput().getItemFeedback(i); + displayFeedback(sb, new ItemFeedback(el_resp), ai, translator.getLocale()); + i++; + } + } + } + + } protected static String getFormattedLimit(long millis) { long sSec = millis / 1000; diff --git a/src/main/java/org/olat/modules/iq/IQDisplayController.java b/src/main/java/org/olat/modules/iq/IQDisplayController.java index 016f8284d81..00efa1e0302 100644 --- a/src/main/java/org/olat/modules/iq/IQDisplayController.java +++ b/src/main/java/org/olat/modules/iq/IQDisplayController.java @@ -82,9 +82,6 @@ public class IQDisplayController extends DefaultController implements Activateab private static Logger log = Logger.getLogger(IQDisplayController.class.getName()); - // used for logging - private static final String IMSQTI = "IMSQTI"; - private VelocityContainer myContent; private Translator translator; @@ -403,7 +400,22 @@ public class IQDisplayController extends DefaultController implements Activateab navig.submitItems(iInp); } if (ai.isClosed()) { // do all the finishing stuff - event(ureq, source, new Event(QTIConstants.QTI_WF_SUBMIT)); + if(navig.getInfo().isFeedback()) { + //render the feedback + } else { + event(ureq, source, new Event(QTIConstants.QTI_WF_SUBMIT)); + return; + } + } + } else if (wfCommand.equals("sitsec")) { // submit + if (ai.isClosed()) { // do all the finishing stuff + if (!qtistatus.isSurvey()) { + // for test and self-assessment, generate detailed results + generateDetailsResults(ureq, ai); + } else { + // Send also finished event in case of survey + fireEvent(ureq, new IQSubmittedEvent()); + } return; } } else if (wfCommand.equals("sflash")) { // submit flash answer @@ -439,44 +451,7 @@ public class IQDisplayController extends DefaultController implements Activateab } else if (wfCommand.equals(QTIConstants.QTI_WF_SUBMIT)) { // submit // Assessment navig.submitAssessment(); - // Persist data in all cases: test, selftest, surveys except previews - // In case of survey, data will be anonymized when reading from the - // table (using the archiver) - if (!qtistatus.isPreview()) { - iqm.persistResults(ai, callingResId, callingResDetail, ureq); - getWindowControl().setInfo(translator.translate("status.results.saved")); - } else { - getWindowControl().setInfo(translator.translate("status.results.notsaved")); - } - - if (!qtistatus.isSurvey()) { // for test and self-assessment, generate - // detailed results - Document docResReporting = iqm.getResultsReporting(ai, ureq); - if (!iqsec.isPreview()) { - FilePersister.createResultsReporting(docResReporting, ureq.getIdentity(), ai.getFormattedType(), ai.getAssessID()); - // Send score and passed to parent controller. Maybe it is necessary - // to save some data there - // Do this now and not later, maybe user will never click on - // 'close'... - AssessmentContext ac = ai.getAssessmentContext(); - fireEvent(ureq, new IQSubmittedEvent(ac.getScore(), ac.isPassed(), ai.getAssessID())); - } - - Boolean showResultsOnFinishObj = (Boolean)modConfig.get(IQEditController.CONFIG_KEY_RESULT_ON_FINISH); - boolean showResultsOnFinish = showResultsOnFinishObj==null || showResultsOnFinishObj!=null && showResultsOnFinishObj.booleanValue(); - if (ai.getSummaryType() == AssessmentInstance.SUMMARY_NONE || !showResultsOnFinish) { - // do not display results reporting - myContent.contextPut("displayreporting", Boolean.FALSE); - } else { // display results reporting - String resReporting = iqm.transformResultsReporting(docResReporting, ureq.getLocale(), ai.getSummaryType() ); - myContent.contextPut("resreporting", resReporting); - myContent.contextPut("displayreporting", Boolean.TRUE); - } - myContent.setPage(VELOCITY_ROOT + "/result.html"); - } else { - // Send also finished event in case of survey - fireEvent(ureq, new IQSubmittedEvent()); - } + postSubmitAssessment(ureq, ai); } else if (wfCommand.equals(QTIConstants.QTI_WF_CANCEL)) { // cancel // assessment navig.cancelAssessment(); @@ -503,6 +478,55 @@ public class IQDisplayController extends DefaultController implements Activateab return; } } + + /** + * Persist data in all cases: test, selftest, surveys except previews + * In case of survey, data will be anonymized when reading from the + * table (using the archiver) + */ + protected void postSubmitAssessment(UserRequest ureq, AssessmentInstance ai) { + if (!qtistatus.isPreview()) { + iqm.persistResults(ai, callingResId, callingResDetail, ureq); + getWindowControl().setInfo(translator.translate("status.results.saved")); + } else { + getWindowControl().setInfo(translator.translate("status.results.notsaved")); + } + + if (!qtistatus.isSurvey()) { + // for test and self-assessment, generate detailed results + generateDetailsResults(ureq, ai); + } else { + // Send also finished event in case of survey + fireEvent(ureq, new IQSubmittedEvent()); + } + } + + protected void generateDetailsResults(UserRequest ureq, AssessmentInstance ai) { + Document docResReporting = iqm.getResultsReporting(ai, ureq); + if (!iqsec.isPreview()) { + FilePersister.createResultsReporting(docResReporting, ureq.getIdentity(), ai.getFormattedType(), ai.getAssessID()); + // Send score and passed to parent controller. Maybe it is necessary + // to save some data there + // Do this now and not later, maybe user will never click on + // 'close'... + AssessmentContext ac = ai.getAssessmentContext(); + fireEvent(ureq, new IQSubmittedEvent(ac.getScore(), ac.isPassed(), ai.getAssessID())); + } + + Boolean showResultsOnFinishObj = (Boolean)modConfig.get(IQEditController.CONFIG_KEY_RESULT_ON_FINISH); + boolean showResultsOnFinish = showResultsOnFinishObj==null || showResultsOnFinishObj!=null && showResultsOnFinishObj.booleanValue(); + if (ai.getSummaryType() == AssessmentInstance.SUMMARY_NONE || !showResultsOnFinish) { + // do not display results reporting + myContent.contextPut("displayreporting", Boolean.FALSE); + } else { // display results reporting + String resReporting = iqm.transformResultsReporting(docResReporting, ureq.getLocale(), ai.getSummaryType() ); + myContent.contextPut("resreporting", resReporting); + myContent.contextPut("displayreporting", Boolean.TRUE); + } + myContent.setPage(VELOCITY_ROOT + "/result.html"); + + + } /** * @param ureq diff --git a/src/main/java/org/olat/modules/iq/IQStatus.java b/src/main/java/org/olat/modules/iq/IQStatus.java index 0a84536d6ed..b65dff4a828 100644 --- a/src/main/java/org/olat/modules/iq/IQStatus.java +++ b/src/main/java/org/olat/modules/iq/IQStatus.java @@ -236,6 +236,10 @@ public class IQStatus { * @return true if assessment instance is not closed */ public boolean isOpen() { return isOpen; } + /** + * @return true if assessment instance is not closed + */ + public boolean isClosed() { return !isOpen; } /** * @return true if of type survey (questionnaire) */ diff --git a/src/main/java/org/olat/modules/iq/_content/qti.html b/src/main/java/org/olat/modules/iq/_content/qti.html index b1832459b32..f24af15b995 100644 --- a/src/main/java/org/olat/modules/iq/_content/qti.html +++ b/src/main/java/org/olat/modules/iq/_content/qti.html @@ -187,6 +187,12 @@ function confirmSuspend() { </div> </div> + #elseif($qtistatus.isClosed()) + <div class="b_subcr"> + <div id="o_qti_run_content_inner" class="b_floatscrollbox"> + $r.render("qticomp", "qtiform") + </div> + </div> #end </div> </div> -- GitLab