001package com.github.gwtbootstrap.client.ui;
002
003import com.github.gwtbootstrap.client.ui.base.MarkupWidget;
004import com.github.gwtbootstrap.client.ui.constants.Constants;
005import com.google.gwt.core.client.Scheduler;
006import com.google.gwt.core.client.Scheduler.ScheduledCommand;
007import com.google.gwt.event.dom.client.ClickEvent;
008import com.google.gwt.event.dom.client.ClickHandler;
009import com.google.gwt.event.dom.client.HasClickHandlers;
010import com.google.gwt.user.client.Element;
011import com.google.gwt.user.client.ui.Widget;
012
013/**
014 * Markup widget of CollapseTrigger
015 * <p>
016 * It's a markup widget (decorator widget).
017 * it's can exchange child to {@link Collapse}'s toggle trigger widget.
018 * 
019 * <p>
020 * <h3>UiBinder Usage:</h3>
021 * </p>
022 * <pre>
023 * {@code
024 * <b:CollapseTrigger target="#toggle1">
025 *      <b:Button>Collapse Trigger</b:Button>
026 * </b:CollapseTrigger>
027 *
028 * <!-- if use collapse trigger, you must set existTrigger=true attribute to Collapse tag. -->
029 * <b:Collapse existTrigger="true" b:id="toggle1" defaultOpen="true">
030 *     <b:FluidRow>
031 *         <b:Column size="12">
032 *             <b:Alert close="false" animation="true" heading="collapsible1">
033 *                 <b:Paragraph>
034 *                     Hello :D
035 *                 </b:Paragraph>
036 *             </b:Alert>
037 *         </b:Column>
038 *     </b:FluidRow>
039 * </b:Collapse>
040 * }
041 * </pre>
042 * 
043 * @since 2.2.1.0
044 * @author ohashi keisuke
045 * @see Accordion
046 * @see Collapse
047 * @see CollapseTrigger
048 * @see <a href="http://twitter.github.com/bootstrap/javascript.html#collapse">Twitter Bootstrap document</a>
049 *
050 */
051public class CollapseTrigger extends MarkupWidget {
052
053    private String target;
054    
055    private String parent;
056
057    private boolean isAccordionTrigger = false;
058
059    /**
060     * Create an empty widget with target selector
061     * @param target selector (eg: #myCollapse)
062     */
063    public CollapseTrigger(String target) {
064        this.target = target;
065    }
066    
067    /**
068     * Create an empty widget.
069     */
070    public CollapseTrigger() {
071    }
072    
073    /**
074     * {@inheritDoc}
075     */
076    @Override
077    public Widget asWidget() {
078        
079        if(widget != null) {
080            Element element = widget.getElement();
081
082            if (isAccordionTrigger) {
083                element.setAttribute(Constants.DATA_TOGGLE, Constants.COLLAPSE);
084                element.removeAttribute(Constants.DATA_TARGET);
085                element.setAttribute("href", target);
086                if(parent != null && !parent.isEmpty()) {
087                    setParent(parent);
088                }
089                Scheduler.get().scheduleDeferred(new ScheduledCommand() {
090                    @Override
091                    public void execute() {
092                        Collapse.configure(target, parent, false);
093                    }
094                });
095                return super.asWidget();
096            }
097
098            if(element.hasAttribute(Constants.DATA_TOGGLE)
099                    && widget instanceof HasClickHandlers
100                    && !widget.isAttached()) {
101                Scheduler.get().scheduleDeferred(new ScheduledCommand() {
102
103                    @Override
104                    public void execute() {
105                        Collapse.configure(target, parent, false);
106                        ((HasClickHandlers)widget).addClickHandler(new ClickHandler() {
107
108                            @Override
109                            public void onClick(ClickEvent event) {
110                                Collapse.changeVisibility(target, "toggle");
111                            }
112                        });
113                    }
114                });
115                return super.asWidget();
116            }
117
118            element.setAttribute(Constants.DATA_TARGET, target);
119            element.setAttribute(Constants.DATA_TOGGLE, Constants.COLLAPSE);
120
121            if(parent != null && !parent.isEmpty()) {
122                setParent(parent);
123            }
124            
125        }
126        
127        return super.asWidget();
128    }
129    
130    /**
131     * Set target collapse selector.
132     * @param target selector of target. (eg:#myCollapse)
133     */
134    public void setTarget(String target) {
135        this.target = target;
136        
137        if(widget != null) {
138            Element element = widget.getElement();
139            element.setAttribute(Constants.DATA_TARGET, target);
140        }
141    }
142    
143    /**
144     * Get target collapse selector.
145     * @return selector.
146     */
147    public String getTarget(){
148        return this.target;
149    }
150
151
152    /**
153     * Set parent selector.
154     * 
155     * it only work with {@link AccordionGroup},
156     * Please see <a href="https://github.com/twitter/bootstrap/issues/4988">this issue</a>.
157     * 
158     * @param parent parent selector
159     */
160    public void setParent(String parent) {
161        this.parent = parent;
162        
163        if(widget != null) {
164            widget.getElement().setAttribute("data-parent", parent);
165        }
166        
167    }
168
169    protected boolean isAccordionTrigger() {
170        return isAccordionTrigger;
171    }
172
173    protected void setAccordionTrigger(boolean accordionTrigger) {
174        isAccordionTrigger = accordionTrigger;
175    }
176}