001package org.gwtbootstrap3.client.ui; 002 003/* 004 * #%L 005 * GwtBootstrap3 006 * %% 007 * Copyright (C) 2013 GwtBootstrap3 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import org.gwtbootstrap3.client.ui.constants.Styles; 024import org.gwtbootstrap3.client.ui.impl.RadioImpl; 025 026import com.google.gwt.core.shared.GWT; 027import com.google.gwt.dom.client.Document; 028import com.google.gwt.dom.client.Element; 029import com.google.gwt.dom.client.InputElement; 030import com.google.gwt.dom.client.LabelElement; 031import com.google.gwt.event.logical.shared.ValueChangeEvent; 032import com.google.gwt.i18n.client.HasDirection.Direction; 033import com.google.gwt.i18n.shared.DirectionEstimator; 034import com.google.gwt.safehtml.shared.SafeHtml; 035import com.google.gwt.uibinder.client.UiConstructor; 036import com.google.gwt.user.client.DOM; 037 038/** 039 * A mutually-exclusive selection radio button widget. Fires 040 * {@link com.google.gwt.event.dom.client.ClickEvent ClickEvents} when the radio 041 * button is clicked, and {@link ValueChangeEvent ValueChangeEvents} when the 042 * button becomes checked. Note, however, that browser limitations prevent 043 * ValueChangeEvents from being sent when the radio button is cleared as a side 044 * effect of another in the group being clicked. 045 * 046 * <p> 047 * <h3>Built-in Bidi Text Support</h3> 048 * This widget is capable of automatically adjusting its direction according to 049 * its content. This feature is controlled by {@link #setDirectionEstimator} or 050 * passing a DirectionEstimator parameter to the constructor, and is off by 051 * default. 052 * </p> 053 * 054 * @author Sven Jacobs 055 */ 056public class Radio extends CheckBox { 057 058 private static final RadioImpl impl = GWT.create(RadioImpl.class); 059 060 /** 061 * Creates a new radio associated with a particular group, and initialized 062 * with the given HTML label. All radio buttons associated with the same 063 * group name belong to a mutually-exclusive set. 064 * 065 * Radio buttons are grouped by their name attribute, so changing their name 066 * using the setName() method will also change their associated group. 067 * 068 * @param name 069 * the group name with which to associate the radio button 070 * @param label 071 * this radio button's html label 072 */ 073 public Radio(String name, SafeHtml label) { 074 this(name, label.asString(), true); 075 } 076 077 /** 078 * @see #RadioButton(String, SafeHtml) 079 * 080 * @param name 081 * the group name with which to associate the radio button 082 * @param label 083 * this radio button's html label 084 * @param dir 085 * the text's direction. Note that {@code DEFAULT} means 086 * direction should be inherited from the widget's parent 087 * element. 088 */ 089 public Radio(String name, SafeHtml label, Direction dir) { 090 this(name); 091 setHTML(label, dir); 092 } 093 094 /** 095 * @see #RadioButton(String, SafeHtml) 096 * 097 * @param name 098 * the group name with which to associate the radio button 099 * @param label 100 * this radio button's html label 101 * @param directionEstimator 102 * A DirectionEstimator object used for automatic direction 103 * adjustment. For convenience, 104 * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used. 105 */ 106 public Radio(String name, SafeHtml label, DirectionEstimator directionEstimator) { 107 this(name); 108 setDirectionEstimator(directionEstimator); 109 setHTML(label.asString()); 110 } 111 112 /** 113 * Creates a new radio associated with a particular group, and initialized 114 * with the given HTML label. All radio buttons associated with the same 115 * group name belong to a mutually-exclusive set. 116 * 117 * Radio buttons are grouped by their name attribute, so changing their name 118 * using the setName() method will also change their associated group. 119 * 120 * @param name 121 * the group name with which to associate the radio button 122 * @param label 123 * this radio button's label 124 */ 125 public Radio(String name, String label) { 126 this(name); 127 setText(label); 128 } 129 130 /** 131 * @see #RadioButton(String, SafeHtml) 132 * 133 * @param name 134 * the group name with which to associate the radio button 135 * @param label 136 * this radio button's label 137 * @param dir 138 * the text's direction. Note that {@code DEFAULT} means 139 * direction should be inherited from the widget's parent 140 * element. 141 */ 142 public Radio(String name, String label, Direction dir) { 143 this(name); 144 setText(label, dir); 145 } 146 147 /** 148 * @see #RadioButton(String, SafeHtml) 149 * 150 * @param name 151 * the group name with which to associate the radio button 152 * @param label 153 * this radio button's label 154 * @param directionEstimator 155 * A DirectionEstimator object used for automatic direction 156 * adjustment. For convenience, 157 * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used. 158 */ 159 public Radio(String name, String label, DirectionEstimator directionEstimator) { 160 this(name); 161 setDirectionEstimator(directionEstimator); 162 setText(label); 163 } 164 165 /** 166 * Creates a new radio button associated with a particular group, and 167 * initialized with the given label (optionally treated as HTML). All radio 168 * buttons associated with the same group name belong to a 169 * mutually-exclusive set. 170 * 171 * Radio buttons are grouped by their name attribute, so changing their name 172 * using the setName() method will also change their associated group. 173 * 174 * @param name 175 * name the group with which to associate the radio button 176 * @param label 177 * this radio button's label 178 * @param asHTML 179 * <code>true</code> to treat the specified label as HTML 180 */ 181 public Radio(String name, String label, boolean asHTML) { 182 this(name); 183 if (asHTML) { 184 setHTML(label); 185 } else { 186 setText(label); 187 } 188 } 189 190 /** 191 * Creates a new radio associated with a particular group name. All radio 192 * buttons associated with the same group name belong to a 193 * mutually-exclusive set. 194 * 195 * Radio buttons are grouped by their name attribute, so changing their name 196 * using the setName() method will also change their associated group. 197 * 198 * @param name 199 * the group name with which to associate the radio button 200 */ 201 @UiConstructor 202 public Radio(String name) { 203 super(DOM.createDiv(), Document.get().createRadioInputElement(name)); 204 setStyleName(Styles.RADIO); 205 206 LabelElement label = Document.get().createLabelElement(); 207 label.appendChild(inputElem); 208 label.appendChild(labelElem); 209 210 getElement().appendChild(label); 211 } 212 213 protected Radio(Element elem, InputElement inputElement) { 214 super(elem, inputElement); 215 } 216 217 /** 218 * Change the group name of this radio button. 219 * 220 * Radio buttons are grouped by their name attribute, so changing their name 221 * using the setName() method will also change their associated group. 222 * 223 * If changing this group name results in a new radio group with multiple 224 * radio buttons selected, this radio button will remain selected and the 225 * other radio buttons will be unselected. 226 * 227 * @param name 228 * name the group with which to associate the radio button 229 */ 230 @Override 231 public void setName(String name) { 232 super.setName(name); 233 } 234 235 @Override 236 protected void ensureDomEventHandlers() { 237 impl.ensureDomEventHandlers(this); 238 } 239 240 @Override 241 public void sinkEvents(int eventBitsToAdd) { 242 if (isOrWasAttached()) { 243 impl.sinkEvents(eventBitsToAdd, inputElem, labelElem); 244 } else { 245 super.sinkEvents(eventBitsToAdd); 246 } 247 } 248 249}