Skip to content
This repository has been archived by the owner on Apr 11, 2018. It is now read-only.

RF-13278: Added a tabPanel@headers metacomponent to the tab panel #71

Merged
merged 1 commit into from Dec 24, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -26,12 +26,19 @@
import org.richfaces.cdk.annotations.JsfRenderer;
import org.richfaces.cdk.annotations.Tag;
import org.richfaces.cdk.annotations.TagType;
import org.richfaces.context.ExtendedVisitContext;
import org.richfaces.ui.attribute.CoreProps;
import org.richfaces.ui.attribute.EventsMouseProps;
import org.richfaces.ui.attribute.I18nProps;
import org.richfaces.ui.common.meta.MetaComponentResolver;
import org.richfaces.ui.toggle.TogglePanelTagHandler;
import org.richfaces.ui.toggle.togglePanel.AbstractTogglePanel;

import javax.faces.component.UIComponent;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;

/**
* <p>The &lt;r:tabPanel&gt; component provides a set of tabbed panels for displaying one panel of content at a time.
* The tabs can be highly customized and themed. Each tab within a &lt;r:tabPanel&gt; container is a &lt;r:tab&gt;
Expand All @@ -42,6 +49,7 @@
@JsfComponent(tag = @Tag(type = TagType.Facelets, handlerClass = TogglePanelTagHandler.class),
renderer = @JsfRenderer(type = "org.richfaces.ui.TabPanelRenderer"))
public abstract class AbstractTabPanel extends AbstractTogglePanel implements CoreProps, EventsMouseProps, I18nProps {
public static final String HEADERS_META_COMPONENT = "headers";
public static final String COMPONENT_TYPE = "org.richfaces.ui.TabPanel";
public static final String COMPONENT_FAMILY = "org.richfaces.ui.TabPanel";

Expand Down Expand Up @@ -128,4 +136,17 @@ public boolean isHeaderPositionedTop() {
public boolean isHeaderAlignedLeft() {
return (null == this.getHeaderAlignment()) || (this.getHeaderAlignment().equals(HeaderAlignment.left));
}

public String resolveClientId(FacesContext facesContext, UIComponent contextComponent, String metaComponentId) {
if (HEADERS_META_COMPONENT.equals(metaComponentId)) {
return getClientId(facesContext) + MetaComponentResolver.META_COMPONENT_SEPARATOR_CHAR + metaComponentId;
}
return null;
}

@Override
protected VisitResult visitMetaComponents(ExtendedVisitContext extendedVisitContext, VisitCallback callback) {
extendedVisitContext.invokeMetaComponentVisitCallback(this, callback, AbstractTabPanel.HEADERS_META_COMPONENT);
return super.visitMetaComponents(extendedVisitContext, callback);
}
}
Expand Up @@ -41,11 +41,14 @@
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
import javax.faces.context.PartialResponseWriter;
import javax.faces.context.ResponseWriter;

import org.richfaces.cdk.annotations.JsfRenderer;
import org.richfaces.context.ExtendedVisitContext;
import org.richfaces.javascript.JSObject;
import org.richfaces.renderkit.RenderKitUtils;
import org.richfaces.ui.common.HtmlConstants;
Expand Down Expand Up @@ -108,6 +111,8 @@ private void writeTabsLineSeparator(ResponseWriter writer, UIComponent component

private void writeTabsLine(ResponseWriter w, FacesContext context, UIComponent comp) throws IOException {
w.startElement(DIV, comp);
String id = comp.getClientId() + AbstractTabPanel.HEADERS_META_COMPONENT;
w.writeAttribute(ID_ATTRIBUTE, id, null);
AbstractTabPanel tabPanel = (AbstractTabPanel) comp;
if (tabPanel.isHeaderPositionedTop()) {
w.writeAttribute(CLASS, "rf-tab-hdr-tabline-vis rf-tab-hdr-tabline-top", null);
Expand Down Expand Up @@ -183,6 +188,20 @@ private String positionAbbreviation(AbstractTab tab) {
}
}

@Override
public void encodeMetaComponent(FacesContext context, UIComponent component, String metaComponentId) throws IOException {
if (AbstractTabPanel.HEADERS_META_COMPONENT.equals(metaComponentId)) {
AbstractTabPanel panel = (AbstractTabPanel) component;
PartialResponseWriter w = context.getPartialViewContext().getPartialResponseWriter();
String id = component.getClientId() + AbstractTabPanel.HEADERS_META_COMPONENT;
w.startUpdate(id);
writeTabsLine(w, context, panel);
w.endUpdate();
} else {
super.encodeMetaComponent(context, component, metaComponentId);
}
}

private void encodeTabHeader(FacesContext context, AbstractTab tab, ResponseWriter writer,
AbstractTogglePanelTitledItem.HeaderStates state, Boolean isDisplay) throws IOException {

Expand Down
Expand Up @@ -79,6 +79,7 @@
import org.richfaces.ui.toggle.TogglePanelVisitCallback;
import org.richfaces.ui.toggle.TogglePanelVisitException;
import org.richfaces.ui.toggle.TogglePanelVisitState;
import org.richfaces.ui.toggle.tabPanel.AbstractTabPanel;
import org.richfaces.util.MessageUtil;
import org.richfaces.util.RendererUtils;

Expand Down Expand Up @@ -923,8 +924,7 @@ public boolean visitTree(VisitContext context, VisitCallback callback) {
ExtendedVisitContext extendedVisitContext = (ExtendedVisitContext) context;
if (extendedVisitContext.getVisitMode() == ExtendedVisitContextMode.RENDER) {

result = extendedVisitContext.invokeMetaComponentVisitCallback(this, callback,
ACTIVE_ITEM_META_COMPONENT);
result = visitMetaComponents(extendedVisitContext, callback);
if (result == VisitResult.COMPLETE) {
return true;
}
Expand All @@ -949,5 +949,9 @@ public boolean visitTree(VisitContext context, VisitCallback callback) {

return false;
}

protected VisitResult visitMetaComponents(ExtendedVisitContext extendedVisitContext, VisitCallback callback) {
return extendedVisitContext.invokeMetaComponentVisitCallback(this, callback, ACTIVE_ITEM_META_COMPONENT);
}
}

Expand Up @@ -73,6 +73,9 @@ public class ITStaticTabTest {
@FindBy(id = "out")
private WebElement out;

@FindBy(id = "myForm:button")
private WebElement button;

@FindBy(id = "myForm:inputText")
private WebElement inputText;

Expand Down Expand Up @@ -138,7 +141,7 @@ public void check_tab_execute() {
public void check_header_render() {
browser.get(contextPath.toExternalForm() + "header.jsf");
Assert.assertEquals("0 clicks", inactiveHeaders.get(1).findElement(By.className("rf-tab-lbl")).getText());
guardAjax(activeHeaders.get(0)).click();
guardAjax(activeHeaders.get(0).findElement(By.className("button"))).click();
Assert.assertEquals("1 clicks", inactiveHeaders.get(1).findElement(By.className("rf-tab-lbl")).getText());
}

Expand Down Expand Up @@ -180,10 +183,15 @@ private static void addHeaderPage(FrameworkDeployment deployment) {

p.body("<h:form id='myForm'>");
p.body("<r:tabPanel id='tabPanel' >");
p.body(" <r:tab id='tab0' name='tab0' header='tab0 header' ");
p.body(" action='#{simpleBean.incrementCount()}'");
p.body(" render='tabPanel' ");
p.body(" execute='@this'> ");
p.body(" <r:tab id='tab0' name='tab0'> "); // header='tab0 header' ");
p.body(" <f:facet name='header'> ");
p.body(" <r:commandLink value='click me' ");
p.body(" styleClass='button' ");
p.body(" action='#{simpleBean.incrementCount()}' ");
p.body(" render='tabPanel@headers' ");
p.body(" oncomplete='return false;' ");
p.body(" execute='@this' /> ");
p.body(" </f:facet> ");
p.body(" content of tab 1");
p.body(" </r:tab>");
p.body(" <r:tab id='tab1'>");
Expand Down