10
votes

Active Index is not getting updated automatically. ReaD in a few posts that by placing the tabView on a form it works. Or by including <p:ajax event="tabChange"/> in the tabview it works. But nothing seems to work

xhtml

Sample 1 : automatic updates

    <p:tabView id="categoryTabView" var="promoArticle" value="#{promotionDetailBean.artDTOs}"  activeIndex="#{promotionDetailBean.activeTabIndex}">
            <p:tab id="categoriesTab" title="#{promoArticle.categoryName}">
                <p:dataTable id="promotionDetail_dataTable" var="articlePromo" value="#{promoArticle.artVO}" selection="#{promotionDetailBean.selectedArt}" rowIndexVar="rowIndex">
                    <p:column id="select" selectionMode="multiple" />

                    <p:column id="barCode">
                        <h:inputText id="barCodeInputTxt" value="#{articlePromo.barCode}"
                        styleClass="inputTextStyle" onchange="onSuggestedValueChange('categoryTabView',#{promotionDetailBean.activeTabIndex}, 'promotionDetail_dataTable',#{rowIndex},'originalCostInputTxt')" />
                    </p:column>
                </p:dataTable>
            </p:tab>
        </p:tabView>

Sample 2: Updating on tabChange event

  <h:form id="form">
    <p:growl id="growlm" showDetail="true" />  

            <p:tabView id="categoryTabView" var="promoArticle" value="#{promotionDetailBean.artDTOs}"  >
               <p:ajax event="tabChange" listener="#{promotionDetailBean.tabChanged}"  update=":growlm" />
                    <p:tab id="categoriesTab" title="#{promoArticle.categoryName}">
                        <p:dataTable id="promotionDetail_dataTable" var="articlePromo" value="#{promoArticle.artVO}" selection="#{promotionDetailBean.selectedArt}" rowIndexVar="rowIndex">
                            <p:column id="select" selectionMode="multiple" />

                            <p:column id="barCode">
                                <h:inputText id="barCodeInputTxt" value="#{articlePromo.barCode}"
                                styleClass="inputTextStyle" onchange="onSuggestedValueChange('categoryTabView',#{promotionDetailBean.activeTabIndex}, 'promotionDetail_dataTable',#{rowIndex},'originalCostInputTxt')" />
                            </p:column>
                        </p:dataTable>
                    </p:tab>
                </p:tabView>

I need to identify the cell on "onChange " event. But the activeIndex is always 0, the initialized value. The event doesn't get call.

bean

private Integer activeTabIndex = 0;
public Integer getActiveTabIndex() {
   return activeTabIndex;
}
public void setActiveTabIndex(Integer activeTabIndex) {
    this.activeTabIndex = activeTabIndex;
}

bean

public void tabChanged(TabChangeEvent event){
        TabView tv = (TabView) event.getComponent(); 
        this.activeTabIndex = tv.getActiveIndex();
    }

But the event is not getting trigerred. Nor getting updated automatically.

What could be the probable issues ?

Thanks, Shikha

8

8 Answers

13
votes

This works for me when the tab is not contained inside a form but every tab contains its own one:

  1. Add a listener to tab change event to your tabView component:

    <p:ajax event="tabChange" listener="#{userBean.onTabChange}" />
  2. Getting the active index from the underlying TabView component doesn't seem to be working. However, in the event, the new selected tab is updated correctly so we can getthe index by searching in the children components of the TabView:

    public void onTabChange(TabChangeEvent event) 
    {   
        TabView tabView = (TabView) event.getComponent();
        activeTab = tabView.getChildren().indexOf(event.getTab());
    }

I hope this works for you too

6
votes

The following worked for me:

XHTML:

<p:tabView id="categoryTabView" var="promoArticle"
        value="#{promotionDetailManagedBean.articuloPromocionDTOs}" dynamic="true">
    <p:ajax event="tabChange" listener="#{promotionDetailManagedBean.onTabChange}" />
    <p:tab> ... </p:tab>
</p:tabView>

Bean:

public final void onTabChange(final TabChangeEvent event) {
    TabView tv = (TabView) event.getComponent();
    this.activeTabIndex = tv.getActiveIndex();
}
3
votes

For primefaces >= 5.0 please use the following code :

public final void onTabChange(TabChangeEvent event) {
    TabView tv = (TabView) event.getComponent();     
    this.ActiveIndex = tv.getChildren().indexOf(event.getTab());
}
2
votes

That only seems to work if active index is not binded to the managed bean. But this is useless for me since I want to keep a backing bean-view synchronization. I'm astonished Primefaces team has not resolved it yet (I'm working with 3.5 version). However it works if the p:tabView itself is wrapped into a h:form instead of having one of them for each tab, but this makes you change your submit context.

0
votes
<p:column id="barCode">
     <h:inputText id="barCodeInputTxt" value="#{articlePromo.barCode}"
            styleClass="inputTextStyle"   onchange="onSuggestedValueChange('categoryTabView',
   #{promotionDetailBean.activeTabIndex}, 
    'promotionDetail_dataTable',#{rowIndex},
    'originalCostInputTxt')" />    **_____/>_____**
</p:column>
  1. you have an extra />
  2. immediate true may cause problem with p:ajax, you should use immediate true when you dont have validation or you are trying cancel operation.

    public void tabChange(TabChangeEvent event){
         TabView tabView = (TabView) event.getComponent();
         Tab tab = (Tab) event.getTab();
         String tabChangedMessage = tab.getTitle() + " changed. index=" + tabView.getActiveIndex();
         System.out.println(tabChangedMessage);
         FacesContext fc = FacesContext.getCurrentInstance();
         fc.addMessage(null, new FacesMessage("Tab changed", tabChangedMessage));
    }
    
    <p:tabView>
       <p:ajax event="tabChange" listener="#{tabChangeBean.tabChange}" update=":growlId" />
       <p:tab title="tab 1">
       tab1 inside
       </p:tab>
       <p:tab title="tab 2">
       tab1 inside
       </p:tab>
    </p:tabView>
    

This works but active index is 0.

0
votes

in your xhtml you are calling listener="#{promotionDetailBean.onTabChange}" but in your bean the method name is "public void tabChanged". So it cannot trigger.

I have tried an example on prime-showcase at:

in bean (TabBean):

private Integer activeTabIndex = 1;

// setter/getter

public void onTabChange(TabChangeEvent event) {
    FacesMessage msg = new FacesMessage("Tab Changed", "Active Tab: " + event.getTab().getTitle());

    TabView tabView = (TabView) event.getComponent(); 
    int activeTabIndex = tabView.getActiveIndex();
    System.out.println("--------" + activeTabIndex);


    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> params = context.getExternalContext().getRequestParameterMap();
    String activeIndexValue = params.get(tabView.getClientId(context) + "_activeIndex");
    System.out.println("--------" + activeIndexValue);

    context.addMessage(null, msg);
}

in xhtml (tabviewChangeListener.xhtml):

<p:tabView id="tabView" dynamic="true" activeIndex="#{tabBean.activeTabIndex}">

                <p:ajax event="tabChange" listener="#{tabBean.onTabChange}" update=":form:growl"/>

                <p:tab title="Godfather Part I" id="Godfather1">

The result is as expected: At beginning the second tab is displayed. I click first tab and then third. sysout is:

--------0

--------0

--------2

--------2

0
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>
-1
votes
public final void onTabChange(final TabChangeEvent event) {
    TabView tv = (TabView) event.getComponent();
    this.activeTabIndex = tv.getIndex();
}

This worked for me...