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 org.gwtbootstrap3.client.ui.base.AbstractTooltip;
024
025import com.google.gwt.core.client.JavaScriptObject;
026import com.google.gwt.dom.client.Element;
027import com.google.gwt.user.client.ui.Widget;
028
029/**
030 * Basic implementation for the Bootstrap Popover
031 * <p/>
032 * <a href="http://getbootstrap.com/javascript/#popovers">Bootstrap Documentation</a>
033 * <p/>
034 * <p/>
035 * <h3>UiBinder example</h3>
036 * <p/>
037 * 
038 * <pre>
039 * {@code
040 * <b:Popover text="...">
041 *    ...
042 * </b:Popover>
043 * }
044 * </pre>
045 * <p/>
046 *
047 * @author Steven Jardine
048 */
049public class Popover extends AbstractTooltip {
050
051    private static final String TEMPLATE = "<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>";
052
053    private String content = null;
054
055    /**
056     * Creates the empty Popover
057     */
058    public Popover() {
059        super("bs.popover");
060        setAlternateTemplate(TEMPLATE);
061    }
062
063    /**
064     * Creates the popover with given title. Remember to set the content and widget as well.
065     *
066     * @param title title for the popover
067     */
068    public Popover(final String title) {
069        this();
070        setTitle(title);
071    }
072
073    /**
074     * Creates the popover with given title and content. Remember to set the widget as well.
075     *
076     * @param title title for the popover
077     */
078    public Popover(final String title, String content) {
079        this();
080        setTitle(title);
081        setContent(content);
082    }
083
084    /**
085     * Creates the popover around this widget
086     *
087     * @param w widget for the popover
088     */
089    public Popover(final Widget w) {
090        this();
091        setWidget(w);
092    }
093
094    /**
095     * Creates the popover around this widget with given title and content.
096     *
097     * @param w widget for the popover
098     * @param title title for the popover
099     * @param content content for the popover
100     */
101    public Popover(final Widget w, final String title, String content) {
102        this();
103        setWidget(w);
104        setTitle(title);
105        setContent(content);
106    }
107
108    /**
109     * Call the native popover method with the given argument.
110     *
111     * @param e the {@link Element}.
112     * @param arg the arg
113     */
114    private native void call(final Element e, final String arg) /*-{
115        $wnd.jQuery(e).popover(arg);
116    }-*/;
117
118    /** {@inheritDoc} */
119    @Override
120    protected void call(String arg) {
121        call(getWidget().getElement(), arg);
122    }
123
124    /**
125     * @return the content of the popover.
126     */
127    public String getContent() {
128        return content == null ? "" : content;
129    }
130
131    /** {@inheritDoc} */
132    @Override
133    public void init() {
134        Element element = getWidget().getElement();
135        JavaScriptObject baseOptions = createOptions(element, isAnimated(), isHtml(), getSelector(),
136                getTrigger().getCssName(), getShowDelayMs(), getHideDelayMs(), getContainer(), prepareTemplate(), 
137                getViewportSelector(), getViewportPadding());
138        popover(element, baseOptions, getContent());
139        bindJavaScriptEvents(element);
140        setInitialized(true);
141    }
142
143    /**
144     * Create the popover.
145     */
146    private native void popover(Element e, JavaScriptObject options, String content) /*-{
147        var target = this;
148        options['content'] = function(){
149            return target.@org.gwtbootstrap3.client.ui.Popover::getContent()();
150        };
151        $wnd.jQuery(e).popover(options);
152    }-*/;
153
154    /**
155     * @param content the content of the popover to set
156     */
157    public void setContent(String content) {
158        this.content = content;
159    }
160
161    /** {@inheritDoc} */
162    @Override
163    protected void updateTitleWhenShowing() {
164        updateTitleWhenShowing(getWidget().getElement());
165    }
166
167    /**
168     * Update the title. This should only be called when the title is already showing. It causes a small flicker but
169     * updates the title immediately.
170     *
171     * @param e the popover {@link Element}.
172     */
173    private native void updateTitleWhenShowing(Element e) /*-{
174        $wnd.jQuery(e).popover('fixTitle').popover('show');
175    }-*/;
176
177}