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}