001package org.gwtbootstrap3.client.ui;
002
003/*
004 * #%L
005 * GwtBootstrap3
006 * %%
007 * Copyright (C) 2013 - 2015 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 com.google.gwt.dom.client.Element;
024import com.google.gwt.event.shared.HandlerRegistration;
025import com.google.gwt.user.client.Event;
026import com.google.gwt.user.client.ui.Widget;
027import org.gwtbootstrap3.client.shared.event.TabShowEvent;
028import org.gwtbootstrap3.client.shared.event.TabShowHandler;
029import org.gwtbootstrap3.client.shared.event.TabShownEvent;
030import org.gwtbootstrap3.client.shared.event.TabShownHandler;
031import org.gwtbootstrap3.client.ui.base.HasDataTarget;
032import org.gwtbootstrap3.client.ui.constants.IconSize;
033import org.gwtbootstrap3.client.ui.constants.IconType;
034import org.gwtbootstrap3.client.ui.constants.Toggle;
035
036import java.util.List;
037
038/**
039 * List item for the nav tabs, needs special toggle and JS to make it work properly
040 * <p/>
041 * <a href="http://getbootstrap.com/javascript/#tabs">Bootstrap Documentation</a>
042 * <p/>
043 * <h3>UiBinder example</h3>
044 * <p/>
045 * <pre>
046 * {@code
047 * <b:NavTabs>
048 *    <b:TabListItem/>
049 *    <b:TabListItem/>
050 * </b:NavTabs>
051 * }
052 * </pre>
053 *
054 * @author Joshua Godi
055 * @author Drew Spencer
056 * @see org.gwtbootstrap3.client.ui.NavTabs
057 */
058public class TabListItem extends AnchorListItem implements HasDataTarget {
059
060    /**
061     * Creates the default widget with no text
062     */
063    public TabListItem() {
064        this("");
065    }
066
067    /**
068     * Creates the default widget with the desired text
069     *
070     * @param text text for the list item
071     */
072    public TabListItem(final String text) {
073        super(text);
074        setDataToggle(Toggle.TAB);
075    }
076
077    public TabListItem(final String text, final IconType iconType) {
078        this(text);
079        setIcon(iconType);
080    }
081
082    public TabListItem(final String text, final IconType iconType, final IconSize iconSize) {
083        this(text, iconType);
084        setIconSize(iconSize);
085    }
086
087    public TabListItem(final String text, final String badgeText) {
088        this(text);
089        setBadgeText(badgeText);
090    }
091
092    /**
093     * Forces the tab pane associated with this list item to be shown and default fires the events
094     */
095    public void showTab() {
096        showTab(true);
097    }
098
099    /**
100     * Forces the tab pane associated with this list item to be shown
101     *
102     * @param fireEvents true=fire show/hide events, false=don't fire show/hide events
103     */
104    public void showTab(final boolean fireEvents) {
105        showTab(anchor.getElement());
106
107        if (fireEvents) {
108            fireEvent(new TabShowEvent(this, null));
109        }
110    }
111
112    /**
113     * Add a show handler for the tab
114     *
115     * @param showHandler show handler
116     * @return HandlerRegistration to manage handles
117     */
118    public HandlerRegistration addShowHandler(final TabShowHandler showHandler) {
119        return addHandler(showHandler, TabShowEvent.getType());
120    }
121
122    /**
123     * Add a shown handler for the tab
124     *
125     * @param shownHandler show handler
126     * @return HandlerRegistration to manage handles
127     */
128    public HandlerRegistration addShownHandler(final TabShownHandler shownHandler) {
129        return addHandler(shownHandler, TabShownEvent.getType());
130    }
131
132    /**
133     * We override set href here because we want to ensure that projects with gwt places and gwtp
134     * don't try to execute a place change event with it being clicked
135     */
136    @Override
137    public void setHref(final String href) {
138        setDataTarget(href);
139    }
140
141    /** {@inheritDoc} */
142    @Override
143    public String getHref() {
144        return getDataTarget();
145    }
146
147    /** {@inheritDoc} */
148    @Override
149    public void setDataTargetWidgets(final List<Widget> widgets) {
150        anchor.setDataTargetWidgets(widgets);
151    }
152
153    /** {@inheritDoc} */
154    @Override
155    public void setDataTargetWidget(final Widget widget) {
156        anchor.setDataTargetWidget(widget);
157    }
158
159    /** {@inheritDoc} */
160    @Override
161    public void setDataTarget(final String dataTarget) {
162        anchor.setDataTarget(dataTarget);
163    }
164
165    /** {@inheritDoc} */
166    @Override
167    public String getDataTarget() {
168        return anchor.getDataTarget();
169    }
170
171    /** {@inheritDoc} */
172    @Override
173    public void setEnabled(final boolean enabled) {
174        super.setEnabled(enabled);
175
176        // On enable/disable we need to add/remove the data toggle for it to work properly
177        if (enabled) {
178            setDataToggle(Toggle.TAB);
179        } else {
180            setDataToggle(null);
181        }
182    }
183
184    /** {@inheritDoc} */
185    @Override
186    protected void onLoad() {
187        super.onLoad();
188
189        // Bind JS Events
190        bindJavaScriptEvents(anchor.getElement());
191    }
192
193    /** {@inheritDoc} */
194    @Override
195    protected void onUnload() {
196        super.onUnload();
197
198        // Unbind JS events
199        unbindJavaScriptEvents(anchor.getElement());
200    }
201
202    public String getHTML() {
203        return anchor.getHTML();
204    }
205
206    public void setHTML(final String html) {
207        anchor.setHTML(html);
208    }
209
210    /**
211     * Can be override by subclasses to handle Tabs's "show" event however
212     * it's recommended to add an event handler to the tab.
213     *
214     * @param evt Event
215     * @see org.gwtbootstrap3.client.shared.event.ShowEvent
216     */
217    protected void onShow(final Event evt) {
218        fireEvent(new TabShowEvent(this, evt));
219    }
220
221    /**
222     * Can be override by subclasses to handle Tabs's "shown" event however
223     * it's recommended to add an event handler to the tab.
224     *
225     * @param evt Event
226     * @see org.gwtbootstrap3.client.shared.event.ShownEvent
227     */
228    protected void onShown(final Event evt) {
229        fireEvent(new TabShownEvent(this, evt));
230    }
231
232    private native void showTab(Element e) /*-{
233        $wnd.jQuery(e).tab('show');
234    }-*/;
235
236    // @formatter:off
237    private native void bindJavaScriptEvents(final Element e) /*-{
238        var target = this;
239        var $tab = $wnd.jQuery(e);
240
241        $tab.on('show.bs.tab', function (evt) {
242            target.@org.gwtbootstrap3.client.ui.TabListItem::onShow(Lcom/google/gwt/user/client/Event;)(evt);
243        });
244
245        $tab.on('shown.bs.tab', function (evt) {
246            target.@org.gwtbootstrap3.client.ui.TabListItem::onShown(Lcom/google/gwt/user/client/Event;)(evt);
247        });
248    }-*/;
249
250    private native void unbindJavaScriptEvents(final Element e) /*-{
251        $wnd.jQuery(e).off('show.bs.tab');
252        $wnd.jQuery(e).off('shown.bs.tab');
253    }-*/;
254    
255}