/******************************************************************************* * Copyright 2015 xWic group (http://www.xwic.de) * * Licensed under the Apache License, Version 2.0 (the "License"). * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *******************************************************************************/ /* * de.jwic.controls.ListBoxControl * $Id: ListControl.java,v 1.11 2008/09/17 15:19:46 lordsam Exp $ */ package de.jwic.controls; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import de.jwic.base.Control; import de.jwic.base.Field; import de.jwic.base.IControlContainer; import de.jwic.base.Page; import de.jwic.base.SessionContext; import de.jwic.events.ElementSelectedEvent; import de.jwic.events.ElementSelectedListener; import de.jwic.events.ValueChangedEvent; import de.jwic.events.ValueChangedListener; /** * This control renders list like a list box, radio group or checkbox. * * @author Florian Lippisch * @version $Revision: 1.11 $ */ public abstract class ListControl extends HTMLElement { private static final long serialVersionUID = 1L; protected Map<String, ListEntry> elements = new LinkedHashMap<String, ListEntry>(); protected boolean changeNotification = false; protected List<ElementSelectedListener> selectionListeners = null; protected Field field = null; /** * @param container * @param name */ public ListControl(IControlContainer container, String name) { super(container, name); init(); } /* (non-Javadoc) * @see de.jwic.base.Control#init() */ private void init() { field = new Field(this); field.setValue(""); field.addValueChangedListener(new ValueChangedListener() { private static final long serialVersionUID = 1L; public void valueChanged(ValueChangedEvent event) { sendElementSelectedEvent(); // transform the event. } }); } /** * Invoked when the value has been changed. * */ public void actionValuechanged() { // nothing to do, as the valueChanged is triggered directly by the field. // but we must leave this method as it is invoked by the onChanged event. } /** * Send the element selected event to the registerd listeners. */ protected void sendElementSelectedEvent() { if (selectionListeners != null) { ElementSelectedEvent e = new ElementSelectedEvent(this, getSelectedKey()); for (Iterator<ElementSelectedListener> it = selectionListeners.iterator(); it.hasNext(); ) { ElementSelectedListener osl = it.next(); osl.elementSelected(e); } } } /** * Add an element to the list where the title is used as the key. * @param title */ public ListEntry addElement(String title) { return addElement(title, title); } /** * Add an element to the list with a title and a seperate key. * @param title * @param key */ public ListEntry addElement(String title, String key) { ListEntry entry = new ListEntry(title, key); elements.put(key, entry); requireRedraw(); return entry; } /** * Register a listener that will be notified when an element has been selected. * @param listener */ public void addElementSelectedListener(ElementSelectedListener listener) { if (selectionListeners == null) { selectionListeners = new ArrayList<ElementSelectedListener>(); } selectionListeners.add(listener); } /** * Removes the specified listener. * @param listener */ public void removeElementSelectedListener(ElementSelectedListener listener) { if (selectionListeners != null) { selectionListeners.remove(listener); } } /** * Remove all entries from the list. */ public void clear() { elements.clear(); field.setValue(""); // reset the key. requireRedraw(); } /** * Returns the collection of elements. * @return List of ListEntry objects. */ public Collection<ListEntry> getElements() { return elements.values(); } /** * @return the map of elements */ public Map<String, ListEntry> getElementsMap() { return elements; } /** * @param the elements to set */ public void setElementsMap(Map<String, ListEntry> elelemts ) { this.elements = elelemts; } /** * Returns the collection of elements keys. * @return */ public Collection<String> getElementsKeys() { return elements.keySet(); } /** * The field representation used by the ListControl on the HTML form. * This property is used by the renderer to generate the proper HTML code. * Use the <code>selectedKey</code> property to change the ListControls data. * @return */ public Field getField() { return field; } /** * Returns the key of the selected element as String. If * multiple elements are selected, the keys are seprated by a ';'. */ public String getSelectedKey() { return field.getValue(); } /** * Returns the selected keys as String[]. * @return */ public String[] getSelectedKeys() { return field.getValues(); } /** * Set the key of the selected element. * @param key * @return */ public void setSelectedKey(String key) { field.setValue(key); requireRedraw(); } /** * Returns true if the page will be submited when the value has been changed * by the user. * @return Returns the changeNotification. */ public boolean isChangeNotification() { return changeNotification; } /** * Set to true if the page should be submited when the value has been changed * by the user. * @param changeNotification boolean */ public void setChangeNotification(boolean changeNotification) { this.changeNotification = changeNotification; requireRedraw(); } /** * @param key the element beeing testet * handle also the multiselect case */ public boolean isKeySelected(String key){ String[] selection = field.getValues(); for (int i = 0; i < selection.length; i++) { if (key.equalsIgnoreCase(selection[i])) { return true; } } return false; } /** * Remove an element by its key. Returns the number of elements removed. * @param key */ public int removeElement(String key) { int count = 0; String[] selection = field.getValues(); List<String> newSelection = new ArrayList<String>(selection.length); for (Iterator<ListEntry> it = elements.values().iterator(); it.hasNext(); ) { ListEntry entry = it.next(); if (entry.key.equals(key)) { it.remove(); count++; } else { if (isKeySelected(entry.key)) { newSelection.add(entry.key); } } } if (newSelection.size() != selection.length) { // a selected element has been removed String[] newList = new String[newSelection.size()]; for (int i = 0; i < newSelection.size(); i++) { newList[i] = newSelection.get(i); } field.setValues(newList); } requireRedraw(); return count; // no element removed. } /** * Forces focus for this field. Returns <code>true</code> if the * field Id could have been set. */ public boolean forceFocus() { // Check if the current top-control is a parent of this input box. // if so, force focus. SessionContext context = getSessionContext(); Control topCtrl = context.getTopControl(); if (topCtrl == null) { // initialization phase -> walk up the control hieracy to find a Page control IControlContainer container = getContainer(); while (container != null && !(container instanceof SessionContext)) { Control ctrl = (Control)container; if (ctrl instanceof Page) { topCtrl = ctrl; break; } container = ctrl.getContainer(); } } if (topCtrl != null && getControlID().startsWith(topCtrl.getControlID() + ".")) { if (topCtrl instanceof Page) { Page page = (Page)topCtrl; page.setForceFocusElement(getForceFocusElement()); return true; } } return false; } /** * @return Name of form element that is used to set the focus. */ public String getForceFocusElement() { return getField().getId(); } }