How to change active tab after button click - primefaces

I used PrimeFaces component tabView and i have code like below.
<p:tabView id="tabs" dynamic="true" cache="false">
<p:tab id="tab1">
<ui:include src="/some/path/page.xhtml"/>
</p:tab>
<p:tab id="tab2">
<ui:include src="/some/path/page2.xhtml"/>
</p:tab>
<p:tab id="tab3">
<ui:include src="/some/path/page3.xhtml" />
</p:tab>
</p:tabView>
On page3 i have ajax commandButton which looks like below.
<p:commandButton actionListener="#{bean.method(parameter)}" ajax="true" value="Add" />
I need switch to tab1 when method in bean finished. Thank you for help.

You have to add:
activeIndex
attribute to your tabView:
<p:tabView id="tabs" dynamic="true" cache="false" activeIndex="1" >

Related

Primefaces: Update not working for two components in different tabs

I have two selectBooleanCheckbox in differet tabs that are linked to the same variable in the backend bean, like this:
.xhtml:
<p:tabView id="tabsView" widgetVar="tabPanelWidget" dynamic="true" cache="true">
....
<p:tab id="tab1">
<p:outputPanel id="panel1">
<p:fieldset toggleable="false">
<p:panelGrid id="panelGrid1">
<p:row>
<p:column>
<p:outputLabel for="toggle1"/>
<p:selectBooleanCheckbox id="toggle1" value="#{backingBean.toogleBool}">
<p:ajax update="#(.toggle2)"/>
</p:selectBooleanCheckbox>
<p:column>
</p:row>
</p:panelGrid>
</p:fieldset>
</p:outputPanel>
</p:tab>
....
<p:tab id="tab2">
<p:outputPanel id="panel2">
<p:fieldset toggleable="false">
<p:panelGrid id="panelGrid2">
<p:row>
<p:column>
<p:outputLabel for="toggle2"/>
<p:selectBooleanCheckbox id="toggle2" value="#{backingBean.toogleBool}">
<p:ajax update="#(.toggle1)"/>
</p:selectBooleanCheckbox>
<p:column>
</p:row>
</p:panelGrid>
</p:fieldset>
</p:outputPanel>
</p:tab>
</p:tabView>
backingBean.java :
....
#Getter #Setter private boolean toggleMailAnhangExtrahieren = true;
....
Obviously this isn't my whole code as that would be too much to post here but I hope I included everything relevant. As you can see I try to use ajax to update the other selectBooleanCheckbox when one of them is clicked. As they are bound to the same variable, I would expect both selectBooleanCheckboxes to have the same status (both checked or both unchecked), but the other checkbox does not update. What am I doing wrong?
You need to fix the update part in the p:ajax tags:
#(.<class>) is a class-selector (Primefaces is using the jQuery Selector API, see https://api.jquery.com/category/selectors/), but you want to reference an id. So just use the id itself in the p:ajax tag, e.g.
<p:ajax update="toggle2"/>
Try using the tab id like this:
<p:ajax update="#form:tabsView:toggle2"/>

Primefaces Datatable inside Tab when tabChange ajax method nullPointerexception

i have a 1 datatable inside a tab and another tab with a other datatable in tabview element, but when the method onTabChange is execute the TabEvent.getTab is null wtf?!!! I have the next Code
<h:form id="frmTab">
<p:tabView id="tabs" dynamic="true" cache="false">
<p:ajax event="tabChange" listener="#{controller.onTabChange}" update="one-content,two-content"/>
<p:tab title="First Tab" id="first-tab">
<h:panelGroup display="block" id="one-content">
<p:dataTable value="${controller.detailTable1}"
</p:datatable>
</h:panelGroup>
</p:datatable>
<p:tab title="Second Tab" id="two-tab">
<h:panelGroup display="block" id="one-content">
<p:dataTable value="${controller.detailTable2}"
</p:datatable>
</h:panelGroup>
</p:tab>
</p:tabView>
When the onTabChange method is fired,
java.lang.NullPointerException
at org.primefaces.component.tabview.TabViewRenderer.encodeEnd(TabViewRenderer.java:59)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:881)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786)

primefaces tabView different tab content with dynamic tabs

