001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui.input; 029 030import org.opencms.gwt.client.I_CmsHasInit; 031import org.opencms.gwt.client.ui.I_CmsAutoHider; 032import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 033import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 034import org.opencms.gwt.client.ui.input.form.CmsWidgetFactoryRegistry; 035import org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetFactory; 036import org.opencms.gwt.client.util.CmsDomUtil; 037import org.opencms.util.CmsPair; 038import org.opencms.util.CmsStringUtil; 039 040import java.util.ArrayList; 041import java.util.HashSet; 042import java.util.LinkedHashMap; 043import java.util.List; 044import java.util.Map; 045import java.util.Set; 046 047import com.google.common.base.Optional; 048import com.google.gwt.event.dom.client.FocusEvent; 049import com.google.gwt.event.dom.client.FocusHandler; 050import com.google.gwt.event.dom.client.HasFocusHandlers; 051import com.google.gwt.event.logical.shared.HasValueChangeHandlers; 052import com.google.gwt.event.logical.shared.ValueChangeEvent; 053import com.google.gwt.event.logical.shared.ValueChangeHandler; 054import com.google.gwt.event.shared.HandlerRegistration; 055import com.google.gwt.user.client.ui.Composite; 056import com.google.gwt.user.client.ui.FlowPanel; 057import com.google.gwt.user.client.ui.Panel; 058 059/** 060 * A form widget consisting of a group of checkboxes.<p> 061 * 062 * @since 8.0.0 063 * 064 */ 065public class CmsMultiCheckBox extends Composite 066implements I_CmsFormWidget, I_CmsHasInit, HasValueChangeHandlers<String>, HasFocusHandlers { 067 068 /** The type string for this widget. */ 069 public static final String WIDGET_TYPE = "multicheck"; 070 071 /** The list of checkboxes. */ 072 protected List<CmsCheckBox> m_checkboxes = new ArrayList<CmsCheckBox>(); 073 074 /** Error display for this widget. */ 075 protected CmsErrorWidget m_error = new CmsErrorWidget(); 076 077 /** The select options of the multi check box. */ 078 protected Map<String, String> m_items = new LinkedHashMap<String, String>(); 079 080 /** Panel which contains all the components of the widget. */ 081 protected Panel m_panel = new FlowPanel(); 082 083 /** 084 * Constructs a new checkbox group from a list of string pairs.<p> 085 * 086 * The first string of every pair is the value of the checkbox, the second string is the label. 087 * 088 * @param items a list of pairs of strings. 089 */ 090 public CmsMultiCheckBox(List<CmsPair<String, String>> items) { 091 092 super(); 093 init(CmsPair.pairsToMap(items)); 094 } 095 096 /** 097 * Constructs a new checkbox group from a map from strings to strings.<p> 098 * 099 * The keys of the map are used as the selection values of the checkboxes, while the value 100 * for a given key in the map is used as the label for the checkbox which is displayed to the user. 101 * 102 * @param items the map of checkbox options 103 */ 104 public CmsMultiCheckBox(Map<String, String> items) { 105 106 super(); 107 init(items); 108 } 109 110 /** 111 * Initializes this class.<p> 112 */ 113 public static void initClass() { 114 115 // registers a factory for creating new instances of this widget 116 CmsWidgetFactoryRegistry.instance().registerFactory(WIDGET_TYPE, new I_CmsFormWidgetFactory() { 117 118 /** 119 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetFactory#createWidget(java.util.Map, com.google.common.base.Optional) 120 */ 121 public I_CmsFormWidget createWidget(Map<String, String> widgetParams, Optional<String> defaultValue) { 122 123 return new CmsMultiCheckBox(widgetParams); 124 } 125 }); 126 } 127 128 /** 129 * @see com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.google.gwt.event.dom.client.FocusHandler) 130 */ 131 public HandlerRegistration addFocusHandler(FocusHandler handler) { 132 133 return addDomHandler(handler, FocusEvent.getType()); 134 } 135 136 /** 137 * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) 138 */ 139 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) { 140 141 return addHandler(handler, ValueChangeEvent.getType()); 142 } 143 144 /** 145 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getApparentValue() 146 */ 147 public String getApparentValue() { 148 149 return getFormValueAsString(); 150 } 151 152 /** 153 * Returns a list of all checkboxes.<p> 154 * 155 * @return a list of checkboxes 156 * */ 157 public List<CmsCheckBox> getCheckboxes() { 158 159 return m_checkboxes; 160 } 161 162 /** 163 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getFieldType() 164 */ 165 public FieldType getFieldType() { 166 167 return I_CmsFormWidget.FieldType.STRING_LIST; 168 } 169 170 /** 171 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getFormValue() 172 */ 173 public Object getFormValue() { 174 175 return new ArrayList<String>(getSelected()); 176 } 177 178 /** 179 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getFormValueAsString() 180 */ 181 public String getFormValueAsString() { 182 183 List<String> selected = new ArrayList<String>(getSelected()); 184 return CmsStringUtil.listAsString(selected, "|"); 185 186 } 187 188 /** 189 * Returns the set of values of the selected checkboxes.<p> 190 * 191 * @return a set of strings 192 */ 193 public Set<String> getSelected() { 194 195 Set<String> result = new HashSet<String>(); 196 int i = 0; 197 for (Map.Entry<String, String> entry : m_items.entrySet()) { 198 String key = entry.getKey(); 199 CmsCheckBox checkBox = m_checkboxes.get(i); 200 if (checkBox.isChecked()) { 201 result.add(key); 202 } 203 i += 1; 204 } 205 return result; 206 } 207 208 /** 209 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#isEnabled() 210 */ 211 public boolean isEnabled() { 212 213 boolean result = true; 214 for (CmsCheckBox checkbox : m_checkboxes) { 215 if (!checkbox.isEnabled()) { 216 result = false; 217 } 218 } 219 return result; 220 } 221 222 /** 223 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#reset() 224 */ 225 public void reset() { 226 227 for (CmsCheckBox checkbox : m_checkboxes) { 228 checkbox.setChecked(false); 229 } 230 } 231 232 /** 233 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setAutoHideParent(org.opencms.gwt.client.ui.I_CmsAutoHider) 234 */ 235 public void setAutoHideParent(I_CmsAutoHider autoHideParent) { 236 237 // nothing to do 238 } 239 240 /** 241 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setEnabled(boolean) 242 */ 243 public void setEnabled(boolean enabled) { 244 245 for (CmsCheckBox checkbox : m_checkboxes) { 246 checkbox.setEnabled(enabled); 247 } 248 } 249 250 /** 251 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setErrorMessage(java.lang.String) 252 */ 253 public void setErrorMessage(String errorMessage) { 254 255 m_error.setText(errorMessage); 256 } 257 258 /** 259 * Sets the value of the widget.<p> 260 * 261 * @param value the new value 262 */ 263 @SuppressWarnings("unchecked") 264 public void setFormValue(Object value) { 265 266 if (value instanceof List<?>) { 267 List<String> keys = (List<String>)value; 268 Set<String> keySet = new HashSet<String>(keys); 269 int i = 0; 270 for (Map.Entry<String, String> entry : m_items.entrySet()) { 271 String key = entry.getKey(); 272 CmsCheckBox checkbox = m_checkboxes.get(i); 273 checkbox.setChecked(keySet.contains(key)); 274 i += 1; 275 } 276 } 277 } 278 279 /** 280 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setFormValueAsString(java.lang.String) 281 */ 282 public void setFormValueAsString(String formValue) { 283 284 if (formValue == null) { 285 formValue = ""; 286 } 287 List<String> values = CmsStringUtil.splitAsList(formValue, "|"); 288 setFormValue(values); 289 } 290 291 /** 292 * Enables or disables italics display in the checkbox labels.<p> 293 * 294 * @param weak true if italics display should be enabled 295 */ 296 public void setTextWeak(boolean weak) { 297 298 String style = I_CmsInputLayoutBundle.INSTANCE.inputCss().weakText(); 299 if (weak) { 300 addStyleName(style); 301 } else { 302 removeStyleName(style); 303 } 304 305 } 306 307 /** 308 * Fires the value change event for the widget.<p> 309 * 310 * @param newValue the new value 311 */ 312 protected void fireValueChanged(String newValue) { 313 314 ValueChangeEvent.fire(this, newValue); 315 } 316 317 /** 318 * Initializes the widget given a map of select options.<p> 319 * 320 * The keys of the map are the values of the select options, while the values of the map 321 * are the labels which should be used for the checkboxes. 322 * 323 * @param items the map of select options 324 */ 325 protected void init(Map<String, String> items) { 326 327 initWidget(m_panel); 328 m_items = new LinkedHashMap<String, String>(items); 329 m_panel.setStyleName(I_CmsInputLayoutBundle.INSTANCE.inputCss().multiCheckBox()); 330 m_panel.addStyleName(I_CmsLayoutBundle.INSTANCE.generalCss().textMedium()); 331 FocusHandler focusHandler = new FocusHandler() { 332 333 public void onFocus(FocusEvent event) { 334 335 CmsDomUtil.fireFocusEvent(CmsMultiCheckBox.this); 336 } 337 }; 338 for (Map.Entry<String, String> entry : items.entrySet()) { 339 String value = entry.getValue(); 340 CmsCheckBox checkbox = new CmsCheckBox(value); 341 // wrap the check boxes in FlowPanels to arrange them vertically 342 FlowPanel checkboxWrapper = new FlowPanel(); 343 checkboxWrapper.add(checkbox); 344 checkbox.addValueChangeHandler(new ValueChangeHandler<Boolean>() { 345 346 public void onValueChange(ValueChangeEvent<Boolean> valueChanged) { 347 348 fireValueChanged(getFormValueAsString()); 349 } 350 }); 351 checkbox.getButton().addFocusHandler(focusHandler); 352 m_panel.add(checkboxWrapper); 353 m_checkboxes.add(checkbox); 354 } 355 m_panel.add(m_error); 356 } 357 358}