From 9f4228af66b33edf15b1cc13fcb7752d81b2e134 Mon Sep 17 00:00:00 2001 From: Brian Leathem Date: Mon, 23 Dec 2013 16:34:45 -0800 Subject: [PATCH] RF-13278: Added a tabPanel@headers metacomponent to the tab panel --- .../ui/toggle/tabPanel/AbstractTabPanel.java | 21 +++++++++++++++++++ .../ui/toggle/tabPanel/TabPanelRenderer.java | 19 +++++++++++++++++ .../togglePanel/AbstractTogglePanel.java | 8 +++++-- .../ui/tabPanel/ITStaticTabTest.java | 18 +++++++++++----- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/AbstractTabPanel.java b/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/AbstractTabPanel.java index f7d62e4ded..28cc92a0da 100644 --- a/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/AbstractTabPanel.java +++ b/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/AbstractTabPanel.java @@ -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; + /** *

The <r:tabPanel> 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 <r:tabPanel> container is a <r:tab> @@ -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"; @@ -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); + } } diff --git a/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/TabPanelRenderer.java b/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/TabPanelRenderer.java index a6154c5704..9f13911d08 100644 --- a/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/TabPanelRenderer.java +++ b/framework/src/main/java/org/richfaces/ui/toggle/tabPanel/TabPanelRenderer.java @@ -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; @@ -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); @@ -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 { diff --git a/framework/src/main/java/org/richfaces/ui/toggle/togglePanel/AbstractTogglePanel.java b/framework/src/main/java/org/richfaces/ui/toggle/togglePanel/AbstractTogglePanel.java index 74755046f5..0388e738c7 100644 --- a/framework/src/main/java/org/richfaces/ui/toggle/togglePanel/AbstractTogglePanel.java +++ b/framework/src/main/java/org/richfaces/ui/toggle/togglePanel/AbstractTogglePanel.java @@ -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; @@ -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; } @@ -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); + } } diff --git a/framework/src/test/integration/org/richfaces/ui/tabPanel/ITStaticTabTest.java b/framework/src/test/integration/org/richfaces/ui/tabPanel/ITStaticTabTest.java index 1301692871..83b0e4c074 100644 --- a/framework/src/test/integration/org/richfaces/ui/tabPanel/ITStaticTabTest.java +++ b/framework/src/test/integration/org/richfaces/ui/tabPanel/ITStaticTabTest.java @@ -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; @@ -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()); } @@ -180,10 +183,15 @@ private static void addHeaderPage(FrameworkDeployment deployment) { p.body(""); p.body(""); - p.body(" "); + p.body(" "); // header='tab0 header' "); + p.body(" "); + p.body(" "); + p.body(" "); p.body(" content of tab 1"); p.body(" "); p.body(" ");