Skip to content

Instantly share code, notes, and snippets.

@uklance
Last active December 11, 2015 22:58
Show Gist options
  • Save uklance/4673533 to your computer and use it in GitHub Desktop.
Save uklance/4673533 to your computer and use it in GitHub Desktop.
TabGroup tapestry component for use with twitter-bootstrap CSS.
package mypackage.components;
import javax.inject.Inject;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.services.Request;
import mypackage.TabModel;
/**
* NB: I would have preferred to use an Environmental instead of a request attribute but I can't
* http://tapestry.1045711.n5.nabble.com/5-4-alpha-2-Environment-cloaked-during-ajax-component-event-td5719496.html
*/
public class Tab {
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String label;
@Inject
private ComponentResources componentResources;
@Inject
private Request request;
@SetupRender
boolean setupRender() {
TabModel tabModel = (TabModel) request.getAttribute(TabGroup.ATTRIBUTE_TAB_MODEL);
if (tabModel == null) {
throw new IllegalStateException("Tab must be nested inside a TabGroup");
}
tabModel.getLabelsById().put(componentResources.getId(), label);
// the active tab's body will be rendered by the TabGroup
return false;
}
}
package mypackage.components;
import java.util.Map;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.CleanupRender;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.services.Request;
import mypackage.model.TabModel;
/**
* NB: I would have preferred to use an Environmental instead of a request attribute but I can't
* http://tapestry.1045711.n5.nabble.com/5-4-alpha-2-Environment-cloaked-during-ajax-component-event-td5719496.html
*/
public class TabGroup {
public static final String ATTRIBUTE_TAB_MODEL = TabGroup.class.getName() + ".TAB_MODEL";
@Inject
private Request request;
@Property
private TabModel tabModel;
@Property
private Map.Entry<String, String> tabEntry;
@Parameter(required=true, defaultPrefix=BindingConstants.LITERAL)
private String active;
@Property
private String mutableActive;
@InjectComponent
private Zone tabsZone;
@SetupRender
void setupRender() {
mutableActive = active;
setup();
}
@Inject
private ComponentResources componentResources;
void setup() {
tabModel = new TabModel();
request.setAttribute(ATTRIBUTE_TAB_MODEL, tabModel);
}
@CleanupRender
void cleanupRender() {
request.setAttribute(ATTRIBUTE_TAB_MODEL, null);
}
Block onTabChange(String tabId) {
mutableActive = tabId;
setup();
return tabsZone.getBody();
}
public String getTabClass() {
return tabEntry.getKey().equals(mutableActive) ? "active" : null;
}
public Block getActiveTabBody() {
Component component = componentResources.getContainerResources().getEmbeddedComponent(mutableActive);
return component.getComponentResources().getBody();
}
}
<t:zone t:id="tabsZone" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter">
<t:delegate to="componentResources.body" />
<ul class="nav nav-tabs">
<t:loop source="tabModel.labelsById.entrySet()" value="tabEntry">
<li class="${tabClass}">
<t:eventlink event="tabChange" context="tabEntry.key" zone="^">${tabEntry.value}</t:eventlink>
</li>
</t:loop>
</ul>
<t:delegate to="activeTabBody" />
</t:zone>
package mypackage.model;
import java.util.LinkedHashMap;
import java.util.Map;
public class TabModel {
private Map<String, String> labelsById = new LinkedHashMap<String, String>();
public Map<String, String> getLabelsById() {
return labelsById;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment