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.base; 017 018import com.github.gwtbootstrap.client.ui.NavLink; 019import com.github.gwtbootstrap.client.ui.constants.Alignment; 020import com.github.gwtbootstrap.client.ui.constants.Constants; 021import com.google.gwt.core.client.GWT; 022import com.google.gwt.dom.client.Document; 023import com.google.gwt.dom.client.Element; 024import com.google.gwt.event.dom.client.ChangeEvent; 025import com.google.gwt.event.dom.client.ChangeHandler; 026import com.google.gwt.event.dom.client.ClickEvent; 027import com.google.gwt.event.dom.client.ClickHandler; 028import com.google.gwt.event.dom.client.DomEvent; 029import com.google.gwt.event.dom.client.HasChangeHandlers; 030import com.google.gwt.event.dom.client.HasClickHandlers; 031import com.google.gwt.event.shared.HandlerRegistration; 032import com.google.gwt.uibinder.client.UiChild; 033import com.google.gwt.user.client.ui.HasText; 034import com.google.gwt.user.client.ui.HasWidgets; 035import com.google.gwt.user.client.ui.Widget; 036 037//@formatter:off 038 039/** 040 * Base class for dropdown widgets. 041 * 042 * @author Carlos A Becker 043 * @author Dominik Mayer 044 * @since 2.0.4.0 045 */ 046//@formatter:on 047public abstract class DropdownBase extends ComplexWidget implements HasChangeHandlers, HasClickHandlers, HasWidgets, HasText ,HasIcon { 048 049 private UnorderedList menu = new UnorderedList(); 050 051 protected IconAnchor trigger; 052 053 private NavLink link; 054 055 private NavLinkClickHandler handler = new NavLinkClickHandler(); 056 057 private boolean dropup; 058 059 /** 060 * Creates a new widget of the given type. 061 * 062 * @param type 063 * the HTML tag to be used for the widget 064 */ 065 public DropdownBase(String type) { 066 super(type); 067 createAndAddTrigger(); 068 menu.setStyleName("dropdown-menu"); 069 super.add(menu); 070 } 071 072 private void createAndAddTrigger() { 073 trigger = createTrigger(); 074 trigger.addStyleName("dropdown-toggle"); 075 trigger.getElement().setAttribute(Constants.DATA_TOGGLE, "dropdown"); 076 super.add(trigger); 077 } 078 079 /** 080 * Sets the text of the dropdown trigger. 081 * 082 * @param text 083 */ 084 public void setText(String text) { 085 trigger.setText(text); 086 } 087 088 /** 089 * @return the text of the dropdown trigger. 090 */ 091 public String getText() { 092 return trigger.getText(); 093 } 094 095 /** 096 * Get trigger wiget 097 * @return trigger wiget 098 */ 099 public IconAnchor getTriggerWidget() { 100 return trigger; 101 } 102 103 104 /** 105 * Get menu unordered list widget 106 * @return menu 107 */ 108 public UnorderedList getMenuWiget() { 109 return menu; 110 } 111 /** 112 * Implement this method to create the trigger appropriate for your widget. 113 * It has to be an {@link IconAnchor} or a subtype. 114 * 115 * @return the created trigger 116 */ 117 protected abstract IconAnchor createTrigger(); 118 119 /** 120 * Set dropup style. 121 * 122 * @param dropup 123 * true:Set Dropup false:Un-set Dropup 124 */ 125 public void setDropup(boolean dropup) { 126 127 this.dropup = dropup; 128 129 if (dropup) 130 addStyleName(Constants.DROPUP); 131 else 132 removeStyleName(Constants.DROPUP); 133 } 134 135 /** 136 * Is widget dropup? 137 * @return true:Dropup false:Dropdown 138 */ 139 public boolean isDropup() { 140 return this.dropup; 141 } 142 143 /** 144 * {@inheritDoc} 145 */ 146 @Override 147 protected void onLoad() { 148 super.onLoad(); 149 if (trigger != null) { 150 configure(trigger.getElement()); 151 } 152 } 153 154 /** 155 * Adds a widget to the dropdown menu. 156 * 157 * @param widget 158 * the widget that will be added to the menu 159 * @see #addWidget(Widget) 160 */ 161 @Override 162 public void add(Widget widget) { 163 menu.add(widget); 164 if (widget instanceof NavLink) { 165 ((NavLink) widget).addClickHandler(handler); 166 } 167 } 168 169 @Override 170 public HandlerRegistration addChangeHandler(ChangeHandler handler) { 171 return addDomHandler(handler, ChangeEvent.getType()); 172 } 173 /** 174 * Adds a widget to the the dropdown widget, <b>not</b> to the dropdown 175 * menu. 176 * <p/> 177 * <p/> 178 * Use {@link #add(Widget)} if you want to add a widget to the dropdown 179 * menu. 180 * 181 * @param widget 182 * the widget to be added. 183 */ 184 protected void addWidget(Widget widget) { 185 super.add(widget); 186 } 187 188 private native void configure(Element e) /*-{ 189 $wnd.jQuery(e).dropdown(); 190 }-*/; 191 192 /** 193 * Pull the dropdown menu to right 194 * 195 * @param rightDropdown 196 * <code>true</code> pull to right, otherwise to left. Default is 197 * <code>false</code> 198 */ 199 public void setRightDropdown(boolean rightDropdown) { 200 menu.setStyleName(Alignment.RIGHT.get(), rightDropdown); 201 } 202 203 private class NavLinkClickHandler implements ClickHandler { 204 205 @Override 206 public void onClick(ClickEvent event) { 207 try { 208 IconAnchor iconAnchor = (IconAnchor) event.getSource(); 209 link = (NavLink) iconAnchor.getParent(); 210 } catch (Exception e) { 211 GWT.log(e.getMessage() , e); 212 } 213 DomEvent.fireNativeEvent(Document.get().createChangeEvent(), DropdownBase.this); 214 } 215 216 } 217 218 /** 219 * Method to get the {@link NavLink} that has been clicked most recently. 220 * 221 * @return Last clicked NavLink or <code>null</code> if none have been 222 * clicked. 223 */ 224 public NavLink getLastSelectedNavLink() { 225 return link; 226 } 227 228 @Override 229 public void clear() { 230 menu.clear(); 231 } 232 233 @Override 234 public HandlerRegistration addClickHandler(ClickHandler handler) { 235 return trigger.addClickHandler(handler); 236 } 237 238 /** 239 * Add widget to trigger anchodr 240 * @param w added widget 241 */ 242 @UiChild(tagname="customTrigger" , limit=1) 243 public void addCustomTrigger(Widget w) { 244 trigger.insert(w , 0); 245 } 246 247}