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"/>
Related
I have a big problem with Primefaces accordion.
I have an outputPanel with an header and an accordion with 2 tabs.
If I close the first tab and change a field in the second tab, it open the first tab and close the second. How can I keep the status of the tabs?
This is a simple example:
<p:outputPanel id="content">
<p:outputPanel id="header" />
<p:accordionPanel multiple="true">
<p:tab title="firstTab">
<p:panel>
<p:inputText id="firstInput" value="firstInput">
<p:ajax event="change" update="content" />
</p:inputText>
</p:panel>
</p:tab>
<p:tab title="secondTab">
<p:panel>
<p:inputText id="secondInput" value="secondInput">
<p:ajax event="change" update="content" />
</p:inputText>
</p:panel>
</p:tab>
</p:accordionPanel>
</p:outputPanel>
How can i resolve it? Any suggestion?
AccordionPanel has an attribute called activeIndex, you could set this attribute from your MB so it doesn´t change after an update. See for instance https://www.primefaces.org/docs/vdl/6.1/core/primefaces-p/accordionPanel.html
Based on cagatay civici's answer provided in the link by #Christian I created a simple example, because it was not working out of the box for me.
The example.xthml:
<h:form styleClass="accordionForm">
<p:accordionPanel multiple="true"
activeIndex="#{sessionBean.activeTabs}">
<p:ajax event="tabChange" />
<p:ajax event="tabClose" />
<p:tab title="Tab1">
<p:panel>
<p:inputText id="firstInput" value="firstInput">
<p:ajax event="change" update="#(.accordionForm)" />
</p:inputText>
</p:panel>
</p:tab>
<p:tab title="Tab2">
<p:panel>
<p:inputText id="secondInput" value="secondInput">
<p:ajax event="change" update="#(.accordionForm)" />
</p:inputText>
</p:panel>
</p:tab>
</p:accordionPanel>
</h:form>
The sessionBean.java:
#Named("sessionBean")
#SessionScoped
public class SessionBean implements Serializable {
private static final long serialVersionUID = 1L;
private String activeTabs = "";
public String getActiveTabs() {
return activeTabs;
}
public void setActiveTabs(String activeTabs) {
this.activeTabs = activeTabs;
}
}
Explanation:
The two p:ajax tags trigger a POST request if a tab is either opened ("tabChange") or closed ("tabClosed"), since this is the default action for the accordionPanel. Hence, I wrapped the p:accordionPanel with an h:form. If you inspect your network traffic you can see how the list of active tabs is sent to the server.
Bear in mind that I update the surrounding form instead of the accordionPanel itself. Therefore, I use Primefaces Selectors.
I have a datatable, and at the last column I will have an edit action, it will trigger the dialog box. However, I found the value in the dialog box is not updated. Can anybody to help on this?
My code as below. In fact the bean.currentItem.name and bean.currentItem.age should base on my selection from the table. I check the bean.currentItem is not null and is refer to my selection from preEdit method, but the value never show up in p:dialog.
<p:dataTable ....>
<p:column...
<p:column...
<p:column>
<f:facet name="header">
<h:outputLabel value="Update" />
</f:facet>
<p:remoteCommand name="preEdit" action="#{bean.preEdit}"
process="#this" update="#this #form:dlg">
<f:setPropertyActionListener target="#{bean.currentItem}"
value="#{thisItem}" />
</p:remoteCommand>
<p:commandLink styleClass="no-decor"
oncomplete="preEdit();PF('dlg').show();" value="Edit"/>
</p:column>
</p:dataTable>
<p:dialog header="#{lbl.tt_cat_upd}" widgetVar="dlg" id="dlg"
resizable="false" >
<h:outputLabel value="#{bean.currentItem.name}" />
<h:outputLabel value="#{bean.currentItem.age}" />
</p:dialog>
How about removing your p:remoteCommand and let your p:commandLink do all the work for you?
Assuming you have a h:form surrounding both your dataTable and your dialog
<p:commandLink action="#{bean.preEdit}" process="#this" update="dlg" styleClass="no-decor" oncomplete="PF('dlg').show()" value="Edit">
<f:setPropertyActionListener target="#{bean.currentItem}"
value="#{thisItem}" />
</p:commandLink>
If your dataTable is not in the same form with your dialog, you might replace update="dlg" by update=":formIdContainingDialog:dlg"
Commandbutton with id("myButtonId2") works fine. I mean it updates "myOutputPanel"
but commandbutton(myButtonId) which is inside datatable doesn't update outputPanel. I found the suggestions and tried with the following,
update=":myForm:myOutputPanel"
update="#myForm"
update=":myOutputPanel"
But none of them worked...
Here is the snippet...
<h:form id="myForm" prependId="false">
<p:panel id="myPanel">
<p:dataTable id="myDatatable">
<p:column style="width:4%">
<p:commandButton id="myButtonId" actionListener="#{bean.showPanel}" update="myOutputPanel"/>
</p:column>
</p:dataTable>
<p:commandButton id="myButtonId2" update="myOutputPanel"/>
</p:panel>
<p:outputPanel id="myOutputPanel" rendered="#{bean.show}">
//some stuff
</p:outputPanel>
Try to put your <p:outputPanel /> inside a <p:panel />
and add a "widgetVar" attribute
For example : <p:panel widgetVar="var" [..]>
and just update the panel directly with update="#widgetVar(var)"
I have a p:dataTable and contains commandLinks.
<h:form id="defVhclForm">
<p:dataTable id="vehicleTable" var="vhcl" value="#{vehicle.vehicleList}"
scrollable="true" scrollHeight="520">
<p:column id="trackId" label="#{general.vehicleName}" width="120" style="spacing:0;padding-left:10px;border:0px">
<p:commandLink id="editLink" immediate="true" value="#{vhcl.vehicle.vehicleName}" title="#{general.editVehicleInfo}"
action="#{vehicle.vehicleSelected}" style="font-weight:bold; font-size:11px;"
update="#form"/>
<br />
<h:outputText id="vehicleId" value="#{vhcl.vehicle.mtsTrackId}" title="#{general.vehicleId}" style="font-size:10px; color:blue;" />
<br/>
<h:outputText value="#{vhcl.vehicle.vehiclePlate}" id="vehiclePlate" title="#{general.licencePlate}" style="font-size:10px; color:blue"/>
<h:inputHidden value="#{vhcl.vehicle.mtsTrackId}" id="mtsTrackId"/>
</p:column>
</p:dataTable>
<p:tabView id="tabView" styleClass="tableCellHeader" style="align:left">
<p:tab id="vehicleDefinitionTab" title="#{general.vehicle}" styleClass="tableCellHeader">
<h:panelGrid id="mainGrid" columns="2" columnClasses="alignTop, alignTop">
<h:panelGrid id="subGrid" columns="4">
<h:outputLabel id="vhclIdLbl" value="#{general.vehicleId}:"/>
<p:inputText id="vehicleIdTxt" binding="#{vehicle.vehicleIdTxt}" style="width:150px;"/>
<h:outputLabel id="vhclPlateLbl" value="#{general.licencePlate}:"/>
<p:inputText id="vehiclePlateTxt" binding="#{vehicle.vehiclePlateTxt}" style="width:150px;"/>
<h:outputLabel id="vhclNameLbl" value="#{general.vehicleName}:"/>
<p:inputText id="vehicleNameTxt" binding="#{vehicle.vehicleNameTxt}" style="width:150px;"/>
<h:outputLabel id="vhclTypeNameLbl" value="#{general.vehichleType}:"/>
<p:selectOneMenu id="vhclTypeCmb" binding="#{vehicle.vehicleTypeCmb}" styleClass="tableCell" effect="slide" style="width:157px">
<f:selectItem itemLabel="#{general.pleaseSelect}" itemValue="" styleClass="tableCell"/>
<f:selectItems value="#{vehicle.vehicleTypeCmbList}" styleClass="tableCell"/>
</p:selectOneMenu>
</h:panelGrid>
<!-- <p:graphicImage value="#" width="120px" height="80px"/>-->
</h:panelGrid>
</p:tab>
<p:tab id="registrationTab" title="#{general.auth}" styleClass="tableCellHeader">
</p:tab>
</:tabView>
</h:form>
By pressing the commandLink some p:tab should be updated and filled with the related data. Every component is inside the same h:form. Pressing the commandLink does not update the related p:tab s. Also, the commandLink action calls the bean method just for one time. More than one pressing does not call the bean method.
How can I solve this problem?
Im trying to update text field from dialog box .The text field is in the parent component. But its not happening . If i give the id of text field in the update of command button . I encountered the error :
javax.faces.FacesException: Cannot find component with identifier "customerCode" referenced from "tabView:lkpSltRec"
Since it is not able to find the component id . I have used the alternative . I have taken the hidden field .After command button is clicked , the hidden field gets updated and through simple javascript function im updating the text field of parent component .The javascript function is called from oncomplete of command button in the dialog box. Since ,as per project requirement i have to achieve it through primefaces only not through javascript . Plz, suggest me the approach in primefaces . Below is the code snippet:
Here ecap:lookup is the the customize component.
Selected Customer <p:inputText id="customerCode"
value="#{sixthTabBBean.customerName}" label="Selected Adddress"></p:inputText>
Selected Customer City <p:inputText id="selectedCity" value="#{sixthTabBBean.customerCity}" ></p:inputText>
<ecap:lookup lookupId="LOV0072" inputId="customerCode" clickStatus="city"
defaultDDValueIndex="0" title="CustomerCode"></ecap:lookup>
New LOV <ecap:lookup lookupId="LOV0092" inputId="customerCode" clickStatus="none"
defaultDDValueIndex="0" title="CustomerCode"></ecap:lookup>
City<p:inputText id="custCity" value="#{sixthTabBBean.customerCity}"
disabled="true" label="City"></p:inputText>
Selected Customer <p:inputText id="customerCode1"
value="#{sixthTabBBean.customerName}" label="Selected Adddress" ></p:inputText>
Selected Customer City <p:inputText id="selectedCity1" value="#{sixthTabBBean.customerCity}" ></p:inputText>
Selected Customer State <p:inputText id="selectedSate1" value="#{sixthTabBBean.customerState}" ></p:inputText>
<ecap:lookup lookupId="LOV0098" inputId="customerCode" clickStatus="state"
defaultDDValueIndex="0" title="CustomerCode"></ecap:lookup>
<p:dialog id="lkpDialog" widgetVar="lpDialogVar" header="Lookup"
modal="true" width="1000" height="600"
rendered="#{lookupSearch.popupRender}" >
<h:form rendered="#{lookupSearch.popupRender}" prependId="false">
<h:panelGrid cellpadding="10" id="diaFrmId">
<p:dataTable id="newfdt" var="flxSearch"
value="#{lookupSearch.lkpSearchCriteriaList}">
<p:column id="newwhc">
<f:facet name="header">
<h:outputLabel value="Search Fields"></h:outputLabel>
</f:facet>
<p:selectOneMenu styleClass="fdd180" id="newwdd"
value="#{flxSearch.searchCriterion.whereClause}">
<f:selectItems value="#{flxSearch.whrClausDropdown}" />
</p:selectOneMenu>
</p:column>
<p:column id="newcoc">
<f:facet name="header">
<h:outputLabel value="Conditions"></h:outputLabel>
</f:facet>
<p:selectOneMenu id="newco" styleClass="fdd95"
value="#{flxSearch.searchCriterion.operator}">
<f:selectItems id="newcriOperatorItms"
value="#{flxSearch.operatorDropdown}" />
</p:selectOneMenu>
</p:column>
<p:column id="newcic">
<f:facet name="header">
<h:outputLabel value="Value"></h:outputLabel>
</f:facet>
<p:inputText id="newcriInpNm"
rendered="#{!flxSearch.inputDate and !flxSearch.boolValue and !flxSearch.required}"
styleClass="285 ftb" deferChangeEvent="true"
value="#{flxSearch.searchCriterion.value}"
maxlength="#{flxSearch.maxLength}"
disabled="#{flxSearch.disableInput}" partialSubmit="true"
labelValue="#{flxSearch.searchCriterion.label}"
required="#{flxSearch.required}">
</p:inputText>
<p:inputText id="newcriInpM"
rendered="#{!flxSearch.inputDate and !flxSearch.boolValue and flxSearch.required }"
value="#{flxSearch.searchCriterion.value}"
maxlength="#{flxSearch.maxLength}"
disabled="#{flxSearch.disableInput}"
labelValue="#{flxSearch.searchCriterion.label}"
required="#{flxSearch.required}">
</p:inputText>
<p:selectOneMenu styleClass="fdd" id="newbldd"
value="#{flxSearch.searchCriterion.value}"
disabled="#{flxSearch.disableInput}"
rendered="#{flxSearch.boolValue }">
<f:selectItems value="#{flxSearch.booleanDropdown}" />
</p:selectOneMenu>
<p:calendar id="newcriDtNm" size="9"
rendered="#{flxSearch.inputDate and !flxSearch.boolValue and !flxSearch.required }"
disabled="#{flxSearch.disableInput}" showOn="button"
value="#{flxSearch.searchCriterion.value}"
labelValue="#{flxSearch.searchCriterion.label}">
</p:calendar>
<p:calendar id="newcriDtM" size="9"
rendered="#{flxSearch.inputDate and !flxSearch.boolValue and flxSearch.required }"
disabled="#{flxSearch.disableInput}"
value="#{flxSearch.searchCriterion.value}"
enableChangeDetector="false" partialSubmit="true"
labelValue="#{flxSearch.searchCriterion.label}"
required="#{flxSearch.required}" showOn="button">
</p:calendar>
</p:column>
</p:dataTable>
<!-- hidden text used to update values in the parent component -->
<p:inputText type="hidden" id="hiddencustomerCode"
value="#{sixthTabBBean.customerName}" ></p:inputText>
<p:inputText type="hidden" id="hiddencustCity"
value="#{sixthTabBBean.customerCity}" ></p:inputText>
<p:inputText type="hidden" id="hiddencustState"
value="#{sixthTabBBean.customerState}" ></p:inputText>
<p:fieldset legend="Combined By">
<h:panelGrid columns="2" cellpadding="10">
<p:selectOneRadio id="newSlctDrk"
valueChangeListener="#{lookupSearch.getSelectedLogOpr}"
value="#{lookupSearch.selLogOpr}"
title="Combine all search criteria with AND or OR">
<f:selectItems id="newSlctDrkItms"
value="#{lookupSearch.logicalOperators}" />
</p:selectOneRadio>
</h:panelGrid>
</p:fieldset>
<h:panelGrid columns="3">
<p:commandButton value="Find" id="lkpfndDg" update="resultFldSet"
actionListener="#{lookupSearch.search}">
</p:commandButton>
<p:commandButton value="Clear" id="lkpClearDg"
actionListener="#{lookupSearch.clear}" />
</h:panelGrid>
<p:fieldset legend="Result" id="resultFldSet">
<p:dataTable binding="#{lookupSearch.lkpResultDataTable}"
value="#{lookupSearch.searchResultsForPage}"></p:dataTable>
</p:fieldset>
<p:commandButton value="Select" id="lkpSltRec" update="customerCode"
oncomplete="lpDialogVar.hide();insertSelectedValue();"
actionListener="#{lookupSearch.selectValue}" />
</h:panelGrid>
</h:form>
</p:dialog>
</h:panelGrid>
Here ecap:lookup is the customize component.
Finally, i have got the solution . The exception i have encountered is because of the form tag . The ajax event fired from the dialog is not able to find the component outside the form .In this case use:
:#{p:component('componentId')}
Here it will search the id not only within the form but outside of it.