Question

I tried to include multiple source page path using ui:include tag in different tabs. The problem is when i gave the source page path as static one means that page will be shown but if give the source page path from backing bean mean it won't include the page.

Here is my code

template.xhtml:

    <p:layoutUnit position="center" id="layoutCenter">
                <h:form id="tempFormId">
                    <p:tabView value="#{multiTabBean.tabsList}" var="useCase"
                        activeIndex="#{multiTabBean.activeTabIndex}">
                        <p:tab title="#{useCase.title}" closable="true">
                            <f:subview>
                                <h:panelGroup id="mainTempPanelGroupId" layout="block">
                                    <ui:include src="#{useCase.path}" />
                                </h:panelGroup>

                            </f:subview>
                        </p:tab>
                    </p:tabView>
                </h:form>
            </p:layoutUnit>

bean:

public String menuAction() {                    
    menuBtnRendered = true;
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    selectedModuleViewId = externalContext.getRequestParameterMap().get(
            "moduleViewId");

    tabsList.add(new Tab(getTabId(selectedModuleViewId),
                selectedModuleViewId, getModulePath(selectedModuleViewId)));        

    return null;
}

I'm using @ViewScoped.

Était-ce utile?

La solution

<ui:include> runs during view build time (when XHTML is turned into JSF component tree). <p:tabView> runs during view render time (when JSF component tree needs to produce HTML).

So, <p:tabView var> isn't available when <ui:include> runs. This problem is detailed in this answer: JSTL in JSF2 Facelets... makes sense? (<ui:include> is a taghandler and has hence same lifecycle as JSTL tags).

You can solve this to a certain degree by using <c:forEach> to produce <p:tab>s instead of <p:tabView value>.

<p:tabView activeIndex="#{multiTabBean.activeTabIndex}">
    <c:forEach items="#{multiTabBean.tabsList}" var="useCase" varStatus="loop">
        <p:tab title="#{useCase.title}" closable="true">
            <f:subview id="tab_#{loop.index}">
                <h:panelGroup id="mainTempPanelGroupId" layout="block">
                    <ui:include src="#{useCase.path}" />
                </h:panelGroup>
            </f:subview>
        </p:tab>
    </c:forEach>
</p:tabView>

It's by the way interesting to see that you somehow used <f:subview> in your initial attempt which is completely useless over there (already taken into account by <p:tabView var>), but it's actually helpful in here (it creates a new NamingContainer around the tab content).

Autres conseils

The above Community's answer hasn't worked for dynamic tabView

<p:tabView dynamic="true" ...

If i use dynamic="true" and c:foreach for tabs, when i add or remove a tab, do update @tabViewId, the tabview will reload "All content of existed tabs" => this is not the way to attribute "dynamic" work, it's not lazy.

My project has a problem with this, i had to customize the method encodeEnd of TabViewRenderer and do something else, but it's not simple.

I wondering whether there is a way to include XHTML templates at rendered time?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top