Primefaces tabview active index is not working correctly

Mudassir Shahzad picture Mudassir Shahzad · Apr 2, 2012 · Viewed 16.1k times · Source

I've changed my code completely. But active index is still showing problems. Sometimes it gets called and sometimes it doesn't. What's wrong with the following xhtml code?

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui" >
    <h:head>
        <title>Admin Panel</title>

        <style type="text/css">
            .ui-accordion .ui-accordion-content{
                background-color: #eedae3;
            }
            .ui-accordion .ui-accordion-header {
                height: 30px;
                background-color: #e74f54;
            } 
            .ui-tabs .ui-tabs-nav li{
                background-color: #6f97df;
                height: 35px;
            }
            .datatable{
                background-color: #eedae3;
            }
        </style>

    </h:head>
    <h:body>  
        <p:tabView id="tabView" activeIndex="#{profileInfoManagedBean.myCurrentTab}" >
            <p:ajax event="tabChange" listener="#{profileInfoManagedBean.tabIsChangedKana}" />


            <p:tab id="locationInfoTab" title="Location Info">

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

                    <p:panel header="New Country">  
                        <h:panelGrid columns="3" cellpadding="5" cellspacing="5">

                            <p:column>
                                <h:outputLabel for="country"  value="Country: "></h:outputLabel>
                            </p:column>
                            <p:column>
                                <p:inputText id="country" value="#{profileInfoManagedBean.country.country}" required="true" label="City">

                                    <f:validateLength minimum="5" maximum="20" />
                                    <p:ajax event="blur" update="msg1"></p:ajax>
                                </p:inputText>
                            </p:column>
                            <p:column>
                                <p:message id="msg1" for="country" display="icon"></p:message>
                            </p:column>

                        </h:panelGrid>
                        <p:commandButton type="submit" action="#{profileInfoManagedBean.addCountry}" value="Save" ajax="true" ></p:commandButton>
                    </p:panel>

                </h:form>
                <p:separator />

                <h:form id="countryDataTableForm">
                    <p:panel>
                        <p:growl id="messagesww" />
                        <p:confirmDialog id="confirmDialog" message="Are you sure you want to delete the selected row ?"
                                         header="Deleting Row" severity="alert" widgetVar="confirmation1">
                            <p:commandButton id="confirm" value="Yes Sure" update="messagesww" oncomplete="confirmation1.hide()"
                                             action="#{profileInfoManagedBean.deleteObject}" />
                            <p:commandButton id="decline" value="Not Yet" onclick="confirmation1.hide()" type="button" />
                        </p:confirmDialog>

                        <p:dataTable style="width: 700px;" var="coun" value="#{profileInfoManagedBean.countryList}" selection="#{profileInfoManagedBean.deletingObj}" rowKey="#{coun.countryId}"
                                     paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                     paginator="true" rows="5" rowsPerPageTemplate="10,15,20,25" editable="true">
                            <p:ajax event="rowEdit" update="@this"
                                    listener="#{profileInfoManagedBean.onEditRow}" />


                            <p:column headerText="Country">
                                <p:cellEditor>
                                    <f:facet name="output">
                                        <h:outputText value="#{coun.country}" />
                                    </f:facet>
                                    <f:facet name="input">
                                        <p:inputText value="#{coun.country}" style="width:100%" />
                                    </f:facet>
                                </p:cellEditor>
                            </p:column>

                            <p:column id="inactive" filterBy="#{coun.isActive}"   
                                      headerText="isActive" footerText="exact" 
                                      filterOptions="#{profileInfoManagedBean.isActiveDropDown}"
                                      filterMatchMode="exact">

                                <p:cellEditor>
                                    <f:facet name="output">
                                        <h:outputText value="#{coun.isActive}"></h:outputText>
                                    </f:facet>
                                    <f:facet name="input">
                                        <h:selectOneMenu value="#{coun.isActive}" >  
                                            <f:selectItem itemLabel="True" itemValue="true" />  
                                            <f:selectItem itemLabel="False" itemValue="false" /> 
                                        </h:selectOneMenu> 
                                    </f:facet>
                                </p:cellEditor>
                            </p:column>

                            <p:column headerText="Edit">
                                <p:rowEditor />
                            </p:column>

                            <p:column headerText="Delete">

                                <p:commandButton type="button" onclick="confirmation1.show()" 
                                                 id="delCountry" title="Delete Country" icon="ui-icon ui-icon-trash" />
                            </p:column>

                            <p:column selectionMode="single">
                                <f:facet name="header">
                                    <h:outputText value="select" />
                                </f:facet>
                            </p:column>


                        </p:dataTable>
                    </p:panel>

                </h:form>

            </p:tab>






            <p:tab id="basicInfoTab" title="Basic info">
                <p:accordionPanel id="aPanel1">
                    <p:tab id="tab2" title="basic   info">
                        <h:form id="dkk">
                            This is basic info tab.
                        </h:form>
                        <h:form id="ddkk">
                            This is basic info tab.
                        </h:form>
                    </p:tab>
                </p:accordionPanel>
            </p:tab>



        </p:tabView>
    </h:body>