I have a problem with tabView. The 1st tab should always display the same content (called search template which is identified with #{not curSearch.isClosable()}. All other tabs are search instances (identified with #{curSearch.isClosable()}
Here is the code:
<p:tabView id="searchTabViewId" var="curSearch" value="#{searchBL.searchInstances}"
activeIndex="#{searchBL.activeTabIndex}" styleClass="searchTabView">
<!-- search template tab -->
<ui:include src="/icarchive/sections/search/firstSearchTab.xhtml">
<ui:param name="curSearch" value="#{curSearch}" />
</ui:include>
<!-- search instances tabs -->
<ui:include src="/icarchive/sections/search/searchInstanceTab.xhtml">
<ui:param name="curSearch" value="#{curSearch}" />
</ui:include>
</p:tabView>
Unfortunately there are methods on the 1st tabs curSearch object called which are used on 2nd and following tabs only. If I do not use the ui:insert it does not change anything.
Anybody knows where is my fault?
Regards
Oliver
This works:
<p:tabView id="searchTabViewId" styleClass="searchTabView" activeIndex="#{searchBL.activeTabIndex}">
<!-- do the iteration over the search instances NOT in the tabView because this will not work with ui:include -->
<c:forEach items="#{searchBL.searchInstances}" var="curSearch">
<p:tab closable="#{curSearch.isCloseable()}">
<f:facet name="title">
<p:graphicImage library="images" name="search_tab.png" height="16" styleClass="tabImage"
rendered="#{not curSearch.isCloseable()}" />
<h:outputText value="#{curSearch.title}" />
</f:facet>
<!-- do not use 2 ui:includes here, the dynamic must be in the src attribute to get it work -->
<ui:include
src="#{curSearch.closeable ? '/sections/search/searchInstanceTab.xhtml' : '/sections/search/firstSearchTab.xhtml'}">
<ui:param name="curSearch" value="#{curSearch}" />
</ui:include>
</p:tab>
</c:forEach>
I had the same problem, only solution i found is wrap include in other component and clamp with render which one is displayed. For initial load if you have ids depending on content you will need to set id prefix so that it does not allow empty id fields:
<p:tabView id="tabsView" dynamic="true" cache="true"
value="#{TabViewController.tabView.openedTabs}" var="tabDefinition" activeIndex="#{TabViewController.tabView.activeIndex}">
<p:ajax event="tabClose" listener="#{TabViewController.onCloseTab}" update="tabsView"/>
<p:ajax event="tabChange" update="tabsView"/>
<p:tab id="tab#{tabDefinition.id}" title="#{tabDefinition.title}" closable="true" action="">
<f:facet name="title">
<h:outputText value="#{tabDefinition.title}"/>
</f:facet>
<p:outputPanel style="display:block" rendered="#{'dataTable'.equals(tabDefinition.type)}">
<ui:include src="dataTable.xhtml">
<ui:param name="dataTableName" value="#{tabDefinition.contentName}"/>
</ui:include>
</p:outputPanel>
<p:outputPanel style="display:block" rendered="#{'form'.equals(tabDefinition.type)}">
<ui:include src="form.xhtml">
<ui:param name="formId" value="#{tabDefinition.id}"/>
<ui:param name="formName" value="#{tabDefinition.contentName}"/>
</ui:include>
</p:outputPanel>
</p:tab>
</p:tabView>

Primefaces dialog not shown at "oncomplete" after update on MenuItem

I have this piece of code:
<h:body>
<h:form id="form1">
<p:menuButton value="#{msgs.settingsMenuButton}">
<p:menuitem value="#{msgs.accountsMenuItem}" url="#" update=":dlgEdit" oncomplete="_dlgEdit.show()"/>
</p:menuButton>
<p:commandButton value="Accounts" icon="ui-icon-gear"
update=":dlgEdit"
oncomplete="_dlgEdit.show()"/>
</h:form>
<p:dialog id="dlgEdit" widgetVar="_dlgEdit" modal="true" closable="true" header="Accounts">
<h:form id="frmEdit" >
<p:panelGrid id="pnlEdit" columns="2">
<p:outputLabel id="lblName" for="eName" value="Name"/>
<p:inputText id="eName" value="#{tasksBean.selectedLocation}"/>
</p:panelGrid>
</h:form>
</p:dialog>
</h:body>
The dialog is not displayed when the menuItem is selected but it works when the commandButton is pressed.
The behaviors for both are the same...
Can you support me please?
Thanks,
Andrei
Try:
oncomplete="PF('_dlgEdit').show();"

Render same panel at multiple occasions

I am working with PrimeFaces and I want to know it rendering a panel multiple time within a same page is possible. For example, I have a panel like below:
<p:panel id="studentInfo">
<p:commandButton id="viewFullProfile" ....
<h:outputText value="Search" />
<p:inputText id="search" ....
</p:panel>
I want this panel to in each tab of a p:tabView control.
<p:tabView id="studentProfile">
<p:tab id="tabA">
..render "studentInfo" here...
</p:tab>
<p:tab id="tabB">
..render "studentInfo" here...
</p:tab>
<p:tab id="tabC">
..render "studentInfo" here...
</p:tab>
</p:tabView>
You will need one simple view like this :
studentInfo.xhtml
<ui:composition>
<p:panel>
#{item}
</p:panel>
</ui:composition>
Note : I'm currently passing #{item} as a parameter that could be a student entity for example.
Your view :
<p:tabView id="studentProfile">
<p:tab id="tabA">
<ui:composition template="studentInfo.xhtml">
<ui:param name="item" value="Student A" />
</ui:composition>
</p:tab>
<p:tab id="tabB">
<ui:composition template="studentInfo.xhtml">
<ui:param name="item" value="Student A" />
</ui:composition>
</p:tab>
<p:tab id="tabC">
<ui:composition template="studentInfo.xhtml">
<ui:param name="item" value="Student A" />
</ui:composition>
</p:tab>
</p:tabView>