Index: lams_central/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rdae7eeb158338a956aaec37705b0c1efb18be6f6 -rba6d2394558dc6e82f56561d0913c9e75d000e89 --- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision dae7eeb158338a956aaec37705b0c1efb18be6f6) +++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision ba6d2394558dc6e82f56561d0913c9e75d000e89) @@ -787,10 +787,12 @@ authoring.error.numlearners=Number of learners must be 1 to 99. authoring.error.group.data=Group settings are not correct. authoring.section.lessondetails=Lesson Details -authoring.section.questionsanalysis=Questions & Analysis +authoring.section.questions=Questions authoring.section.applicationexercise=Application Exercise authoring.section.introduction=Introduction authoring.create.question=Create Question +authoring.create.essay.question=Create Essay Question +authoring.create.mc.question=Create Multiple Choice Question authoring.label.application.exercise.num=Application Exercise {0} authoring.error.application.exercise.num=Application Exercise {0} may not be blank. authoring.label.question.num=Question {0} @@ -804,6 +806,11 @@ authoring.error.content.id=Content ID is missing authoring.error.question.correct.num=One of the answers for Question {0} needs to be correct. authoring.error.question.must.have.answer.num=Question {0} must have at least one answer. +authoring.error.application.exercise.must.have.answer.num=Application Exercise {0} must have at least one answer. +authoring.error.application.exercise.must.have.100.percent=Application Exercise {0} must have at least one answer worth 100%. +authoring.error.application.exercise.not.blank.and.grade=Application Exercise {0} may not be blank and must have a grade. +authoring.label.grade=Grade +authoring.label.none=None #=================== Specific to Team Based Learning (TBL) =========================# authoring.tbl.template.title=Team Based Learning Index: lams_central/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -r4c51f9c8b6fab7efa4d5296f1ee60c1c3bd207e5 -rba6d2394558dc6e82f56561d0913c9e75d000e89 --- lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 4c51f9c8b6fab7efa4d5296f1ee60c1c3bd207e5) +++ lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision ba6d2394558dc6e82f56561d0913c9e75d000e89) @@ -787,10 +787,12 @@ authoring.error.numlearners=Number of learners must be 1 to 99. authoring.error.group.data=Group settings are not correct. authoring.section.lessondetails=Lesson Details -authoring.section.questionsanalysis=Questions & Analysis +authoring.section.questions=Questions authoring.section.applicationexercise=Application Exercise authoring.section.introduction=Introduction authoring.create.question=Create Question +authoring.create.essay.question=Create Essay Question +authoring.create.mc.question=Create Multiple Choice Question authoring.label.application.exercise.num=Application Exercise {0} authoring.error.application.exercise.num=Application Exercise {0} may not be blank. authoring.label.question.num=Question {0} Index: lams_central/src/java/org/lamsfoundation/lams/authoring/template/Assessment.java =================================================================== diff -u --- lams_central/src/java/org/lamsfoundation/lams/authoring/template/Assessment.java (revision 0) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/template/Assessment.java (revision ba6d2394558dc6e82f56561d0913c9e75d000e89) @@ -0,0 +1,156 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.authoring.template; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.ResourceBundle; + +import org.apache.tomcat.util.json.JSONArray; +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; +import org.lamsfoundation.lams.rest.RestTags; + +/** Simple assessment object used for parsing survey data before conversion to JSON */ +public class Assessment { + + // assessment type - copied from ResourceConstants + // question type; + public static final short ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE = 1; +// public static final short ASSESSMENT_QUESTION_TYPE_MATCHING_PAIRS = 2; +// public static final short ASSESSMENT_QUESTION_TYPE_SHORT_ANSWER = 3; +// public static final short ASSESSMENT_QUESTION_TYPE_NUMERICAL = 4; +// public static final short ASSESSMENT_QUESTION_TYPE_TRUE_FALSE = 5; + public static final short ASSESSMENT_QUESTION_TYPE_ESSAY = 6; +// public static final short ASSESSMENT_QUESTION_TYPE_ORDERING = 7; + + short type = 6; + String title = null; + String questionText = null; + Boolean required = false; + List answers = null; // only used if type == 1 + + public void setType(short type) { + this.type = type; + if (type == 1 && this.answers == null) + this.answers = new LinkedList(); + } + + public void setType(String type) { + if (type != null && type.equalsIgnoreCase("mcq")) + setType(ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE); + else + setType(ASSESSMENT_QUESTION_TYPE_ESSAY); + } + + public short getType() { + return type; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + public Boolean getRequired() { + return required; + } + + public void setQuestionText(String questionText) { + this.questionText = questionText; + } + + public String getQuestionText() { + return questionText; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + + public List getAnswers() { + return answers; + } + + public JSONObject getAsJSONObject(int displayOrder) throws JSONException { + JSONObject json = new JSONObject(); + json.put(RestTags.QUESTION_TITLE, title != null ? title : ""); + json.put(RestTags.QUESTION_TEXT, questionText != null ? questionText : ""); + json.put(RestTags.DISPLAY_ORDER, displayOrder); + json.put("answerRequired", required); + if (type == ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE) { + json.put("type", ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE); + JSONArray answersJSON = new JSONArray(); + for (AssessMCAnswer answer : answers) { + answersJSON.put(answer.getAsJSONObject()); + } + json.put(RestTags.ANSWERS, answersJSON); + } else { + json.put("type", ASSESSMENT_QUESTION_TYPE_ESSAY); + } + return json; + } + + private List addError(List errorMessages, String errorMessage) { + if (errorMessages == null) { + errorMessages = new ArrayList(); + } + errorMessages.add(errorMessage); + return errorMessages; + } + + /** If no errors exist, returns null */ + public List validate(ResourceBundle appBundle, MessageFormat formatter, Integer questionNumber) { + List errorMessages = null; + if (questionText == null || questionText.length() == 0) { + errorMessages = addError(errorMessages, + TextUtil.getText(appBundle, formatter, "authoring.error.application.exercise.num", new Object[] { questionNumber })); + } + if (type == ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE) { + if (answers.size() == 0) { + errorMessages = addError(errorMessages, TextUtil.getText(appBundle, formatter, + "authoring.error.application.exercise.must.have.answer.num", new Object[] { questionNumber })); + } else { + boolean found100percent = false; + for (AssessMCAnswer answer : answers) { + if (answer.getGrade() == 1) { + found100percent = true; + break; + } + } + if (!found100percent) { + errorMessages = addError(errorMessages, + TextUtil.getText(appBundle, formatter, "authoring.error.application.exercise.must.have.100.percent", new Object[] { questionNumber })); + } + } + } + return errorMessages; + } +} Index: lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateAction.java =================================================================== diff -u -r4972b394013bef3bc563652df80d9c2dbb04e238 -rba6d2394558dc6e82f56561d0913c9e75d000e89 --- lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateAction.java (.../LdTemplateAction.java) (revision 4972b394013bef3bc563652df80d9c2dbb04e238) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateAction.java (.../LdTemplateAction.java) (revision ba6d2394558dc6e82f56561d0913c9e75d000e89) @@ -26,7 +26,6 @@ import java.io.IOException; import java.text.MessageFormat; import java.util.LinkedList; -import java.util.List; import java.util.ResourceBundle; import java.util.Set; import java.util.TreeMap; @@ -47,7 +46,6 @@ import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.authoring.service.IAuthoringService; -import org.lamsfoundation.lams.authoring.template.AssessMCAnswer; import org.lamsfoundation.lams.authoring.template.Option; import org.lamsfoundation.lams.authoring.template.TextUtil; import org.lamsfoundation.lams.learningdesign.Activity; @@ -78,7 +76,7 @@ public abstract class LdTemplateAction extends DispatchAction { private static Logger log = Logger.getLogger(LdTemplateAction.class); - public static final int MAX_OPTION_COUNT = 5; + public static final int MAX_OPTION_COUNT = 6; public static final int MAX_FLOATING_ACTIVITY_OPTIONS = 6; // Hardcoded in the Flash client public static final String PARENT_ACTIVITY_TYPE = "parentActivityType"; // used to work out transitions - not used by the authoring module @@ -728,11 +726,12 @@ * to be expanded. */ protected Long createAssessmentToolContent(UserDTO user, String title, String instructions, - String reflectionInstructions, JSONArray questions) + String reflectionInstructions, boolean selectLeaderToolOutput, JSONArray questions) throws JSONException, HttpException, IOException { JSONObject toolContentJSON = createStandardToolContent(title, instructions, reflectionInstructions, null, null, user); + toolContentJSON.put(RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, selectLeaderToolOutput); toolContentJSON.put(RestTags.QUESTIONS, questions); JSONArray references = new JSONArray(); @@ -746,40 +745,6 @@ return createToolContent(user, LdTemplateAction.ASSESSMENT_TOOL_SIGNATURE, toolContentJSON); } - // assessment type - copied from ResourceConstants - // question type; - public static final short ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE = 1; - public static final short ASSESSMENT_QUESTION_TYPE_MATCHING_PAIRS = 2; - public static final short ASSESSMENT_QUESTION_TYPE_SHORT_ANSWER = 3; - public static final short ASSESSMENT_QUESTION_TYPE_NUMERICAL = 4; - public static final short ASSESSMENT_QUESTION_TYPE_TRUE_FALSE = 5; - public static final short ASSESSMENT_QUESTION_TYPE_ESSAY = 6; - public static final short ASSESSMENT_QUESTION_TYPE_ORDERING = 7; - - protected JSONObject createAssessmentQuestionEssayType(String questionTitle, String questionText, int displayOrder, - boolean required) throws JSONException { - JSONObject essayJSON = new JSONObject(); - essayJSON.put(RestTags.QUESTION_TITLE, questionTitle != null ? questionTitle : ""); - essayJSON.put(RestTags.QUESTION_TEXT, questionText != null ? questionText : ""); - essayJSON.put("type", ASSESSMENT_QUESTION_TYPE_ESSAY); - essayJSON.put(RestTags.DISPLAY_ORDER, displayOrder); - essayJSON.put("answerRequired", required); - return essayJSON; - } - - protected JSONObject createAssessmentQuestionMultipleChoiceType(String questionTitle, String questionText, - int displayOrder, boolean required, List answers) throws JSONException { - JSONObject mcJSON = createAssessmentQuestionEssayType(questionTitle, questionText, displayOrder, required); - JSONArray answersJSON = new JSONArray(); - for (AssessMCAnswer answer : answers) { - answersJSON.put(answer.getAsJSONObject()); - } - mcJSON.put(RestTags.ANSWERS, answersJSON); - mcJSON.put("type", ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE); - log.debug("assessment: " + mcJSON); - return mcJSON; - } - /** * Creates a forum activity's JSON details. */ @@ -1126,7 +1091,6 @@ JSONObject toolContentJSON = createStandardToolContent(title, instructions, null, null, null, null); toolContentJSON.put(RestTags.QUESTIONS, questions); - toolContentJSON.put(RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, useSelectLeaderToolOuput); return createToolContent(user, LdTemplateAction.SCRATCHIE_TOOL_SIGNATURE, toolContentJSON); } @@ -1362,12 +1326,20 @@ /** * Specialised call to create a new question for the Assessment fields. Returns a fragment of HTML - * which sets up a new CKEditor. + * which sets up a new CKEditor. Defaults to essay. If questionType = "mcq" then it will do a multiple choice */ public ActionForward createAssessment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { + request.setAttribute("questionNumber", WebUtil.readIntParam(request, "questionNumber")); - return mapping.findForward("assess"); + + String questionType = WebUtil.readStrParam(request, "questionType"); + if (questionType == null || !questionType.equalsIgnoreCase("mcq")) { + return mapping.findForward("assess"); + } else { + return mapping.findForward("assessmcq"); + } + } /** @@ -1397,23 +1369,27 @@ } /** - * Specialised call to create a new option for a multiple choice question (mcoption.jsp) or Survey question - * (surveyoption.jsp) Returns a fragment of HTML which sets up the editing field. The template's + * Specialised call to create a new option for a multiple choice question (mcoption.jsp), Survey question + * (surveyoption.jsp) or assessment multiple choice (assessmcq.jsp). + * Returns a fragment of HTML which sets up the editing field. The template's * struts action determines which jsp is used (see TBL and Inquiry uses). */ public ActionForward createOption(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { request.setAttribute("questionNumber", WebUtil.readIntParam(request, "questionNumber")); request.setAttribute("optionNumber", WebUtil.readIntParam(request, "optionNumber")); - return mapping.findForward("questionoption"); + boolean useAssessmentVersion = WebUtil.readBooleanParam(request, "assess", false); + return mapping.findForward(useAssessmentVersion?"assessoption":"questionoption"); } public ActionForward deleteOption(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { Integer questionNumber = WebUtil.readIntParam(request, "questionNumber", true); Integer delete = WebUtil.readIntParam(request, "optionNumber"); - TreeMap optionsMap = getOptions(request, questionNumber); + boolean useAssessmentVersion = WebUtil.readBooleanParam(request, "assess", false); + + TreeMap optionsMap = getOptions(request, questionNumber, useAssessmentVersion); optionsMap.remove(delete); // reorder the displayOrder and setup the return value LinkedList