/** * 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. * <p> */ package org.olat.core.gui.components.form.flexible.impl.elements; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormItemImpl; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.ValidationStatus; /** * Description:<br> * TODO: patrickb Class Description for MultipleSelectionElementImpl * <P> * Initial Date: 04.01.2007 <br> * * @author patrickb */ public class MultipleSelectionElementImpl extends FormItemImpl implements MultipleSelectionElement { private static final OLog log = Tracing.createLoggerFor(MultipleSelectionElementImpl.class); protected String[] keys; protected String[] values; private String[] cssClasses; private String[] iconLeftCSS; private Collection<String> selected; private final Layout layout; private final int columns; protected MultipleSelectionComponent component; private String[] original = null; private boolean ajaxOnlyMode = false; private boolean originalIsDefined = false; private boolean escapeHtml = true; private boolean domReplacementWrapperRequired = true; public MultipleSelectionElementImpl(String name) { this(name, Layout.horizontal, 1); } public MultipleSelectionElementImpl(String name, Layout layout) { this(name, layout, 1); } public MultipleSelectionElementImpl(String name, Layout layout, int columns) { super(name); selected = new HashSet<String>(); this.layout = layout; this.columns = columns; } @Override public String getForId() { return null; } @Override public void setDomReplacementWrapperRequired(boolean required) { domReplacementWrapperRequired = required; if(component != null) { component.setDomReplacementWrapperRequired(required); } } @Override public boolean isAjaxOnly() { return ajaxOnlyMode; } @Override public void setAjaxOnly(boolean ajaxOnlyMode) { this.ajaxOnlyMode = ajaxOnlyMode; } public Layout getLayout() { return layout; } public int getColumns() { return columns; } public boolean isEscapeHtml() { return escapeHtml; } @Override public void setEscapeHtml(boolean escapeHtml) { this.escapeHtml = escapeHtml; } public Collection<String> getSelectedKeys() { return selected; } @Override public void setKeysAndValues(String[] keys, String[] values) { setKeysAndValues(keys, values, null, null); } @Override public void setKeysAndValues(String[] keys, String[] values, String[] cssClasses, String[] iconLeftCSS) { this.keys = keys; this.values = values; this.cssClasses = cssClasses; this.iconLeftCSS = iconLeftCSS; initSelectionElements(); } /** * @see org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement#isAtLeastSelected(int, * java.lang.String) */ public boolean isAtLeastSelected(int howmany) { boolean ok = selected.size() >= howmany; return ok; } public String getKey(int which) { if(which >= 0 && which < keys.length) { return keys[which]; } return null; } public int getSize() { return keys.length; } public String getValue(int which) { return values[which]; } /** * selection element supports multiple select * * @see org.olat.core.gui.components.form.flexible.elements.SelectionElement#isMultiselect() */ public boolean isMultiselect() { return true; } public boolean isSelected(int which) { String key = getKey(which); return selected.contains(key); } public void select(String key, boolean select) { if (select) { selected.add(key); } else { selected.remove(key); } if(!originalIsDefined) { originalIsDefined = true; if(selected != null && selected.size() > 0){ original = new String[selected.size()]; original = selected.toArray(original); }else{ original = null; } } // set container dirty to render new selection component.setDirty(true); } /** * array of values which are selected * * @param values */ public void setSelectedValues(String[] values) { selected = new HashSet<String>(3); //remember original values if(!originalIsDefined){ originalIsDefined = true; original = (values != null ? values.clone() : null); } if (values == null) return; // no selection made (no checkbox activated) -> // selection is empty // H: values != null for (int i = 0; i < values.length; i++) { String key = values[i]; // prevent introducing fake keys int ksi = keys.length; boolean foundKey = false; int j = 0; while (!foundKey && j < ksi) { String eKey = keys[j]; if (eKey.equals(key)) foundKey = true; j++; } if (!foundKey){ log.warn("submitted key '" + key + "' was not found in the keys of formelement named " + this.getName() + " , keys=" + Arrays.asList(keys)); }else{ selected.add(key); } } // set container dirty to render new values component.setDirty(true); } @Override protected void rootFormAvailable() { // create components and add them to the velocity container initSelectionElements(); } @Override public void evalFormRequest(UserRequest ureq) { Form form = getRootForm(); if(isAjaxOnly()) { String dispatchuri = form.getRequestParameter("dispatchuri"); if(dispatchuri != null && dispatchuri.equals(component.getFormDispatchId())) { String key = form.getRequestParameter("achkbox"); String checked = form.getRequestParameter("checked"); if("true".equals(checked)) { selected.add(key); } else if("false".equals(checked)) { selected.remove(key); } } } else if(isEnabled() ) { // which one was selected? // selection change? // mark corresponding comps as dirty String[] reqVals = form.getRequestParameterValues(getName()); if (reqVals == null) { // selection box? reqVals = form.getRequestParameterValues(getName() + "_SELBOX"); } // selected = new HashSet<String>(); if (reqVals != null) { for (int i = 0; i < reqVals.length; i++) { selected.add(reqVals[i]); } } } } @Override public void validate(List<ValidationStatus> validationResults) { // no constraint to be checked } @Override public void reset() { setSelectedValues(original); clearError(); } /** * @see org.olat.core.gui.components.form.flexible.FormItemImpl#setEnabled(boolean) */ @Override public void setEnabled(boolean isEnabled) { super.setEnabled(isEnabled); component.setEnabled(isEnabled); } /** * @see org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement#setEnabled(java.lang.String, boolean) */ @Override public void setEnabled(String key, boolean isEnabled) { for(CheckboxElement check : component.getCheckComponents()) { if(check.getKey().equals(key)) { check.setEnabled(isEnabled); } } } /** * @see org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement#setEnabled(java.util.Set, boolean) */ @Override public void setEnabled(Set<String> keys, boolean isEnabled) { for (String key : keys) { setEnabled(key, isEnabled); } } @Override public void setVisible(boolean isVisible) { super.setVisible(isVisible); // set container dirty to render new values component.setVisible(isVisible); } /** * @see org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement#setVisible(java.lang.String, boolean) */ @Override public void setVisible(String key, boolean isVisible) { for(CheckboxElement check : component.getCheckComponents()) { if(check.getKey().equals(key)) { check.setVisible(isVisible); } } } /** * @see org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement#setVisible(java.util.Set, boolean) */ @Override public void setVisible(Set<String> keys, boolean isEnabled) { for (String key : keys) { setEnabled(key, isEnabled); } } /** * Returns the keys of the checkboxes in this {@link MultipleSelectionElement}. * @return Keys of the checkboxes */ public Set<String> getKeys() { return new HashSet<String>(Arrays.asList(keys)); } protected void initSelectionElements() { boolean createValues = (values == null) || (values.length == 0); if (createValues) { values = new String[keys.length]; for (int i = 0; i < keys.length; i++) { values[i] = translator.translate(keys[i]); } } // keys,values initialized // create and add radio elements CheckboxElement[] ssecs = new CheckboxElement[keys.length]; for (int i = 0; i < keys.length; i++) { String checkName = getName() + "_" + keys[i]; ssecs[i] = new CheckboxElement(checkName, this, i, (cssClasses == null ? null : cssClasses[i]), (iconLeftCSS == null ? null : iconLeftCSS[i])); ssecs[i].setEnabled(isEnabled()); } // create and add selectbox element if(component == null) { String ssscId = getFormItemId() == null ? null : getFormItemId() + "_SELBOX"; component = new MultipleSelectionComponent(ssscId, this); component.setDomReplacementWrapperRequired(domReplacementWrapperRequired); component.setCheckComponents(ssecs); } else { component.setCheckComponents(ssecs); } } /** * @see org.olat.core.gui.components.form.flexible.FormBaseComponentIdProvider#getFormDispatchId() */ @Override public String getFormDispatchId() { return DISPPREFIX.concat(getComponent().getDispatchID()); } @Override protected MultipleSelectionComponent getFormItemComponent() { return component; } /** * Select all selection elements. */ public void selectAll() { selected = new HashSet<String>(3); for (int i = 0; i < keys.length; i++) { selected.add(keys[i]); } // set container dirty to render new selection component.setDirty(true); } /** * Uncheck all selection elements. */ public void uncheckAll() { selected = new HashSet<String>(3); // set container dirty to render new selection component.setDirty(true); } }