Ajax – Primefaces tabview: set the active index on tab change

ajaxjsf-2primefaces

I've got a tab view that contains two tab.

When I switch from tab 1 to tab 2, I'm calling some code that executes a validation and updates some values. Depending on the result of this validation, I would like to stay on tab 1, or go to tab 2, and refresh the tabs' content.

My tabview:

<h:form id="form"> 
    <p:tabView id="tabview" activeIndex="#{ctrl.idx}" dynamic="true" cache="false">  
        <p:ajax event="tabChange" listener="#{ctrl.doStuff}" update=":form:tabview"/>
        <p:tab title="Tab 1" id="t1">  
            <h:panelGrid columns="1" cellpadding="10">
                <h:outputText value="#{ctrl.s1}"/>
            </h:panelGrid>  
        </p:tab>  
        <p:tab title="Tab 2" id="t2">  
            <h:panelGrid columns="1" cellpadding="10">
                <h:outputText value="#{ctrl.s2}"/>
            </h:panelGrid>  
        </p:tab>
    </p:tabView>  
</h:form>

My test code that simly changes the values:

public void doStuff() {
    s1 = String.valueOf(Math.random());
    s2 = String.valueOf(Math.random());
}

I thought that changing the active tab index in my method would be enough, like that:

public void doStuff() {
    // ...
    idx = 0;
}

On tabChange event, the method is called but the tabview components goes to the clicked tab, ignoring the idx new value.

I thought adding an update attribute to p:ajax would render the whole tabview but only the tabs and/or the tabs' content is re rendered.

And weirdest of all, if I change update=":form:tabview" to update=":form" or update="@form", I only receive the tab's content in the ajax response -> the component disappears from the page!

My bean is viewscoped, I'm using Primefaces 3.5, JSF 2.1 and Tomcat 7.

Any idea? Thanks.

Best Answer

Try to bind your TabView to server side component instance in your backing bean.

1.Add TabView component instance to your backing bean

org.primefaces.component.tabview.TabView tabview=null;

and coresponding getter and setter

public TabView getTabview() {
    return tabview;
}

public void setTabview(TabView tabview) {
    this.tabview = tabview;
}

2.Bind server side instance to your TabView

<p:tabView id="tabview" binding=#{yourBean.tabview} dynamic="true" cache="false">
...
</p:tabView>

3.Modify your doStuff() method

public void doStuff() {
    // ...
    //idx = 0;
    tabview.setActiveIndex(0);
}

And it will hopefully do the trick.

Related Topic