/** * OLAT - Online Learning and Training<br> * http://www.olat.org * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> * University of Zurich, Switzerland. * <hr> * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * This file has been modified by the OpenOLAT community. Changes are licensed * under the Apache 2.0 license as the original file. */ package org.olat.course.condition; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.DependencyRuleApplayable; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.FormItemDependencyRule; import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.elements.IntegerElement; import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.form.flexible.impl.elements.FormLinkImpl; import org.olat.core.gui.components.form.flexible.impl.elements.JSDateChooser; import org.olat.core.gui.components.form.flexible.impl.rules.RulesFactory; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.util.StringHelper; import org.olat.core.util.event.EventBus; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.event.MultiUserEvent; import org.olat.core.util.resource.OresHelper; import org.olat.course.assessment.AssessmentModule; import org.olat.course.condition.interpreter.ConditionDateFormatter; import org.olat.course.editor.CourseEditorEnv; import org.olat.course.nodes.CourseNode; import org.olat.group.BusinessGroupService; import org.olat.group.BusinessGroupShort; import org.olat.group.area.BGArea; import org.olat.group.area.BGAreaManager; import org.olat.group.ui.NewAreaController; import org.olat.group.ui.NewBGController; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryManagedFlag; import org.olat.repository.RepositoryManager; import org.olat.resource.OLATResource; import org.olat.shibboleth.ShibbolethModule; import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> * The ConditionConfigEasyController implements the easy condition editing * workflow in the course editor. It has several complex dependency rules to * show and hide form input fields, and also the possibility to start * subworkflows for creation of groups or areas. * <P> * Initial Date: 13.06.2007 <br> * * @author patrickb */ public class ConditionConfigEasyController extends FormBasicController implements GenericEventListener { private Condition validatedCondition; private CourseEditorEnv courseEditorEnv; private List<CourseNode> nodeIdentList; //private FormReset reset; private MultipleSelectionElement coachExclusive, assessmentMode; private JSDateChooser fromDate; private JSDateChooser toDate; private FormItemContainer dateSubContainer, groupSubContainer, assessSubContainer; private FormLayoutContainer areaChooseSubContainer, groupChooseSubContainer; private MultipleSelectionElement dateSwitch; private StaticTextElement easyGroupList; private FormLink chooseGroupsLink; private StaticTextElement easyAreaList; private FormLink chooseAreasLink; private MultipleSelectionElement groupSwitch; private GroupSelectionController groupChooseC; private AreaSelectionController areaChooseC; private FormLink fixGroupError; private FormLink fixAreaError; private MultipleSelectionElement assessmentSwitch; private SingleSelection assessmentTypeSwitch; private SingleSelection nodePassed; // private MultipleSelectionElement attributeSwitch; private SingleSelection attributeBconnector; private AttributeEasyRowAdderController attribteRowAdderSubform; // private IntegerElement cutValue; private MultipleSelectionElement applyRulesForCoach; private NewBGController groupCreateCtlr; private CloseableModalController cmc; private NewAreaController areaCreateCtlr; private FormLink createGroupsLink; private FormLink createAreasLink; private static final String NODEPASSED_VAL_PASSED = "passed"; private static final String NODEPASSED_VAL_SCORE = "score"; private static final String DELETED_NODE_IDENTIFYER = "deletedNode"; private static final String NO_NODE_SELECTED_IDENTIFYER = ""; protected static final String BCON_VAL_OR = "bcon_or"; protected static final String BCON_VAL_AND = "bcon_and"; private EventBus singleUserEventCenter; private OLATResourceable groupConfigChangeEventOres; @Autowired private BGAreaManager areaManager; @Autowired private ShibbolethModule shibbolethModule; @Autowired private BusinessGroupService businessGroupService; @Autowired private AssessmentModule assessmentModule; private boolean managedGroup; /** * with default layout <tt>_content/easycondedit.html</tt> * * @param ureq * @param wControl * @param groupMgr The course group manager * @param cond condition for initialisation * @param title The title that should be displayed for this condition * @param formName Name of the condition form - must be unique within a HTML * page * @param nodeIdentList * @param euce */ public ConditionConfigEasyController(UserRequest ureq, WindowControl wControl, Condition cond, List<CourseNode> nodeIdentList, CourseEditorEnv env) { super(ureq, wControl, "easycondedit"); singleUserEventCenter = ureq.getUserSession().getSingleUserEventCenter(); groupConfigChangeEventOres = OresHelper.createOLATResourceableType(MultiUserEvent.class); singleUserEventCenter.registerFor(this, ureq.getIdentity(), groupConfigChangeEventOres); OLATResource courseResource = env.getCourseGroupManager().getCourseResource(); RepositoryEntry courseRe = RepositoryManager.getInstance().lookupRepositoryEntry(courseResource, false); managedGroup = RepositoryEntryManagedFlag.isManaged(courseRe, RepositoryEntryManagedFlag.groups); /* * my instance variables, these data is used by form items to initialise */ this.validatedCondition = cloneCondition(cond); if (this.validatedCondition == null) throw new OLATRuntimeException( "CondititionEditController called with a NULL condition", new IllegalArgumentException() ); this.courseEditorEnv = env; this.nodeIdentList = nodeIdentList; initForm(ureq); } /** * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose(boolean) */ @Override protected void doDispose() { singleUserEventCenter.deregisterFor(this, groupConfigChangeEventOres); } /** * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formOK(org.olat.core.gui.UserRequest) */ @Override protected void formOK(UserRequest ureq) { // 1) rule applies also for coach switch - one checkbox // has opposite meaning -> selected is saved as false, and vice versa if (applyRulesForCoach.getSelectedKeys().size() == 0) { validatedCondition.setEasyModeAlwaysAllowCoachesAndAdmins(true); } else { validatedCondition.setEasyModeAlwaysAllowCoachesAndAdmins(false); } // 2) admin and coach switch - one checkbox if (coachExclusive.getSelectedKeys().size() == 1) { validatedCondition.setEasyModeCoachesAndAdmins(true); // when true discard all other rules validatedCondition.setEasyModeBeginDate(null); validatedCondition.setEasyModeEndDate(null); validatedCondition.setEasyModeGroupAccess(null); validatedCondition.setEasyModeGroupAreaAccess(null); validatedCondition.setEasyModeCutValue(null); validatedCondition.setEasyModeNodePassedId(null); validatedCondition.setAttributeConditions(null); validatedCondition.setAttributeConditionsConnectorIsAND(null); validatedCondition.setAssessmentMode(false); } else { validatedCondition.setEasyModeCoachesAndAdmins(false); // 3) date switch if (dateSwitch.getSelectedKeys().size() == 1) { if (StringHelper.containsNonWhitespace(fromDate.getValue())) { validatedCondition.setEasyModeBeginDate(ConditionDateFormatter.format(fromDate.getDate())); } else { validatedCondition.setEasyModeBeginDate(null); } if (StringHelper.containsNonWhitespace(toDate.getValue())) { validatedCondition.setEasyModeEndDate(ConditionDateFormatter.format(toDate.getDate())); } else { validatedCondition.setEasyModeEndDate(null); } } else { validatedCondition.setEasyModeBeginDate(null); validatedCondition.setEasyModeEndDate(null); } // 4) group switch if (groupSwitch.getSelectedKeys().size() == 1) { // groups if (!isEmpty(easyGroupList)) { validatedCondition.setEasyModeGroupAccessIdList(getKeys(easyGroupList)); } else { validatedCondition.setEasyModeGroupAccess(null); } // areas if (!isEmpty(easyAreaList)) { validatedCondition.setEasyModeGroupAreaAccessIdList(getKeys(easyAreaList)); } else { validatedCondition.setEasyModeGroupAreaAccess(null); } } else { validatedCondition.setEasyModeGroupAccess(null); validatedCondition.setEasyModeGroupAccessIdList(null); validatedCondition.setEasyModeGroupAreaAccess(null); validatedCondition.setEasyModeGroupAreaAccessIdList(null); } // 5) assessment switch if (assessmentSwitch.getSelectedKeys().size() == 1) { // now evaluate the selection // which node, if one is selected if (!nodePassed.getSelectedKey().equals("")) { validatedCondition.setEasyModeNodePassedId(nodePassed.getSelectedKey()); } else { validatedCondition.setEasyModeNodePassedId(null); } if (assessmentTypeSwitch.getSelectedKey().equals(NODEPASSED_VAL_SCORE)) { // this is formOK -> value of integer elment is ensured to be an // int! validatedCondition.setEasyModeCutValue(cutValue.getValue()); } else { validatedCondition.setEasyModeCutValue(null); } } else { validatedCondition.setEasyModeNodePassedId(null); if(nodeIdentList.size()==0) { assessmentSwitch.setEnabled(false); } } // 6) attribute switch if (shibbolethModule.isEnableShibbolethLogins()) { if (attributeSwitch.getSelectedKeys().size() == 1) { List<ExtendedCondition> le = attribteRowAdderSubform.getAttributeConditions(); if (le.size() < 1) { // some error(s) occured, don't save anything validatedCondition.setAttributeConditions(null); } else { // add the conditions validatedCondition.setAttributeConditions(le); } validatedCondition.setAttributeConditionsConnectorIsAND(new Boolean(attributeBconnector.getSelectedKey().equals(BCON_VAL_AND))); } else { validatedCondition.setAttributeConditions(null); validatedCondition.setAttributeConditionsConnectorIsAND(null); } } // assessment mode validatedCondition.setAssessmentMode(assessmentMode.isAtLeastSelected(1)); } // calculate expression from easy mode form String condString = validatedCondition.getConditionFromEasyModeConfiguration(); validatedCondition.setConditionExpression(condString); validatedCondition.setExpertMode(false); /* * condition is updated */ // Inform all listeners about the changed condition fireEvent(ureq, Event.CHANGED_EVENT); } @Override public void event(Event event) { if (event.getCommand().equals("changed")) { updateGroupsAndAreasCheck(); validateGroupFields(); } } @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if (source == chooseGroupsLink) { removeAsListenerAndDispose(cmc); removeAsListenerAndDispose(groupChooseC); List<Long> groupKeys = getKeys(easyGroupList); groupChooseC = new GroupSelectionController(ureq, getWindowControl(), true, courseEditorEnv.getCourseGroupManager(), groupKeys); listenTo(groupChooseC); cmc = new CloseableModalController( getWindowControl(), "close", groupChooseC.getInitialComponent(), true, getTranslator().translate("popupchoosegroups")); listenTo(cmc); cmc.activate(); } else if (source == createGroupsLink) { removeAsListenerAndDispose(cmc); removeAsListenerAndDispose(groupCreateCtlr); OLATResource courseResource = courseEditorEnv.getCourseGroupManager().getCourseResource(); RepositoryEntry courseRe = RepositoryManager.getInstance().lookupRepositoryEntry(courseResource, false); groupCreateCtlr = new NewBGController(ureq, getWindowControl(), courseRe, true, null); listenTo(groupCreateCtlr); cmc = new CloseableModalController(getWindowControl(), "close", groupCreateCtlr.getInitialComponent()); listenTo(cmc); cmc.activate(); } else if (source == chooseAreasLink) { removeAsListenerAndDispose(cmc); removeAsListenerAndDispose(areaChooseC); areaChooseC = new AreaSelectionController(ureq, getWindowControl(), true, courseEditorEnv.getCourseGroupManager(), getKeys(easyAreaList)); listenTo(areaChooseC); cmc = new CloseableModalController( getWindowControl(), "close", areaChooseC.getInitialComponent(), true, getTranslator().translate("popupchooseareas")); listenTo(cmc); cmc.activate(); } else if (source == createAreasLink) { removeAsListenerAndDispose(cmc); removeAsListenerAndDispose(areaCreateCtlr); OLATResource courseResource = courseEditorEnv.getCourseGroupManager().getCourseResource(); areaCreateCtlr = new NewAreaController(ureq, getWindowControl(), courseResource, true, null); listenTo(areaCreateCtlr); cmc = new CloseableModalController(getWindowControl(), "close",areaCreateCtlr.getInitialComponent()); listenTo(cmc); cmc.activate(); } else if (source == fixGroupError) { // user wants to fix problem with fixing group error link e.g. create one // or more group at once. String[] csvGroupName = (String[]) fixGroupError.getUserObject(); OLATResource courseResource = courseEditorEnv.getCourseGroupManager().getCourseResource(); RepositoryEntry courseRe = RepositoryManager.getInstance().lookupRepositoryEntry(courseResource, false); removeAsListenerAndDispose(groupCreateCtlr); groupCreateCtlr = new NewBGController(ureq, getWindowControl(), courseRe, true, csvGroupName[0]); listenTo(groupCreateCtlr); removeAsListenerAndDispose(cmc); cmc = new CloseableModalController(getWindowControl(), "close", groupCreateCtlr.getInitialComponent()); listenTo(cmc); cmc.activate(); } else if (source == fixAreaError) { /* * user wants to fix problem with fixing area error link e.g. create one * or more areas at once. */ String[] csvAreaName = (String[]) fixAreaError.getUserObject(); OLATResource courseResource = courseEditorEnv.getCourseGroupManager().getCourseResource(); removeAsListenerAndDispose(areaCreateCtlr); areaCreateCtlr = new NewAreaController(ureq, getWindowControl(), courseResource, true, csvAreaName[0]); listenTo(areaCreateCtlr); removeAsListenerAndDispose(cmc); cmc = new CloseableModalController(getWindowControl(), "close", areaCreateCtlr.getInitialComponent()); listenTo(cmc); cmc.activate(); } } @Override protected void event(UserRequest ureq, Controller source, org.olat.core.gui.control.Event event) { if (source == groupChooseC) { if (Event.DONE_EVENT == event) { cmc.deactivate(); List<Long> groupKeys = groupChooseC.getSelectedKeys(); easyGroupList.setUserObject(groupKeys); easyGroupList.setValue(getGroupNames(groupKeys)); validateGroupFields(); easyGroupList.getRootForm().submit(ureq); } else if (event == Event.CANCELLED_EVENT) { cmc.deactivate(); } else if (event == Event.CHANGED_EVENT) { //a group was created within from within the chooser } } else if (source == areaChooseC) { if (event == Event.DONE_EVENT) { cmc.deactivate(); List<Long> areaKeys = areaChooseC.getSelectedKeys(); easyAreaList.setUserObject(areaKeys); easyAreaList.setValue(this.getAreaNames(areaKeys)); validateGroupFields(); easyAreaList.getRootForm().submit(ureq); } else if (event == Event.CANCELLED_EVENT) { cmc.deactivate(); } else if (event == Event.CHANGED_EVENT) { //an area was created within from within the chooser } } else if (source == groupCreateCtlr) { cmc.deactivate(); if (event == Event.DONE_EVENT) { List<Long> c = new ArrayList<Long>(); c.addAll(getKeys(easyGroupList)); if (fixGroupError != null && fixGroupError.getUserObject() != null) { c.removeAll(Arrays.asList((String[])fixGroupError.getUserObject())); } c.addAll(groupCreateCtlr.getCreatedGroupKeys()); easyGroupList.setValue(getGroupNames(c)); easyGroupList.setUserObject(c); easyGroupList.getRootForm().submit(ureq); validateGroupFields(); if (!groupCreateCtlr.getCreatedGroupKeys().isEmpty()) { singleUserEventCenter.fireEventToListenersOf(new MultiUserEvent("changed"), groupConfigChangeEventOres); } } } else if (source == areaCreateCtlr) { cmc.deactivate(); if (event == Event.DONE_EVENT) { List<Long> c = new ArrayList<Long>(); c.addAll(getKeys(easyAreaList)); if (fixAreaError!= null && fixAreaError.getUserObject() != null) { c.removeAll(Arrays.asList((String[])fixAreaError.getUserObject())); } c.addAll(areaCreateCtlr.getCreatedAreaKeys()); easyAreaList.setValue(getAreaNames(c)); easyAreaList.setUserObject(c); easyAreaList.getRootForm().submit(ureq); validateGroupFields(); if (!areaCreateCtlr.getCreatedAreaKeys().isEmpty()) { singleUserEventCenter.fireEventToListenersOf(new MultiUserEvent("changed"), groupConfigChangeEventOres); } } } } @Override protected boolean validateFormLogic(UserRequest ureq) { boolean retVal = true; // (1) // dateswitch is enabled and the datefields are valid // check complex rules involving checks over multiple elements Date fromDateVal = fromDate.getDate(); Date toDateVal = toDate.getDate(); if (dateSwitch.getSelectedKeys().size() == 1 && !fromDate.hasError() && !toDate.hasError()) { // one must be set if (fromDate.isEmpty() && toDate.isEmpty()) { // error concern both input fields -> set it as switch error dateSubContainer.setErrorKey("form.easy.error.date", null); retVal = false; } else { // remove general error dateSubContainer.clearError(); } // check valid dates // if both are set, check from < to if (fromDateVal != null && toDateVal != null) { /* * bugfix http://bugs.olat.org/jira/browse/OLAT-813 valid dates and not * empty, in easy mode we assume that Start and End date should * implement the meaning of * ----false---|S|-----|now|-TRUE---------|E|---false--->t ............. * Thus we check for Startdate < Enddate, error otherwise */ if (fromDateVal.after(toDateVal)) { dateSubContainer.setErrorKey("form.easy.error.bdateafteredate", null); retVal = false; } else { // remove general error dateSwitch.clearError(); } } else { if (fromDateVal == null && !fromDate.isEmpty()) { //not a correct begin date fromDate.setErrorKey("form.easy.error.bdate", null); retVal = false; } if (toDateVal == null && !toDate.isEmpty()) { toDate.setErrorKey("form.easy.error.edate", null); retVal = false; } } } // (2) // groups switch is enabled // check if either group or area is defined retVal = validateGroupFields() && retVal; if (assessmentSwitch.getSelectedKeys().size() == 1) { // foop d fbg,dfbg,f ,gfbirst check two error cases of a selection // no node selected or a deleted node selected if (nodePassed.getSelectedKey().equals(NO_NODE_SELECTED_IDENTIFYER)) { nodePassed.setErrorKey("form.easy.error.nodePassed", null); retVal = false; } else if (nodePassed.getSelectedKey().equals(DELETED_NODE_IDENTIFYER)) { nodePassed.setErrorKey("form.easy.error.nodeDeleted", null); retVal = false; } else { //clear nodepassed error nodePassed.clearError(); //retVal stays } } if (shibbolethModule.isEnableShibbolethLogins()) { retVal=validateAttibuteFields()&&retVal; } // return retVal; } /** * @param retVal * @return */ private boolean validateGroupFields() { boolean retVal = true; if (groupSwitch.getSelectedKeys().size() == 1) { List<Long> activeGroupSelection = null; List<Long> activeAreaSelection = null; groupChooseSubContainer.clearError(); if (!isEmpty(easyGroupList)) { // check whether groups exist activeGroupSelection = getKeys(easyGroupList); Set<Long> missingGroups = new HashSet<Long>(); List<BusinessGroupShort> existingGroups = businessGroupService.loadShortBusinessGroups(activeGroupSelection); a_a: for(Long activeGroupKey:activeGroupSelection) { for(BusinessGroupShort group:existingGroups) { if(group.getKey().equals(activeGroupKey)) { continue a_a; } } missingGroups.add(activeGroupKey); } if (missingGroups.size() > 0) { retVal = false; String labelKey = missingGroups.size() == 1 ? "error.notfound.name" : "error.notfound.names"; String csvMissGrps = toString(missingGroups); String[] params = new String[] { "-", csvMissGrps }; // create error with link to fix it String vc_errorPage = velocity_root + "/erroritem.html"; FormLayoutContainer errorGroupItemLayout = FormLayoutContainer.createCustomFormLayout( "errorgroupitem", getTranslator(), vc_errorPage); groupChooseSubContainer.setErrorComponent(errorGroupItemLayout, this.flc); // FIXING LINK ONLY IF A DEFAULTCONTEXT EXISTS fixGroupError = new FormLinkImpl("error.fix", "create"); // link fixGroupError.setCustomEnabledLinkCSS("btn btn-default"); errorGroupItemLayout.add(fixGroupError); fixGroupError.setErrorKey(labelKey, params); fixGroupError.showError(true); fixGroupError.showLabel(false); // hinty to pass the information if one group is // missing or if 2 or more groups are missing // (see fixGroupErrer.getUserObject to understand) // e.g. if userobject String[].lenght == 1 -> one group only // String[].lenght > 1 -> show bulkmode creation group if (missingGroups.size() > 1) { fixGroupError.setUserObject(new String[] { csvMissGrps, "dummy" }); } else { fixGroupError.setUserObject(new String[] { csvMissGrps }); } groupChooseSubContainer.showError(true); } else { // no more errors groupChooseSubContainer.clearError(); } } areaChooseSubContainer.clearError(); if (!isEmpty(easyAreaList)) { // check whether areas exist activeAreaSelection = getKeys(easyAreaList); List<Long> missingAreas = new ArrayList<Long>(); List<BGArea> cnt = areaManager.loadAreas(activeAreaSelection); a_a: for(Long activeAreaKey:activeAreaSelection) { for (BGArea element : cnt) { if (element.getKey().equals(activeAreaKey)) { continue a_a; } } missingAreas.add(activeAreaKey); } if (missingAreas.size() > 0) { retVal = false; String labelKey = missingAreas.size() == 1 ? "error.notfound.name" : "error.notfound.names"; String csvMissAreas = toString(missingAreas); String[] params = new String[] { "-", csvMissAreas }; // create error with link to fix it String vc_errorPage = velocity_root + "/erroritem.html"; FormLayoutContainer errorAreaItemLayout = FormLayoutContainer.createCustomFormLayout( "errorareaitem", getTranslator(), vc_errorPage); areaChooseSubContainer.setErrorComponent(errorAreaItemLayout, this.flc); // FXINGIN LINK ONLY IF DEFAULT CONTEXT EXISTS fixAreaError = new FormLinkImpl("error.fix", "create");// erstellen // link fixAreaError.setCustomEnabledLinkCSS("btn btn-default"); errorAreaItemLayout.add(fixAreaError); fixAreaError.setErrorKey(labelKey, params); fixAreaError.showError(true); fixAreaError.showLabel(false); // hint to pass the information if one area is // missing or if 2 or more areas are missing // (see fixGroupErrer.getUserObject to understand) // e.g. if userobject String[].lenght == 1 -> one group only // String[].lenght > 1 -> show bulkmode creation group if (missingAreas.size() > 1) { fixAreaError.setUserObject(new String[] { csvMissAreas, "dummy" }); } else { fixAreaError.setUserObject(new String[] { csvMissAreas }); } areaChooseSubContainer.showError(true); } else { areaChooseSubContainer.clearError(); } } boolean easyGroupOK = (!isEmpty(easyGroupList) && activeGroupSelection != null && !activeGroupSelection.isEmpty()); boolean easyAreaOK = (!isEmpty(easyAreaList) && activeAreaSelection != null && !activeAreaSelection.isEmpty()); if (easyGroupOK || easyAreaOK) { // clear general error groupSubContainer.clearError(); } else { // error concerns both fields -> set it as switch error groupSubContainer.setErrorKey("form.easy.error.group", null); retVal = false; } } return retVal; } /** * @param retVal * @return */ private boolean validateAttibuteFields() { boolean retVal = true; if (attributeSwitch.getSelectedKeys().size() == 1&&attribteRowAdderSubform.hasError()) { attributeSwitch.setErrorKey("form.easy.error.attribute", null); retVal = false; return retVal; } attributeSwitch.clearError(); return retVal; } /** * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm(org.olat.core.gui.components.form.flexible.FormItemContainer, * org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest) */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { addCoachExclusive(formLayout); addFromToDateChooser(formLayout); addEasyGroupAreaChoosers(formLayout); addAssessmentSwitch(formLayout); // if(shibbolethModule.isEnableShibbolethLogins()){ addAttributeSwitch(formLayout, ureq); } flc.contextPut("shibbolethEnabled", new Boolean(shibbolethModule.isEnableShibbolethLogins())); addAssessmentMode(formLayout); addApplyRulesForTutorsToo(formLayout); // add rules addRules(formLayout); // the submit button uifactory.addFormSubmitButton("subm", "submit", formLayout); validateGroupFields(); } private void addAttributeSwitch(FormItemContainer formLayout, UserRequest ureq) { /* * yes / no chooser defines if learner do not see the building block at all */ String[] values = new String[]{ translate("form.easy.attributeSwitch") }; attributeSwitch = uifactory.addCheckboxesHorizontal("attributeSwitch", null, formLayout, new String[] { "ison" }, values); attributeSwitch.select("ison", validatedCondition.getAttributeConditions() != null); // register for on click event to hide/disable other elements attributeSwitch.addActionListener(FormEvent.ONCLICK); // rules are later added // add attribute connector: AND or OR final String[] attributebconnectorValues = new String[] { translate("form.easy.attributebconnector.and"), translate("form.easy.attributebconnector.or") }; attributeBconnector = uifactory.addRadiosHorizontal("attributeBconnector", "form.easy.attributebconnector", formLayout, new String[] { BCON_VAL_AND, BCON_VAL_OR }, attributebconnectorValues); if(validatedCondition.isConditionsConnectorIsAND()){ attributeBconnector.select(BCON_VAL_AND, true); } else { attributeBconnector.select(BCON_VAL_OR, true); } // add attribute condition rows attribteRowAdderSubform = new AttributeEasyRowAdderController(ureq, getWindowControl(), mainForm); flc.add(attribteRowAdderSubform.getFormItem()); listenTo(attribteRowAdderSubform); flc.put("attribteRowAdderSubform", attribteRowAdderSubform.getInitialComponent()); if (validatedCondition.getAttributeConditions() != null && validatedCondition.getAttributeConditions().size() > 0) { attribteRowAdderSubform.setAttributeConditions(validatedCondition.getAttributeConditions()); } } /** * Check if any of the date/group/assessment/attributes switch is ON. * @return */ private boolean isDateGroupAssessmentOrAttributeSwitchOnOrAssessmentModeOn() { return dateSwitch.getSelectedKeys().size() == 1 || groupSwitch.getSelectedKeys().size() == 1 || assessmentSwitch.getSelectedKeys().size() == 1 || (attributeSwitch!=null && attributeSwitch.getSelectedKeys().size()==1) || (assessmentMode.isEnabled() && assessmentMode.isAtLeastSelected(1)); } /** * Show applyRulesForCoach depending on isDateGroupAssessmentOAttributeSwitchOn state. */ private void showOrHideApplyRulesForCoach() { if(isDateGroupAssessmentOrAttributeSwitchOnOrAssessmentModeOn()) { applyRulesForCoach.setVisible(true); } else { applyRulesForCoach.setVisible(false); } } /** * you may find here now the complexest rule set ever use in OLAT<br> * This form has a 5 switches<br> * <ul> * <li>[] 1 Learners only</li> * <li>[] 2 Date dependent</li> * <li>[] 3 Group dependent</li> * <li>[] 4 Assess dependent</li> * <li>[] 5 Apply rules also to coaches</li> * </ul> * enable [1] this greys out all others<br> * if one of [2] [3] or [4] is selected -> [5] becomes selectable<br> * selecting [2] [3] or [4] opens their respective subconfiguration<br> * "[2] date dependent" shows an end and startdate where at least one must be * selected and the start date must be before the enddate.<br> * "[3] group dependent" shows a group or area input field. which takes group * or area names comma separated. the form evaluates if the areas or groups * exists, and if not, a quick fix is provided to create the missing groups/areas. * furthermore there is a "choose" button to choose groups/areas. This choose * button is named "create" if there are no groups or areas to choose from. If * create is clicked a create group/area workflow is started directly. If some * comma separated values are in the input field, it allows to create them at * once. At least an area or groupname must be specified, and all the specified * names must exist.<br> * "[4] assessment " allows to choose a node and to define a cut value or if * it should be checked for passed.<br> * To accomplish all the hiding, disabling, enabling, resetting to initial values * the following rules are added. this may look confusing, and it is confusing. * It took quite some days and testing until to get it right. * @param formLayout */ private void addRules(FormItemContainer formLayout) { // disable date choosers if date switch is set to no // enable it otherwise. final Set<FormItem> dependenciesDateSwitch = new HashSet<FormItem>(); dependenciesDateSwitch.add(toDate); dependenciesDateSwitch.add(fromDate); dependenciesDateSwitch.add(dateSubContainer); final Set<FormItem> dependenciesAttributeSwitch = new HashSet<FormItem>(); // only add when initialized. is null when shibboleth module is not enabled if (shibbolethModule.isEnableShibbolethLogins()) { dependenciesAttributeSwitch.add(attributeBconnector); } // show elements dependent on other values set. FormItemDependencyRule hideClearDateSwitchDeps = RulesFactory.createCustomRule(dateSwitch, null, dependenciesDateSwitch, formLayout); hideClearDateSwitchDeps.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { toDate.setDate(null); toDate.setVisible(false); fromDate.setDate(null); fromDate.setVisible(false); toDate.clearError(); fromDate.clearError(); dateSwitch.clearError(); dateSubContainer.setVisible(false); fromDate.setFocus(false); /* * special rules for apply rules for coach and for assessment dependent */ //assessment switch only enabled if nodes to be selected boolean coachExclIsOn = coachExclusive.getSelectedKeys().size() == 1; assessmentSwitch.setEnabled(!coachExclIsOn && (nodeIdentList.size() > 0 || isSelectedNodeDeleted())); showOrHideApplyRulesForCoach(); } }); RulesFactory.createShowRule(dateSwitch, "ison", dependenciesDateSwitch, formLayout); FormItemDependencyRule toggleApplyRule = RulesFactory.createCustomRule(dateSwitch, "ison", dependenciesDateSwitch, formLayout); toggleApplyRule.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { fromDate.setFocus(true); //assessment switch only enabled if nodes to be selected assessmentSwitch.setEnabled((nodeIdentList.size() > 0 || isSelectedNodeDeleted())); showOrHideApplyRulesForCoach(); } }); if (shibbolethModule.isEnableShibbolethLogins()) { FormItemDependencyRule hideClearAttibuteSwitchDeps = RulesFactory.createCustomRule(attributeSwitch, null, dependenciesAttributeSwitch, formLayout); hideClearAttibuteSwitchDeps.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { attributeSwitch.clearError(); attributeBconnector.select(BCON_VAL_AND, true); attributeBconnector.setVisible(false); if(attribteRowAdderSubform!=null){ attribteRowAdderSubform.cleanUp(); } showOrHideApplyRulesForCoach(); } }); RulesFactory.createShowRule(attributeSwitch, "ison", dependenciesAttributeSwitch, formLayout); FormItemDependencyRule attributeSwitchtoggleApplyRule = RulesFactory.createCustomRule(attributeSwitch, "ison", dependenciesAttributeSwitch, formLayout); attributeSwitchtoggleApplyRule.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { attributeBconnector.setVisible(true); if(attribteRowAdderSubform!=null){ attribteRowAdderSubform.init(); } showOrHideApplyRulesForCoach(); } }); } // // enable textfields and subworkflow-start-links if groups is yes // disable it otherwise final Set<FormItem> dependenciesGroupSwitch = new HashSet<FormItem>(); dependenciesGroupSwitch.add(groupSubContainer); FormItemDependencyRule hideClearGroupSwitchDeps = RulesFactory.createCustomRule(groupSwitch, null, dependenciesGroupSwitch, formLayout); hideClearGroupSwitchDeps.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { easyAreaList.clearError(); easyGroupList.clearError(); groupSwitch.clearError(); groupSubContainer.setVisible(false); if (shibbolethModule.isEnableShibbolethLogins()) { attributeSwitch.clearError(); } easyGroupList.setFocus(false); //assessment switch only enabled if nodes to be selected boolean coachExclIsOn = coachExclusive.getSelectedKeys().size() == 1; assessmentSwitch.setEnabled(!coachExclIsOn && (nodeIdentList.size() > 0 || isSelectedNodeDeleted())); showOrHideApplyRulesForCoach(); } }); RulesFactory.createShowRule(groupSwitch, "ison", dependenciesGroupSwitch, formLayout); toggleApplyRule = RulesFactory.createCustomRule(groupSwitch, "ison", dependenciesGroupSwitch, formLayout); toggleApplyRule.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { easyGroupList.setFocus(true); //assessment switch only enabled if nodes to be selected assessmentSwitch.setEnabled((nodeIdentList.size() > 0 || isSelectedNodeDeleted())); showOrHideApplyRulesForCoach(); } }); // // dependencies of assessment switch final Set<FormItem> assessDeps = new HashSet<FormItem>(); assessDeps.add(assessmentTypeSwitch); assessDeps.add(nodePassed); assessDeps.add(cutValue); assessDeps.add(assessSubContainer); // show elements dependent on other values set. FormItemDependencyRule showAssessmentSwitchDeps = RulesFactory.createCustomRule(assessmentSwitch, "ison", assessDeps, formLayout); showAssessmentSwitchDeps.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { boolean cutValueVisibility = assessmentTypeSwitch.getSelectedKey().equals(NODEPASSED_VAL_SCORE); assessSubContainer.setVisible(true); assessmentTypeSwitch.setVisible(true); nodePassed.setVisible(true); cutValue.setVisible(cutValueVisibility); assessmentSwitch.clearError(); cutValue.clearError(); nodePassed.clearError(); showOrHideApplyRulesForCoach(); } }); // hide elements and reset values. FormItemDependencyRule hideResetAssessmentSwitchDeps = RulesFactory.createCustomRule(assessmentSwitch, null, assessDeps, formLayout); hideResetAssessmentSwitchDeps.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { assessSubContainer.setVisible(false); assessmentTypeSwitch.select(NODEPASSED_VAL_PASSED, true); assessmentTypeSwitch.setVisible(false); nodePassed.select(NO_NODE_SELECTED_IDENTIFYER, true); nodePassed.setVisible(false); cutValue.setIntValue(0); cutValue.setVisible(false); showOrHideApplyRulesForCoach(); } }); final Set<FormItem> assessTypeDeps = new HashSet<FormItem>(); assessTypeDeps.add(cutValue); RulesFactory.createHideRule(assessmentTypeSwitch, NODEPASSED_VAL_PASSED, assessTypeDeps, assessSubContainer); RulesFactory.createShowRule(assessmentTypeSwitch, NODEPASSED_VAL_SCORE, assessTypeDeps, assessSubContainer); // // final Set<FormItem> dependenciesCoachExclusiveReadonly = new HashSet<FormItem>(); dependenciesCoachExclusiveReadonly.addAll(dependenciesDateSwitch); dependenciesCoachExclusiveReadonly.addAll(dependenciesGroupSwitch); dependenciesCoachExclusiveReadonly.addAll(assessDeps); dependenciesCoachExclusiveReadonly.addAll(dependenciesAttributeSwitch); // coach exclusive switch rules // -> custom rule implementation because it is not a simple hide / show rule // while disabling reset the elements FormItemDependencyRule disableAndResetOthers = RulesFactory.createCustomRule(coachExclusive, "ison", dependenciesCoachExclusiveReadonly, formLayout); disableAndResetOthers.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { // disable and remove checkbox selection // uncheck and disable checkboxes dateSwitch.select("ison", false); groupSwitch.select("ison", false); assessmentSwitch.select("ison", false); dateSwitch.setEnabled(false); toDate.setDate(null); fromDate.setDate(null); groupSwitch.setEnabled(false); easyAreaList.setValue(""); easyAreaList.setUserObject(new ArrayList<Long>()); easyGroupList.setValue(""); easyGroupList.setUserObject(new ArrayList<Long>()); assessmentSwitch.setEnabled(false); assessmentMode.select("ison", false); assessmentMode.setEnabled(false); // disable the shibboleth attributes switch and reset the row subform if (attributeSwitch != null) { attributeSwitch.select("ison", false); attributeSwitch.setEnabled(false); attribteRowAdderSubform.cleanUp(); attributeSwitch.clearError(); } showOrHideApplyRulesForCoach(); // hide (e.g. remove) general erros dateSwitch.clearError(); groupSwitch.clearError(); assessmentSwitch.clearError(); // all dependent elements become invisible for (Iterator<FormItem> iter = dependenciesCoachExclusiveReadonly.iterator(); iter.hasNext();) { FormItem element = iter.next(); element.setVisible(false); } } }); // two rules to bring them back visible and also checkable // dependencies of assessment switch final Set<FormItem> switchesOnly = new HashSet<FormItem>(); switchesOnly.add(dateSwitch); switchesOnly.add(groupSwitch); switchesOnly.add(assessmentSwitch); switchesOnly.add(applyRulesForCoach); if (shibbolethModule.isEnableShibbolethLogins()) { switchesOnly.add(attributeSwitch); } FormItemDependencyRule enableOthers = RulesFactory.createCustomRule(coachExclusive, null, switchesOnly, formLayout); enableOthers.setDependencyRuleApplayable(new DependencyRuleApplayable() { private boolean firedDuringInit = true; public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { dateSwitch.setEnabled(true); groupSwitch.setEnabled(true); //assessment switch only enabled if nodes to be selected assessmentSwitch.setEnabled((nodeIdentList.size() > 0 || isSelectedNodeDeleted())); assessmentMode.setEnabled(true); //default is a checked disabled apply rules for coach if (shibbolethModule.isEnableShibbolethLogins()) { attributeSwitch.setEnabled(true); } if(!firedDuringInit){ showOrHideApplyRulesForCoach(); } firedDuringInit = false; } }); // // dependencies of assessment mode final Set<FormItem> assessModeDeps = new HashSet<FormItem>(); // show elements dependent on other values set. FormItemDependencyRule showAssessmentModeDeps = RulesFactory.createCustomRule(assessmentMode, "ison", assessModeDeps, formLayout); showAssessmentModeDeps.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { showOrHideApplyRulesForCoach(); } }); // hide elements and reset values. FormItemDependencyRule hideResetAssessmentModeDeps = RulesFactory.createCustomRule(assessmentMode, null, assessModeDeps, formLayout); hideResetAssessmentModeDeps.setDependencyRuleApplayable(new DependencyRuleApplayable() { public void apply(FormItem triggerElement, Object triggerVal, Set<FormItem> targets) { showOrHideApplyRulesForCoach(); } }); } /** * Methods to add elements * @param formLayout * @param listener */ private void addCoachExclusive(FormItemContainer formLayout) { /* * yes / no chooser defines if learner do not see the building block at all */ coachExclusive = uifactory.addCheckboxesHorizontal("coachExclusive", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.coachExclusive") }); coachExclusive.setElementCssClass("o_sel_condition_coach_exclusive"); boolean coachesAndAdminsInitValue = validatedCondition.isEasyModeCoachesAndAdmins(); coachExclusive.select("ison", coachesAndAdminsInitValue); // register for on click event to hide/disable other elements coachExclusive.addActionListener(FormEvent.ONCLICK); // rules are later added } private void addAssessmentMode(FormItemContainer formLayout) { assessmentMode = uifactory.addCheckboxesHorizontal("assessmentMode", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.assessmentMode") }); assessmentMode.select("ison", validatedCondition.isAssessmentMode()); assessmentMode.addActionListener(FormEvent.ONCLICK); assessmentMode.setVisible(assessmentModule.isAssessmentModeEnabled()); } /** * @param formLayout * @param listener */ private void addApplyRulesForTutorsToo(FormItemContainer formLayout) { /* * yes / no chooser defines if learner do not see the building block at all */ applyRulesForCoach = uifactory.addCheckboxesHorizontal("applyRulesForCoach", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.applyRulesForCoach") }); if(isDateGroupAssessmentOrAttributeSwitchOnOrAssessmentModeOn()) { applyRulesForCoach.setVisible(true); } else { applyRulesForCoach.setVisible(false); } //note that in the condition this rule is saved with the opposite meaning: // true when // coach and admins always have access, false when rule should apply also to // them boolean alwaysAllowCoachesAndAdminsInitValue = validatedCondition.isEasyModeAlwaysAllowCoachesAndAdmins(); if (alwaysAllowCoachesAndAdminsInitValue) { applyRulesForCoach.select("ison", false); } else { applyRulesForCoach.select("ison", true); } } /** * @param formLayout * @param listener */ private void addFromToDateChooser(FormItemContainer formLayout) { /* * yes / no switch if a date.time constraint is defined */ dateSubContainer = FormLayoutContainer.createDefaultFormLayout("dateSubContainer", getTranslator()); formLayout.add(dateSubContainer); fromDate = new JSDateChooser("fromDate", getLocale()); fromDate.setLabel("form.easy.bdate", null); fromDate.setDate(ConditionDateFormatter.parse(validatedCondition.getEasyModeBeginDate())); fromDate.setExampleKey("form.easy.example.bdate", null); fromDate.setDateChooserTimeEnabled(true); fromDate.setDisplaySize(fromDate.getExampleDateString().length()); dateSubContainer.add(fromDate); toDate = new JSDateChooser("toDate", getLocale()); toDate.setLabel("form.easy.edate", null); toDate.setDate(ConditionDateFormatter.parse(validatedCondition.getEasyModeEndDate())); toDate.setExampleKey("form.easy.example.edate", null); toDate.setDateChooserTimeEnabled(true); toDate.setDisplaySize(toDate.getExampleDateString().length()); dateSubContainer.add(toDate); dateSwitch = uifactory.addCheckboxesHorizontal("dateSwitch", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.dateSwitch") }); if (fromDate.getDate() != null || toDate.getDate() != null) { dateSwitch.select("ison", true); } else { dateSwitch.select("ison", false); } dateSwitch.addActionListener(FormEvent.ONCLICK); } /** * @param formLayout * @param listener */ private void addEasyGroupAreaChoosers(FormItemContainer formLayout) { groupSubContainer = FormLayoutContainer.createBareBoneFormLayout("groupSubContainer", getTranslator()); formLayout.add(groupSubContainer); List<Long> groupKeyList = validatedCondition.getEasyModeGroupAccessIdList(); String groupInitVal = getGroupNames(groupKeyList); List<Long> areaKeyList = validatedCondition.getEasyModeGroupAreaAccessIdList(); String areaInitVal = getAreaNames(areaKeyList); groupSwitch = uifactory.addCheckboxesHorizontal("groupSwitch", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.groupSwitch") }); groupSwitch.setElementCssClass("o_sel_condition_groups"); // initialize selection if (!groupKeyList.isEmpty() || !areaKeyList.isEmpty()) { groupSwitch.select("ison", true); } else { groupSwitch.select("ison", false); } groupSwitch.addActionListener(FormEvent.ONCLICK); //groups groupChooseSubContainer = FormLayoutContainer.createDefaultFormLayout("groupChooseSubContainer", getTranslator()); groupSubContainer.add(groupChooseSubContainer); easyGroupList = uifactory.addStaticTextElement("groupList", "form.easy.group", groupInitVal, groupChooseSubContainer); easyGroupList.setUserObject(groupKeyList); chooseGroupsLink = uifactory.addFormLink("choose", groupChooseSubContainer, "o_form_groupchooser"); chooseGroupsLink.setElementCssClass("o_sel_condition_choose_groups"); createGroupsLink = uifactory.addFormLink("create", groupChooseSubContainer, "o_form_groupchooser"); createGroupsLink.setElementCssClass("o_sel_condition_create_groups"); //areas areaChooseSubContainer = FormLayoutContainer.createDefaultFormLayout("areaChooseSubContainer", getTranslator()); groupSubContainer.add(areaChooseSubContainer); easyAreaList = uifactory.addStaticTextElement("groupList", "form.easy.area", areaInitVal, areaChooseSubContainer); easyAreaList.setUserObject(areaKeyList); chooseAreasLink = uifactory.addFormLink("choose", areaChooseSubContainer, "o_form_groupchooser"); createAreasLink = uifactory.addFormLink("create", areaChooseSubContainer, "o_form_groupchooser"); updateGroupsAndAreasCheck(); } private void addAssessmentSwitch(FormItemContainer formLayout) { assessSubContainer = FormLayoutContainer.createDefaultFormLayout("assessSubContainer", getTranslator()); formLayout.add(assessSubContainer); Translator translator = getTranslator(); final String[] assessmentSwitchKeys = new String[] { NODEPASSED_VAL_PASSED, NODEPASSED_VAL_SCORE }; final String[] assessmentSwitchValues = new String[] { translator.translate("form.easy.assessmentSwitch.passed"), translator.translate("form.easy.assessmentSwitch.score") }; String nodePassedInitVal = validatedCondition.getEasyModeNodePassedId(); String cutInitStrValue = validatedCondition.getEasyModeCutValue(); int cutInitValue = 0; assessmentSwitch = uifactory.addCheckboxesHorizontal("assessmentSwitch", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.assessmentSwitch") }); assessmentSwitch.addActionListener(FormEvent.ONCLICK); boolean selectedNodeIsInList = false; List<String> keysList = new ArrayList<String>(); List<String> valuesList = new ArrayList<String>(); if (nodeIdentList.size() > 0) { // there are nodes to be selected keysList.add(NO_NODE_SELECTED_IDENTIFYER); valuesList.add("- " + translator.translate("form.easy.nodePassed.select") + " -"); for (int i = 0; i < nodeIdentList.size(); i++) { CourseNode courseNode = nodeIdentList.get(i); keysList.add(courseNode.getIdent()); valuesList.add(courseNode.getShortName() + " (Id:" + courseNode.getIdent() + ")"); if (courseNode.getIdent().equals(nodePassedInitVal)) selectedNodeIsInList = true; } } else { // no nodes to be selected keysList.add(NO_NODE_SELECTED_IDENTIFYER); valuesList.add("- " + translator.translate("form.easy.nodePassed.noNodes")); //disable switch assessmentSwitch.setEnabled(false); } // add dummy value if needed if (nodePassedInitVal != null && !selectedNodeIsInList) { keysList.add(DELETED_NODE_IDENTIFYER); valuesList.add("- " + translator.translate("form.easy.nodePassed.deletedNode") + " -"); } final String[] nodePassedKeys = new String[keysList.size()]; keysList.toArray(nodePassedKeys); final String[] nodePassedValues = new String[valuesList.size()]; valuesList.toArray(nodePassedValues); nodePassed = uifactory.addDropdownSingleselect("nodePassed", "form.easy.nodePassed", assessSubContainer, nodePassedKeys, nodePassedValues, null); if (nodePassedInitVal != null) { if (selectedNodeIsInList) { nodePassed.select(nodePassedInitVal, true); } else { nodePassed.select(DELETED_NODE_IDENTIFYER, true); } } else { nodePassed.select(NO_NODE_SELECTED_IDENTIFYER, true); } assessmentTypeSwitch = uifactory.addRadiosVertical("assessmentTypeSwitch", null, assessSubContainer, assessmentSwitchKeys, assessmentSwitchValues); assessmentTypeSwitch.setLabel("form.easy.assessmentSwitch.type", null); assessmentTypeSwitch.addActionListener(FormEvent.ONCLICK); if (nodePassedInitVal != null) { // has a node configured if (cutInitStrValue == null) { // with cut value assessmentTypeSwitch.select(NODEPASSED_VAL_PASSED, true); } else { cutInitValue = Integer.valueOf(cutInitStrValue); assessmentTypeSwitch.select(NODEPASSED_VAL_SCORE, true); } assessmentSwitch.select("ison", true); assessmentTypeSwitch.setVisible(true); } else { assessmentSwitch.select("ison", false); assessmentTypeSwitch.setVisible(false); assessmentTypeSwitch.select(NODEPASSED_VAL_PASSED, true); } cutValue = uifactory.addIntegerElement("cutval", "form.easy.cutValue", cutInitValue, assessSubContainer); cutValue.setDisplaySize(3); } /* * HELPER METHODS AFTER HERE */ private Condition cloneCondition(Condition orig) { return orig.clone(); } public Condition getCondition() { return validatedCondition; } /** * gets called if other condition edit controller on the same screen has * created groups or areas and informs other condition edit controller to * update for example the "create link" to "choose link */ private void updateGroupsAndAreasCheck() { OLATResource courseResource = courseEditorEnv.getCourseGroupManager().getCourseResource(); RepositoryEntry courseEntry = courseEditorEnv.getCourseGroupManager().getCourseEntry(); boolean hasAreas = areaManager.countBGAreasInContext(courseResource) > 0; boolean hasGroups = businessGroupService.countBusinessGroups(null, courseEntry) > 0; createGroupsLink.setVisible(!hasGroups && !managedGroup); chooseGroupsLink.setVisible(!createGroupsLink.isVisible()); createAreasLink.setVisible(!hasAreas); chooseAreasLink.setVisible(!createAreasLink.isVisible()); } /** * It checks if the selected EasyModeNodePassedId is not null, while the assessable node list is empty, * and it enables the assessmentSwitch. * * @return */ private boolean isSelectedNodeDeleted() { String nodePassedInitVal = validatedCondition.getEasyModeNodePassedId(); if(nodePassedInitVal!=null && nodeIdentList.size()==0) { assessmentSwitch.setEnabled(true); return true; } return false; } private boolean isEmpty(StaticTextElement element) { List<Long> keys = getKeys(element); if(keys == null || keys.isEmpty()) { return true; } return false; } private List<Long> getKeys(StaticTextElement element) { @SuppressWarnings("unchecked") List<Long> keys = (List<Long>)element.getUserObject(); if(keys == null) { keys = new ArrayList<Long>(); element.setUserObject(keys); } return keys; } private String toString(Collection<Long> keys) { StringBuilder sb = new StringBuilder(); for(Long key:keys) { if(sb.length() > 0) sb.append(','); sb.append(key); } return sb.toString(); } private String getGroupNames(List<Long> keys) { StringBuilder sb = new StringBuilder(); List<BusinessGroupShort> groups = businessGroupService.loadShortBusinessGroups(keys); for(BusinessGroupShort group:groups) { if(sb.length() > 0) sb.append(", "); sb.append(StringHelper.escapeHtml(group.getName())); } return sb.toString(); } private String getAreaNames(List<Long> keys) { StringBuilder sb = new StringBuilder(); for(Long key:keys) { BGArea area = areaManager.loadArea(key); if(area != null) { if(sb.length() > 0) sb.append(", "); sb.append(StringHelper.escapeHtml(area.getName())); } } return sb.toString(); } }