Index: lams_tool_assessment/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r0256157df25d72ff4822298fe41d0db73ddebf8b -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 0256157df25d72ff4822298fe41d0db73ddebf8b) +++ lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -100,6 +100,7 @@ label.authoring.advance.feedback =Feedback label.authoring.advance.add.feedback.field =Add feedback label.authoring.advance.question.etherpad = Include discussion pad for questions +label.authoring.advance.answer.justification = Allow answer justification label.authoring.cancel.button =Cancel label.authoring.basic.answer.options =Answer options label.authoring.basic.instruction =Instructions @@ -380,6 +381,8 @@ label.someone.allocated.this.answer =Sorry, someone has allocated this answer already label.monitoring.user.summary.full.name =Full name label.etherpad.discussion = Discussion +label.answer.justification = Justification +label.answer.justification.prompt = Please justify your answer... label.answer.rating.title = Other teams' feedback label.average.rating =Average rating {0}/{1} votes label.your.rating =Your rating {0}, average rating {1}/{2} votes Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java =================================================================== diff -u -r5b3de375324cb89215865883a2658932ff2bd846 -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java (.../AssessmentConstants.java) (revision 5b3de375324cb89215865883a2658932ff2bd846) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java (.../AssessmentConstants.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -89,6 +89,8 @@ public static final String ATTR_CONFIDENCE_LEVEL_PREFIX = "confidenceLevel"; + public static final String ATTR_ANSWER_JUSTIFICATION_PREFIX = "answerJustification"; + public static final String ATTR_QUESTION_LIST = "questionList"; public static final String ATTR_RANDOM_POOL_QUESTIONS = "randomPoolQuestions"; @@ -211,6 +213,6 @@ public static final String CONFIG_KEY_HIDE_TITLES = "hideTitles"; public static final String ATTR_IS_QUESTION_ETHERPAD_ENABLED = "isQuestionEtherpadEnabled"; - + public static final String ATTR_ALL_GROUP_USERS = "allGroupUsers"; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20200624.sql =================================================================== diff -u --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20200624.sql (revision 0) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20200624.sql (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -0,0 +1,17 @@ +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; +SET FOREIGN_KEY_CHECKS=0; +-- Put all sql statements below here + +--LDEV-5033 Add justification to question answer in Assessment + +ALTER TABLE tl_laasse10_question_result ADD COLUMN justification VARCHAR(10000); +ALTER TABLE tl_laasse10_assessment ADD COLUMN allow_answer_justification TINYINT DEFAULT 0 AFTER allow_history_responses; + + +-- Put all sql statements above here + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; +SET FOREIGN_KEY_CHECKS=1; Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/QuestionDTO.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/QuestionDTO.java (.../QuestionDTO.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/QuestionDTO.java (.../QuestionDTO.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -10,12 +10,12 @@ import org.lamsfoundation.lams.qb.model.QbToolQuestion; import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestion; -public class QuestionDTO implements Comparable{ +public class QuestionDTO implements Comparable { // ============= immutable properties copied from AssessmentQuestion question ============= private Long uid; - + private Long qbQuestionUid; private Integer type; @@ -61,15 +61,15 @@ private int minWordsLimit; private boolean hedgingJustificationEnabled; - + private boolean autocompleteEnabled; private boolean correctAnswersDisclosed; private boolean groupsAnswersDisclosed; // ============= variable properties ============= - + private String titleEscaped; private String answer; @@ -80,6 +80,8 @@ private String questionFeedback; + private String justification; + private boolean responseSubmitted; private float mark; @@ -98,25 +100,25 @@ /** * Expanded version of the constructor which also sets correctAnswersDisclosed and groupsAnswersDisclosed. - * + * * @param assessmentQuestion */ public QuestionDTO(AssessmentQuestion assessmentQuestion) { this((QbToolQuestion) assessmentQuestion); - + this.correctAnswersDisclosed = assessmentQuestion.isCorrectAnswersDisclosed(); this.groupsAnswersDisclosed = assessmentQuestion.isGroupsAnswersDisclosed(); } - + /** * Same as above, but skips setting correctAnswersDisclosed and groupsAnswersDisclosed - * + * * @param qbToolQuestion */ public QuestionDTO(QbToolQuestion qbToolQuestion) { this.uid = qbToolQuestion.getUid(); this.displayOrder = qbToolQuestion.getDisplayOrder(); - + QbQuestion qbQuestion = qbToolQuestion.getQbQuestion(); this.type = qbQuestion.getType(); this.title = qbQuestion.getName(); @@ -146,7 +148,7 @@ optionDtos.add(new OptionDTO(option)); } } - + @Override public int compareTo(QuestionDTO anotherQuestion) { return displayOrder - anotherQuestion.getDisplayOrder(); @@ -159,7 +161,7 @@ public void setUid(Long userID) { this.uid = userID; } - + public Long getQbQuestionUid() { return qbQuestionUid; } @@ -335,7 +337,7 @@ public void setHedgingJustificationEnabled(boolean hedgingJustificationEnabled) { this.hedgingJustificationEnabled = hedgingJustificationEnabled; } - + public boolean isAutocompleteEnabled() { return autocompleteEnabled; } @@ -385,6 +387,18 @@ return questionFeedback; } + public String getJustification() { + return justification; + } + + public void setJustification(String justification) { + this.justification = justification; + } + + public String getJustificationHtml() { + return justification == null ? null : justification.replace("\n", "
"); + } + public Float getMark() { return mark; } @@ -456,7 +470,7 @@ public void setPrefixAnswersWithLetters(boolean prefixAnswersWithLetters) { this.prefixAnswersWithLetters = prefixAnswersWithLetters; } - + public String getTitleEscaped() { return titleEscaped; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java =================================================================== diff -u -r50e336123ddaab4628f5f94f795340c8e845c6df -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java (.../Assessment.java) (revision 50e336123ddaab4628f5f94f795340c8e845c6df) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java (.../Assessment.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -139,6 +139,9 @@ @Column(name = "allow_history_responses") private boolean allowHistoryResponses; + @Column(name = "allow_answer_justification") + private boolean allowAnswerJustification; + @Column(name = "display_summary") private boolean displaySummary; @@ -603,6 +606,14 @@ this.allowHistoryResponses = allowHistoryResponses; } + public boolean isAllowAnswerJustification() { + return allowAnswerJustification; + } + + public void setAllowAnswerJustification(boolean allowAnswerJustification) { + this.allowAnswerJustification = allowAnswerJustification; + } + public boolean isDisplaySummary() { return displaySummary; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java =================================================================== diff -u -r2b3d3b2f61d37cf2fa7cccc0cf4565e5dfc4b88e -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java (.../AssessmentQuestionResult.java) (revision 2b3d3b2f61d37cf2fa7cccc0cf4565e5dfc4b88e) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java (.../AssessmentQuestionResult.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -38,6 +38,7 @@ import javax.persistence.Table; import javax.persistence.Transient; +import org.apache.commons.lang.StringEscapeUtils; import org.lamsfoundation.lams.qb.model.QbQuestion; import org.lamsfoundation.lams.qb.model.QbToolAnswer; import org.lamsfoundation.lams.tool.assessment.dto.QuestionDTO; @@ -74,6 +75,9 @@ @Column(name = "confidence_level") private int confidenceLevel; + @Column + private String justification; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "result_uid") private AssessmentResult assessmentResult; @@ -185,6 +189,18 @@ this.confidenceLevel = confidenceLevel; } + public String getJustification() { + return justification; + } + + public void setJustification(String justification) { + this.justification = justification; + } + + public String getJustificationEscaped() { + return justification == null ? null : StringEscapeUtils.escapeJavaScript(justification.replace("\r\n", "
")); + } + public AssessmentUser getUser() { return user; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r897ad3c3694440281f178d7834a9233d62c4e874 -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 897ad3c3694440281f178d7834a9233d62c4e874) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -264,6 +264,8 @@ userOptionAnswer.setOptionUid(leaderOptionAnswer.getOptionUid()); userOptionAnswers.add(userOptionAnswer); } + + userQuestionResult.setJustification(leaderQuestionResult.getJustification()); } } @@ -708,6 +710,11 @@ questionResult.setConfidenceLevel(questionDto.getConfidenceLevel()); } + // store justification entered by the learner + if (assessment.isAllowAnswerJustification()) { + questionResult.setJustification(questionDto.getJustification()); + } + return questionResult; } @@ -943,6 +950,7 @@ questionDto.setAnswerBoolean(questionResult.getAnswerBoolean()); questionDto.setAnswerFloat(questionResult.getAnswerFloat()); questionDto.setAnswer(questionResult.getAnswer()); + questionDto.setJustification(questionResult.getJustification()); questionDto.setMark(questionResult.getMark()); questionDto.setResponseSubmitted(questionResult.getFinishDate() != null); questionDto.setPenalty(questionResult.getPenalty()); @@ -1775,6 +1783,10 @@ ExcelCell.BORDER_STYLE_BOTTOM_THIN); questionTitleRow.addCell(getMessage("label.export.time.taken"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); questionTitleRow.addCell(getMessage("label.export.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + if (assessment.isAllowAnswerJustification()) { + questionTitleRow.addCell(getMessage("label.answer.justification"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + } int questionNumber = 1; @@ -1891,6 +1903,12 @@ //mark userResultRow.addCell(questionResult.getMark()); + + if (assessment.isAllowAnswerJustification()) { + userResultRow.addCell(AssessmentEscapeUtils + .escapeStringForExcelExport(questionResult.getJustification())); + } + questionSummaryTabTemp.add(userResultRow); //calculating markCount & markTotal @@ -2030,6 +2048,10 @@ } userTitleRow.addCell(getMessage("label.export.mark"), true); + if (assessment.isAllowAnswerJustification()) { + userTitleRow.addCell(getMessage("label.answer.justification"), true); + } + AssessmentResult assessmentResult = userUidToResultMap.get(assessmentUser.getUid()); if (assessmentResult != null) { Set questionResults = assessmentResult.getQuestionResults(); @@ -2064,7 +2086,13 @@ userResultRow.addCell(confidenceLevel); } + userResultRow.addCell(questionResult.getMark()); + + if (assessment.isAllowAnswerJustification()) { + userResultRow.addCell(AssessmentEscapeUtils + .escapeStringForExcelExport(questionResult.getJustification())); + } } } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/util/AssessmentEscapeUtils.java =================================================================== diff -u -r0306bfaf661b3900cd5fdf901c2cfcb26493817e -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/util/AssessmentEscapeUtils.java (.../AssessmentEscapeUtils.java) (revision 0306bfaf661b3900cd5fdf901c2cfcb26493817e) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/util/AssessmentEscapeUtils.java (.../AssessmentEscapeUtils.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -233,8 +233,7 @@ switch (questionResult.getQbQuestion().getType()) { case QbQuestion.TYPE_ESSAY: String answer = questionResult.getAnswer(); - return (answer == null) ? "" - : answer.replaceAll("\\<.*?>", "").replaceAll(" ", " "); + return AssessmentEscapeUtils.escapeStringForExcelExport(answer); case QbQuestion.TYPE_MATCHING_PAIRS: return AssessmentEscapeUtils.getOptionResponse(questionResult, QbQuestion.TYPE_MATCHING_PAIRS); case QbQuestion.TYPE_MULTIPLE_CHOICE: @@ -256,6 +255,10 @@ return ret; } + public static String escapeStringForExcelExport(String input) { + return input == null ? "" : input.replaceAll("\\<.*?>", "").replaceAll(" ", " "); + } + /** * Used only for excell export (for getUserSummaryData() method). */ Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java =================================================================== diff -u -r5b3de375324cb89215865883a2658932ff2bd846 -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision 5b3de375324cb89215865883a2658932ff2bd846) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -885,11 +885,18 @@ AssessmentConstants.ATTR_CONFIDENCE_LEVEL_PREFIX + i); questionDto.setConfidenceLevel(confidenceLevel); } + + // store justification entered by the learner + if (assessment.isAllowAnswerJustification()) { + String justification = WebUtil.readStrParam(request, + AssessmentConstants.ATTR_ANSWER_JUSTIFICATION_PREFIX + i, true); + questionDto.setJustification(justification); + } } } /** - * Checks whether all required questions were answered and all essay question with min words limit have fullfilled + * Checks whether all required questions were answered and all essay question with min words limit have fulfilled * that. * * @param sessionMap @@ -1042,6 +1049,10 @@ questionDto.setAnswerBoolean(isAnsweredCorrectly); } + if (StringUtils.isNotBlank(questionResult.getJustification())) { + questionDto.setJustification(questionResult.getJustification()); + } + // required for markandpenalty area and if it's on - on question's summary page List questionResults = service .getAssessmentQuestionResultList(assessment.getUid(), userId, questionDto.getUid()); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java =================================================================== diff -u -r897ad3c3694440281f178d7834a9233d62c4e874 -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 897ad3c3694440281f178d7834a9233d62c4e874) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -575,7 +575,14 @@ userData.add(starString); } - userData.add(AssessmentEscapeUtils.printResponsesForJqgrid(questionResult)); + String response = AssessmentEscapeUtils.printResponsesForJqgrid(questionResult); + + if (StringUtils.isNotBlank(questionResult.getJustification())) { + response += "
" + service.getMessage("label.answer.justification") + "
" + + questionResult.getJustificationEscaped(); + } + + userData.add(response); } else { userData.add(""); userData.add(""); @@ -627,6 +634,10 @@ throw new IllegalArgumentException("There can be only one criterion for an Assessment activity. " + "If other criteria are introduced, the criterion for rating other groups' answers needs to become uniquely identifiable."); } + if (criteria.isEmpty()) { + // criteria were not yet created in learner results page + return null; + } Long ratingCriteriaId = criteria.get(0).getRatingCriteriaId(); List ratings = ratingService.getRatingsByCriteriasAndItems(Arrays.asList(ratingCriteriaId), Index: lams_tool_assessment/web/pages/authoring/advance.jsp =================================================================== diff -u -r50e336123ddaab4628f5f94f795340c8e845c6df -r0dc158981713b0ab875102e364bd7c4a3a0e2235 --- lams_tool_assessment/web/pages/authoring/advance.jsp (.../advance.jsp) (revision 50e336123ddaab4628f5f94f795340c8e845c6df) +++ lams_tool_assessment/web/pages/authoring/advance.jsp (.../advance.jsp) (revision 0dc158981713b0ab875102e364bd7c4a3a0e2235) @@ -229,6 +229,13 @@
+ +
+ +