</html>

I'm using primefaces 3.2, JSF 2.1, Tomcat 7, netbeans 7.1, Hibernate3


Update: @rags i was having some problem in activeindex. After the activeindex and everything started working, i started to compare my code to know what was going wrong. Now, when i changed the required="false" to required="true" in the input fields and other components, the activeindex won't work again.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui" >
    <h:head>
        <title>Admin Panel</title>

        <script type="text/javascript">
            function deleteObj(x){
                //alert("checking javascript - " + x);
            }
        </script>

        <style type="text/css">
            .ui-accordion .ui-accordion-content{
                background-color: #eedae3;
            }
            .ui-accordion .ui-accordion-header {
                height: 30px;
                background-color: #e74f54;
            } 
            .ui-tabs .ui-tabs-nav li{
                background-color: #6f97df;
                height: 35px;
            }
            .datatable{
                background-color: #eedae3;
            }
        </style>

    </h:head>
    <h:body>  
        <h:form id="mainForm">

            <p:growl id="growl" showDetail="true" />

            <p:confirmDialog id="confirmDialog" message="Are you sure you want to delete the selected row ?"
                             header="Deleting Row" severity="alert" widgetVar="confirmation1">


                <p:commandButton id="confirm" value="Yes Sure" update=":mainForm:growl mainForm:myTabViewID:aPanel:countryTable" oncomplete="confirmation1.hide()"
                                 action="#{profileInfoManagedBean.deleteObject}">
                    <!--                                        <f:ajax render=":mainForm" />-->
                </p:commandButton>
                <p:commandButton id="decline" value="Not Yet" onclick="confirmation1.hide()" type="button" />
            </p:confirmDialog>

            <p:tabView id="myTabViewID" activeIndex="#{profileInfoManagedBean.myCurrentTab}" >
                <p:ajax event="tabChange" listener="#{profileInfoManagedBean.tabIsChanged}" />


                <p:tab id="locationInfoTab" title="Location Info">

                    <p:accordionPanel id="aPanel" activeIndex="#{profileInfoManagedBean.myCurrentATab}"> 
                        <p:tab id="tab1" title="Country">

                            <p:outputPanel>  
                                <h:panelGrid columns="3" cellpadding="5" cellspacing="5">

                                    <p:column>
                                        <h:outputLabel for="country"  value="Country: "></h:outputLabel>
                                    </p:column>
                                    <p:column>
                                        <p:inputText id="country" value="#{profileInfoManagedBean.country.country}" required="false" label="Country">
                                            <p:watermark value="Enter a country name" for="country" />
                                            <f:validateLength for="country" minimum="5" maximum="20" />
                                            <p:ajax event="blur" update="msg1" />
                                            <f:validateRequired for="country" />
                                        </p:inputText>
                                    </p:column>
                                    <p:column>
                                        <p:message id="msg1" for="country" display="icon"></p:message>
                                    </p:column>

                                </h:panelGrid>
                                <p:commandButton value="Add" action="#{profileInfoManagedBean.addCountry}" update=":mainForm" style="margin:10px 0" id="btnAdd"/>
                            </p:outputPanel>

                            <p:separator />
                            <p:outputPanel id="countryTable">

                                <p:dataTable style="width: 700px;" var="coun" value="#{profileInfoManagedBean.countryList}" selection="#{profileInfoManagedBean.deletingObj}" rowKey="#{coun.countryId}"
                                             paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                             paginator="true" rows="5" rowsPerPageTemplate="10,15,20,25" editable="true">
                                    <p:ajax event="rowEdit" update="@this"
                                            listener="#{profileInfoManagedBean.onEditRow}" />

                                    <p:confirmDialog id="confirmDialog" message="Are you sure you want to delete the selected row ?"
                                                     header="Deleting Row" severity="alert" widgetVar="confirmation2">
                                        <p:commandButton id="confirm" value="Yes Sure" update=":mainForm" oncomplete="confirmation2.hide()"
                                                         action="#{profileInfoManagedBean.deleteObject}" />
                                        <p:commandButton id="decline" value="Not Yet" onclick="confirmation2.hide()" type="button" />
                                    </p:confirmDialog>


                                    <p:column headerText="Country">
                                        <p:cellEditor>
                                            <f:facet name="output">
                                                <h:outputText value="#{coun.country}" />
                                            </f:facet>
                                            <f:facet name="input">
                                                <p:inputText value="#{coun.country}" style="width:100%" />
                                            </f:facet>
                                        </p:cellEditor>
                                    </p:column>

                                    <p:column id="inactive" filterBy="#{coun.isActive}"   
                                              headerText="isActive" footerText="exact" 
                                              filterOptions="#{profileInfoManagedBean.isActiveDropDown}"
                                              filterMatchMode="exact">

                                        <p:cellEditor>
                                            <f:facet name="output">
                                                <h:outputText value="#{coun.isActive}"></h:outputText>
                                            </f:facet>
                                            <f:facet name="input">
                                                <h:selectOneMenu value="#{coun.isActive}" >  
                                                    <f:selectItem itemLabel="True" itemValue="true" />  
                                                    <f:selectItem itemLabel="False" itemValue="false" /> 
                                                </h:selectOneMenu> 
                                            </f:facet>
                                        </p:cellEditor>
                                    </p:column>

                                    <p:column headerText="Edit">
                                        <p:rowEditor />

                                    </p:column>

                                    <p:column headerText="Delete">
                                        <p:commandButton update=":mainForm:growl :mainForm:myTabViewID:aPanel:countryTable" icon="ui-icon-circle-close" action="#{profileInfoManagedBean.deleteCountry(coun.countryId)}" 
                                                         title="Delete Country" style="border-color:#FF0000" />
                                    </p:column>


                                </p:dataTable>
                            </p:outputPanel>

                        </p:tab>

                        <p:tab id="tab2" title="Province">

                            <p:outputPanel>  
                                <h:panelGrid columns="3" cellpadding="5" cellspacing="5">

                                    <p:column>
                                        <p:selectOneMenu value="#{profileInfoManagedBean.province.country.countryId}" id="cou"
                                                         required="false">
                                            <f:selectItem itemLabel="Select Here" itemValue="" />
                                            <f:selectItems
                                                value="#{profileInfoManagedBean.countryList}"
                                                var="coun" itemValue="#{coun.countryId}" itemLabel="#{coun.country}" />
                                            <p:ajax event="blur" update="msg2" />
                                        </p:selectOneMenu><p:message id="msg2" for="cou" display="icon" />
                                    </p:column>

                                    <p:column>
                                        <h:outputLabel for="province"  value="Province: "></h:outputLabel>
                                    </p:column>
                                    <p:column>
                                        <p:inputText id="province" value="#{profileInfoManagedBean.province.province}" required="false" label="Province">
                                            <p:watermark value="Enter a province name" for="province" />
                                            <f:validateLength minimum="5" maximum="20" />
                                            <p:ajax event="blur" update="msg3"></p:ajax>
                                        </p:inputText>
                                    </p:column>
                                    <p:column>
                                        <p:message id="msg3" for="province" display="icon"></p:message>
                                    </p:column>

                                </h:panelGrid>
                                <p:commandButton value="Add" action="#{profileInfoManagedBean.addProvince}" update=":mainForm" style="margin:10px 0" id="btnAddProvince"/>
                            </p:outputPanel>

                            <p:separator />
                            <p:outputPanel id="provinceTable">

                                <p:dataTable style="width: 700px;" var="prov" value="#{profileInfoManagedBean.provinceList}" selection="#{profileInfoManagedBean.deletingObj}" rowKey="#{prov.provinceId}"
                                             paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                             paginator="true" rows="5" rowsPerPageTemplate="10,15,20,25" editable="true">
                                    <p:ajax event="rowEdit" update="@this"
                                            listener="#{profileInfoManagedBean.onEditRow}" />


                                    <p:column headerText="Province">
                                        <p:cellEditor>
                                            <f:facet name="output">
                                                <h:outputText value="#{prov.province}" />
                                            </f:facet>
                                            <f:facet name="input">
                                                <p:inputText value="#{prov.province}" style="width:100%" />
                                            </f:facet>
                                        </p:cellEditor>
                                    </p:column>

                                    <p:column id="inactive" filterBy="#{coun.isActive}"   
                                              headerText="isActive" footerText="exact" 
                                              filterOptions="#{profileInfoManagedBean.isActiveDropDown}"
                                              filterMatchMode="exact">

                                        <p:cellEditor>
                                            <f:facet name="output">
                                                <h:outputText value="#{prov.isActive}"></h:outputText>
                                            </f:facet>
                                            <f:facet name="input">
                                                <h:selectOneMenu value="#{prov.isActive}" >  
                                                    <f:selectItem itemLabel="True" itemValue="true" />  
                                                    <f:selectItem itemLabel="False" itemValue="false" /> 
                                                </h:selectOneMenu> 
                                            </f:facet>
                                        </p:cellEditor>
                                    </p:column>

                                    <p:column headerText="Edit">
                                        <p:rowEditor />
                                        <p:commandButton icon="ui-icon-circle-close" onclick="deleteObj(5)" title="Delete Province" style="border-color:#FF0000" />
                                    </p:column>

                                    <p:column headerText="Delete">

                                        <p:commandButton type="button" onclick="confirmation1.show()" 
                                                         id="delProvince" title="Delete Province" icon="ui-icon ui-icon-trash" />
                                    </p:column>

                                    <p:column selectionMode="single">
                                        <f:facet name="header">
                                            <h:outputText value="select" />
                                        </f:facet>
                                    </p:column>


                                </p:dataTable>
                            </p:outputPanel>

                        </p:tab>

                    </p:accordionPanel>

                </p:tab>


                <p:tab id="basicInfoTab" title="Basic info">
                    <p:accordionPanel id="aPanel1">
                        <p:tab id="tab2" title="basic   info">
                            This is basic info tab.
                            This is basic info tab.
                        </p:tab>
                    </p:accordionPanel>
                </p:tab>



            </p:tabView>
        </h:form>
    </h:body>
</html>

I've many tabview and accordion tabs. activeindex worked when I made required="false" for every component of one tab. Changing all to required="true" caused activeindex not to work, but if you change to required="false" of components of only one tab activeindex works just fine.

Answer

wwhite picture wwhite · May 17, 2012

If <p:tabView is in a <h:form, _activeIndex is updated. If <p:tabView is NOT in a <h:form, _activeIndex is NOT updated. This can be seen in the POST using Firebug.

From what I can tell, _activeIndex and _activetab should have same value with TabView component.

I use the following code with multiple tabs, and different form in each tab:

public void tabIsChanged(TabChangeEvent event) {
  //This code was taken directly from TabViewRenderer.
  FacesContext context = FacesContext.getCurrentInstance();
  Map<String, String> params = context.getExternalContext().getRequestParameterMap();
  TabView tabView = (TabView) event.getComponent();
  String activeIndexValue = params.get(tabView.getClientId(context) + "_tabindex");

  //this.activeTab = Integer.parseInt(activeIndexValue);
  this.myCurrentATab = Integer.parseInt(activeIndexValue);

}

Maybe this a solution for you.