TabView in PrimeFaces 5.0 doesn’t call tabChange event

jsfjsf-2onchangeprimefacestabview

I use PrimeFaces 5.0 and jsf 2.2. Here is my page that contains PrimeFaces tabview

            <h:panelGroup layout="block" style="position:absolute;top:60px;width:100%;">
            <p:tabView id="tabs" activeIndex="#{TabsManagerBean.activeIndex}" onTabShow="$('#tvlistr').click();" dynamic="true"
                value="#{TabsManagerBean.tabs}" var="tab">
                <p:ajax event="tabChange" listener="#{TabsManagerBean.onTabChange}" />
                <p:tab title="#{tab}" titleStyle="width:180px" />
            </p:tabView>
            <p:commandLink id="tvlistr" style="display:none;" action="#{TabsManagerBean.navigate}"/>
        </h:panelGroup>

My onTabChange method

public void onTabChange(TabChangeEvent evt) {
    logger.debug("Tab changed to: {}.", evt.getData());
    selectedTab = (String) evt.getData();
    ...
}

and the problem that this method isn't called. i need this method to be called before

<p:commandLink id="tvlistr" style="display:none;" action="#{TabsManagerBean.navigate}"/>

Updated: here is my h:form

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
<f:view locale="en">
    <h:head>
        <title>#{appMsg.common_pms}</title>
        <!--  main JavaScript file -->
        <h:outputScript name="js/main.js" />
    </h:head>

    <h:body>
        <h:form id="formId" prependId="false">

            <ui:include src="progressbar.xhtml" />

            <h:panelGroup id="header" layout="block" style="position:absolute;top:0;width:100%;height:90px;">
                <ui:include src="header.xhtml" />
            </h:panelGroup>

            <h:panelGroup layout="block" style="position:absolute;top:60px;width:100%;">
                <p:tabView id="tabs" activeIndex="#{TabsManagerBean.activeIndex}" onTabShow="$('#tvlistr').click();" dynamic="true"
                    value="#{TabsManagerBean.tabs}" var="tab">
                    <p:ajax event="tabChange" listener="#{TabsManagerBean.onTabChange}" />
                    <p:tab title="#{tab}" titleStyle="width:180px" />
                </p:tabView>
                <h:commandLink id="tvlistr" style="display:none;" action="#{TabsManagerBean.navigate}">
                    <f:ajax event="action" />
                </h:commandLink>
            </h:panelGroup>

            <h:panelGroup id="footer" layout="block" style="position:absolute;height:20px;width:100%;bottom:0;background-color: #005696">
                <ui:include src="/templates/version.xhtml" />
            </h:panelGroup>

        </h:form>
    </h:body>
</f:view>

Best Answer

I had a similar problem with Primefaces 5.1

As long as i put the tabview into a form everything worked fine. But because i wanted to use seperate forms in my tabs i had to remove the surrounding form of the tabview to avoid nested forms. Without the surrounding form the ajax event didnĀ“t get triggered any more when changing the tab.

My solution was to use a remotecommand in a form parallel to the tabview.
The remotecommand is triggered by the onTabChange attribute of the tabview element. At that call i forwarded the index parameter to the global request parameters.

<p:tabView id="rootTabMenu" styleClass="tabcontainer" prependId="false" 
        activeIndex="#{sessionData.activeTabIndex}" widgetVar="rootTabMenu"
        onTabChange="tabChangeHelper([{name: 'activeIndex', value: index}])">
    // Tabs...  
</p:tabView>

<h:form id="tabChangeHelperForm">
    <p:remoteCommand name="tabChangeHelper" actionListener="#{sessionData.onTabChange()}" />
</h:form>    

In the backing bean i catched the value again from the request parameter map and set the active index.

public void onTabChange()
{   
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
    String paramIndex = paramMap.get("activeIndex");
    setActiveTabIndex(Integer.valueOf(paramIndex));
    System.out.println("Active index changed to " + activeTabIndex);
}    

Hope that can help you

Related Topic