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