7
votes

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.

3

3 Answers

10
votes

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.

4
votes

i easy fix this with:

  public void onSPTabChange(TabChangeEvent event) 
  {   
  TabView tabView = (TabView) event.getComponent();
  currentData.setSP_Index(tabView.getChildren().indexOf(event.getTab())+1);
  }

in currentdata i have property SP_Index with number of tab (first,second....)

 <p:tabView id="tabView" styleClass="tabView">  
 <p:ajax event="tabChange" listener="#{dataAccess.onSPTabChange}" />
 ....

and add jquery script

<script>
  $("#tabView li:nth-child(#{currentData.SP_Index})").click();
</script>
0
votes

Try to keep your tabview in panelgrid like this way and update this h:panelgrid

h:panelGrid id="mainPanel">

<p:tabView id="tabview" activeIndex="#{ctrl.idx}" dynamic="true" cache="false">  
        <p:ajax event="tabChange" listener="#{ctrl.doStuff}" update=":form:mainPanel"/>
        <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:panelGrid>