001/* 002 * Copyright 2012 GWT-Bootstrap 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.github.gwtbootstrap.client.ui; 017 018import java.util.List; 019 020import com.github.gwtbootstrap.client.ui.base.HasAlternateSize; 021import com.github.gwtbootstrap.client.ui.base.HasId; 022import com.github.gwtbootstrap.client.ui.base.HasSize; 023import com.github.gwtbootstrap.client.ui.base.HasStyle; 024import com.github.gwtbootstrap.client.ui.base.IsResponsive; 025import com.github.gwtbootstrap.client.ui.base.IsSearchQuery; 026import com.github.gwtbootstrap.client.ui.base.ResponsiveHelper; 027import com.github.gwtbootstrap.client.ui.base.SearchQueryStyleHelper; 028import com.github.gwtbootstrap.client.ui.base.SizeHelper; 029import com.github.gwtbootstrap.client.ui.base.Style; 030import com.github.gwtbootstrap.client.ui.base.StyleHelper; 031import com.github.gwtbootstrap.client.ui.constants.AlternateSize; 032import com.github.gwtbootstrap.client.ui.constants.Constants; 033import com.github.gwtbootstrap.client.ui.constants.ControlGroupType; 034import com.github.gwtbootstrap.client.ui.constants.Device; 035import com.google.gwt.dom.client.Element; 036import com.google.gwt.editor.client.EditorError; 037import com.google.gwt.editor.client.HasEditorErrors; 038import com.google.gwt.safehtml.shared.SafeHtmlBuilder; 039import com.google.gwt.user.client.ui.Widget; 040 041/** 042 * A ListBox for Bootstrap form. 043 * 044 * @since 2.0.4.0 045 * 046 * @author ohashi keisuke 047 * 048 */ 049public class ListBox extends com.google.gwt.user.client.ui.ListBox implements HasSize, HasAlternateSize, IsSearchQuery, HasId , IsResponsive , HasStyle, HasEditorErrors<String>{ 050 051 /** Widget for control decoration on <code>EditorError</code>s */ 052 private Widget controlGroup;// could be a ControlGroup widget 053 /** Widget where <code>EditorError</code>s messages will be placed */ 054 private Widget errorLabel;// could be a HelpInline widget 055 056 { 057 setStyleName(""); 058 } 059 060 /** 061 * Creates an empty list box in single selection mode. 062 */ 063 public ListBox() { 064 super(); 065 } 066 067 /** 068 * Creates an empty list box. The preferred way to enable multiple 069 * selections is to use this constructor rather than 070 * {@link #setMultipleSelect(boolean)}. 071 * 072 * @param isMultipleSelect 073 * specifies if multiple selection is enabled 074 */ 075 public ListBox(boolean isMultipleSelect) { 076 super(isMultipleSelect); 077 } 078 079 /** 080 * This constructor may be used by subclasses to explicitly use an existing 081 * element. This element must be a <select> element. 082 * 083 * @param element 084 * the element to be used 085 */ 086 protected ListBox(Element element) { 087 super(element); 088 } 089 090 /** 091 * {@inheritDoc} 092 */ 093 @Override 094 public void setAlternateSize(AlternateSize size) { 095 StyleHelper.changeStyle(this, size, AlternateSize.class); 096 } 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public void setSize(int size) { 103 SizeHelper.setSize(this, size); 104 } 105 106 /** 107 * Get Selected Value. 108 * <p> 109 * If set multiple,return first selected value. 110 * @return Selected Value.(If there is nothing selected item,return null) 111 */ 112 public String getValue() { 113 114 if(getSelectedIndex() == -1) { 115 return null; 116 } 117 118 return getValue(getSelectedIndex()); 119 } 120 121 /** 122 * {@inheritDoc} 123 */ 124 @Override 125 public void setSearchQuery(boolean searchQuery) { 126 SearchQueryStyleHelper.setSearchQuery(this, searchQuery); 127 } 128 129 /** 130 * {@inheritDoc} 131 */ 132 @Override 133 public boolean isSearchQuery() { 134 return SearchQueryStyleHelper.isSearchQuery(this); 135 } 136 137 /** 138 * {@inheritDoc} 139 */ 140 @Override 141 public String getId() { 142 return getElement().getId(); 143 } 144 145 /** 146 * {@inheritDoc} 147 */ 148 @Override 149 public void setId(String id) { 150 getElement().setId(id); 151 } 152 153 /** 154 * {@inheritDoc} 155 */ 156 @Override 157 public void setEnabled(boolean enabled) { 158 super.setEnabled(enabled); 159 if(enabled) { 160 removeStyleName(Constants.DISABLED); 161 } else { 162 addStyleName(Constants.DISABLED); 163 } 164 } 165 166 /** 167 * Selects item which has the given value. If value 168 * is not found, nothing is done. 169 * @param value to be selected (<code>null</code>-safe) 170 */ 171 public void setSelectedValue(String value) { 172 if (value == null) { 173 value = ""; 174 } 175 for(int i = 0; i < getItemCount(); i++) { 176 if (getValue(i).equals(value)) { 177 setSelectedIndex(i); 178 return; 179 } 180 } 181 } 182 183 184 /** 185 * {@inheritDoc} 186 */ 187 @Override 188 public void setShowOn(Device device) { 189 ResponsiveHelper.setShowOn(this, device); 190 } 191 192 /** 193 * {@inheritDoc} 194 */ 195 @Override 196 public void setHideOn(Device device) { 197 ResponsiveHelper.setHideOn(this, device); 198 199 } 200 201 /** 202 * {@inheritDoc} 203 */ 204 @Override 205 public void setStyle(Style style) { 206 StyleHelper.setStyle(this, style); 207 } 208 209 /** 210 * {@inheritDoc} 211 */ 212 @Override 213 public void addStyle(Style style) { 214 StyleHelper.addStyle(this, style); 215 } 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override 221 public void removeStyle(Style style) { 222 StyleHelper.removeStyle(this, style); 223 224 } 225 226 /** 227 * 228 * @see com.google.gwt.editor.client.HasEditorErrors#showErrors(java.util.List) 229 */ 230 @Override 231 public void showErrors(List<EditorError> errors) { 232 Widget decoratedWidget = controlGroup != null? controlGroup : this; 233 if(errors != null && !errors.isEmpty()) { 234 StyleHelper.addStyle(decoratedWidget, ControlGroupType.ERROR); 235 SafeHtmlBuilder sb = new SafeHtmlBuilder(); 236 for (EditorError error : errors) { 237 if(error.getEditor() == this) { 238 error.setConsumed(true); 239 sb.appendEscaped(error.getMessage()); 240 sb.appendHtmlConstant("<br />"); 241 } 242 } 243 setErrorLabelText(sb.toSafeHtml().asString()); 244 } else { 245 StyleHelper.removeStyle(decoratedWidget, ControlGroupType.ERROR); 246 setErrorLabelText(""); 247 } 248 } 249 250 /** 251 * The widget that will be decorated on <code>EditorError</code>s will be added de <code>ControlGroupType.ERROR</code> style. 252 * It can be a ControlGroup or any widget. 253 * @param controlGroup 254 */ 255 public void setControlGroup(Widget controlGroup) { 256 this.controlGroup = controlGroup; 257 } 258 /** 259 * Widget where <code>EditorError</code>s messages will be placed. 260 * It can be a HelpBlock or any other widget. 261 * @param errorLabel 262 */ 263 public void setErrorLabel(Widget errorLabel) { 264 this.errorLabel = errorLabel; 265 } 266 267 /** 268 * Sets the content of the <code>EditorError</code>s messages inside de <code>errorLabel</code>. 269 * This implementation uses {@link Element#setInnerHTML(String)} to set the content. 270 * @param errorMessage 271 */ 272 protected void setErrorLabelText(String errorMessage) { 273 if(errorLabel != null) { 274 errorLabel.getElement().setInnerHTML(errorMessage); 275 } 276 } 277}