How to change the state of properties before event calls? - jsf

I am using this dialog to display a Create form
<p:dialog id="dialogoGestion" header="Asignar nueva gestión" widgetVar="dlg1" >
<p:ajax event="close" update="dialogoGestion"/>
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Cliente: "/>
<h:outputText value="#{miscMB.factura.cliente.nombre}"/>
<h:outputText value="Factura: "/>
<h:outputText value="#{miscMB.factura}"/>
<h:outputLabel value="#{bundle.CreateGestionLabel_descripcion}" for="descripcion" />
<p:inputText id="descripcion" value="#{miscMB.nuevaGestion.descripcion}" title="#{bundle.CreateGestionTitle_descripcion}" />
<h:outputLabel value="#{bundle.CreateGestionLabel_fechaLimiteGestion}" for="fechaLimiteGestion" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaLimiteGestion" value="#{miscMB.nuevaGestion.fechaLimiteGestion}" title="#{bundle.CreateGestionTitle_fechaLimiteGestion}" required="true" requiredMessage="#{bundle.CreateGestionRequiredMessage_fechaLimiteGestion}">
</p:calendar>
<h:outputLabel value="#{bundle.CreateGestionLabel_usuario}" for="usuario" />
<p:selectOneMenu id="usuario" value="#{miscMB.nuevaGestion.usuario}" required="true" requiredMessage="#{bundle.CreateGestionRequiredMessage_usuario}">
<f:selectItems value="#{usuarioController.itemsAvailableSelectOne}"/>
</p:selectOneMenu>
</h:panelGrid>
<br />
<p:commandButton onsuccess="micalendario.update();PF('dlg1').hide();" action="#{gestionController.crearGestion()}" value="#{bundle.CreateGestionSaveLink}" >
<f:setPropertyActionListener target="#{gestionController.selected}" value="#{miscMB.nuevaGestion}"/>
<f:setPropertyActionListener target="#{gestionController.factura}" value="#{miscMB.factura}"/>
<f:setPropertyActionListener value="#{null}" target="#{miscMB.nuevaGestion}"/>
<f:actionListener binding="#{miscMB.anularNuevaGestion()}"/>
<f:actionListener binding="#{miscMB.agregarGestion(gestionController.selected)}"/>
</p:commandButton>
</h:form>
</p:dialog>
This is where I call the dialog to display
<p:commandLink value="Asignar gestión" onclick="PF('dlg1').show();return false;" action="#{gestionController.preparar()}" rendered="#{miscMB.factura!=null}">
<f:setPropertyActionListener target="#{gestionController.factura}" value="#{miscMB.factura}"/>
</p:commandLink>
What happens is that both <h:outputText value="#{miscMB.factura.cliente.nombre}"/> and <h:outputText value="#{miscMB.factura}"/> values display the properties' last state.
For example, the first time an item selected and you call the dialog, the output is none, because the state is not set. Then, when you select another item and call the dialog, the output is the state last set, which is the previous item value.
Apparently, the setPropertyActionListener in the commandLink is called after the dialog is closed or it executes an action, but not when the commandLink is clicked.
So, how can I set the properties before the dialog frame is displayed?

Related

<p:dataScroller> reloading automatically on entity edits

I have a p:datascroller configured to display a list of entities and lazy loading them upon clicking the more button.
<h:form id="investigationOperationsForm">
<p:dataScroller
value="#{investigationManagerBackingBean.lazyLoadedInvestigationOperations}"
var="investigationOperation" chunkSize="9" lazy="true"
rowIndexVar="test">
<f:facet name="header">
Scroll down to load investigations
</f:facet>
<h:panelGrid columns="2" style="width:100%"
columnClasses="logo,detail">
<p:commandLink oncomplete="PF('investigationDialogW').show()"
update="investigationEditorForm" immediate="true">
<f:setPropertyActionListener value="#{investigationOperation}"
target="#{investigationManagerBackingBean.selection}" />
<p:graphicImage alt="Investigation Operation"
url="/images/common/investigation-operation.png" />
</p:commandLink>
<!-- h:outputText value="#{investigationOperation.name}" /-->
<p:outputPanel id="pnl">
<h:panelGrid columns="2" cellpadding="5">
<h:outputText value="Name:" />
<h:outputText value="#{investigationOperation.name}"
style="font-weight: bold" />
<h:outputText value="Description:" />
<h:outputText value="#{investigationOperation.shortDescription}"
style="font-weight: bold" />
</h:panelGrid>
<p:draggable for="pnl" />
</p:outputPanel>
</h:panelGrid>
<f:facet name="loader">
<p:outputPanel
visible="#{investigationManagerBackingBean.lazyLoadedInvestigationOperations.rowCount gt 10}"
rendered="#{investigationManagerBackingBean.lazyLoadedInvestigationOperations.rowCount gt 10}">
<p:commandLink value="More" />
</p:outputPanel>
</f:facet>
</p:dataScroller>
</h:form>
In addition, I have a dialog that pops up when the p:commandLink oncomplete method is executed where I can update the value of the current selection and persist the changes.
<p:dialog id="investigationDialog"
header="#{msg['inv-manager.invDialog.header.title']}"
widgetVar="investigationDialogW" minWidth="400" minHeight="400"
resizable="false" position="center center" modal="true">
<p:panel id="investigationEditorPanel">
<h:form id="investigationEditorForm">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="name"
value="#{msg['inv-manager.invDialog.nameFieldLabel']}" />
<p:inplace id="nameInplaceEditor" editor="true">
<p:inputText
value="#{investigationManagerBackingBean.selection.name}"
id="name" required="true" immediate="true"
label="#{msg['inv-manager.invDialog.nameFieldInputLabel']}" />
</p:inplace>
<h:outputLabel for="shortDescription"
value="#{msg['inv-manager.invDialog.shortDescriptionFieldLabel']}" />
<p:inplace id="shortDescriptionInplaceEditor" editor="true">
<p:inputText
value="#{investigationManagerBackingBean.selection.shortDescription}"
id="shortDescription" required="true" immediate="true"
label="#{msg['inv-manager.invDialog.shortDescriptionFieldInputLabel']}" />
</p:inplace>
<h:outputLabel for="description"
value="#{msg['inv-manager.invDialog.descriptionFieldLabel']}" />
<p:inputTextarea id="description" required="false"
label="#{msg['inv-manager.invDialog.descriptionFieldInputLabel']}"
immediate="true"
value="#{investigationManagerBackingBean.selection.description}" />
<p:commandButton id="okButton"
value="#{msg['inv-manager.invDialog.okButton']}" type="submit"
partialSubmit="true" process="investigationEditorForm"
action="#{investigationManagerBackingBean.createOrUpdate()}"
onclick="dlg.hide();" />
</h:panelGrid>
</h:form>
</p:panel>
</p:dialog>
The backing bean is configured to be #ViewScoped and everything works as defined. However, upon update the values of the p:datascroller are reset and the load method of the lazy loading model is executed and the datascroller is repopulated with new values from the database.
I have no reference to the datascroller or its containing form in the p:dialog and am wondering why the datascroller is being updated automagically? What am I missing in the equation. Have I overlooked something or something specific to the p:datascroller model that I need to consider when following this approach?
Look forward to the expertise of the community in resolving this issue.
Many thanks in advance :)

Selected values of selectBooleanCheckbox and selectoneradio is reset while navigating between tabs of tabview

I am trying to do a page with a few tabs, by using primefaces. But some some selected values are lost while navigating between tabs. Last tab contains 2 selectBooleanCheckboxes and 2 selectOneRadios and one of the selectoneradio grid is rendered according to checkbox value. When user selects among these 4 components and navigates between tabs radio button and check box selected values are lost. I am using #viewScoped at the bean part. For example if the user is viewing the 4th tab and wants to change something from third tab. When user navigates to the third tab and makes change on checkbox or radio button new values and previous values are reset. Form is uploading itself again I think. Why the values are lost?Is there a solution for this? Do I need something like converter?
my .xhtml is:
<h:form id="form">
<p:tabView id="tabPanel" dynamic="true" activeIndex="#{myBean.activeIndex}" cache="false">
<!-- FIRST TAB -->
<p:tab id="person" title="Person">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="name" />
<p:inputText value="???USERINFO???" label="Name" />
<p:commandButton value="NEXT" action="#{myBean.nextTab}" update=":form:tabPanel" />
</h:panelGrid>
</p:tab>
<!-- SECOND TAB -->
<p:tab id="adres" title="Address">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="Phone" />
<p:inputMask id="phone" value="???USERINFO???" mask="1999999999" required="true" requiredMessage="ERROR AT PHONE NUMBER"/>
<p:commandButton value="NEXT" action="#{myBean.nextTab}" update=":form:tabPanel" />
</h:panelGrid>
</p:tab>
<!-- THIRD TAB -->
<p:tab id="contact" title="Contact">
<h:panelGrid columns="2" cellpadding="10">
<h:panelGrid columns="3" style="margin-bottom:5px" cellpadding="5">
<h:outputText value="My Question: " />
<p:selectBooleanCheckbox value="#{myBean.myCheckBox}" />
<h:outputText value="Yes" />
<h:outputText value="My Second Question:" />
<p:selectBooleanCheckbox value="#{myBean.myCheckBox2}" />
<h:outputText value="No" />
</h:panelGrid>
<h:panelGrid id="panelGrid" columns="3" style="margin-bottom:10px" cellpadding="10">
<p:outputLabel value="My question"/>
<h:outputLabel for="radio"/>
<h:selectOneRadio id="radio" value="#{myBean.radioButton}" required="true" requiredMessage="ERROR">
<f:selectItem itemLabel="Yes" itemValue="Yes"/>
<f:selectItem itemLabel="No" itemValue="No"/>
<f:ajax execute="#this" render="idInfo"/>
</h:selectOneRadio>
</h:panelGrid>
<h:panelGroup id="idInfo">
<h:panelGrid columns="3" rendered="#{myBean.radioButton == 'No'}">
<h:outputText value="Chooses: " />
<h:selectOneRadio id="selectOneRadio" value="#{myBean.type}" layout="pageDirection">
<f:selectItem itemLabel="Choice 1" itemValue="choice1"/>
<f:selectItem itemLabel="Choice 2" itemValue="choice2"/>
<f:selectItem itemLabel="Choice 3" itemValue="choice3"/>
</h:selectOneRadio>
</h:panelGrid>
</h:panelGroup>
</h:panelGrid>
</p:tab>
</p:tabView>
</h:form>
<p:commandButton value="NEXT" action="#{myBean.nextTab}" update=":form:tabPanel" />
Add process to your button's process=":form:tabPanel" so the value is set to the property in backbean.

how to reload p:dataGrid programmatically?

I have a datagrid with subscribe and unsubscribe option so the user can subscribe and unsubscribe and vise verse.
now I want to reload the datagrid after subscription or unsubscription
I load the data of the grid like that
#PostConstruct
public void init() {
packages = packagehelper.getAllPackages();
getCurrentUserSubscritions();
}
and here is the xhtml file
<h:form id="form">
<p:growl id="growl" showDetail="true" sticky="false" life="8000" />
<p:dataGrid var="package" value="#{packageView.packages}" columns="3"
>
<p:column>
<f:facet name="header">
Cars for Sale
</f:facet>
<p:panel header="#{package.id}" style="text-align:center">
<h:panelGrid columns="2" style="width:100%">
<p:graphicImage width="100px" name="images/#{package.imageurl}"/>
<h:outputText value="#{package.name}" />
<h:outputText value="#{package.value} EGP for #{package.duration} Days " />
<h:outputText value="#{package.description}" />
<p:commandButton ajax="true" update=":pack" value="Subscribe" rendered="#{!packageView.IsPackageActive(package.id)}" action="#{packageView.Subscribe()}" >
<f:setPropertyActionListener value="#{package.id}" target="#{packageView.packageID}" />
<f:setPropertyActionListener value="#{package.duration}" target="#{packageView.packageDuration}" />
</p:commandButton>
<p:commandButton action="#{packageView.Unsubscribe}" update=":pack" ajax="true" value="Cancel" rendered="#{packageView.UserHasPackage(package.id) and packageView.IsPackageActive(package.id) }">
<f:setPropertyActionListener value="#{package.id}" target="#{packageView.packageID}" />
<f:setPropertyActionListener value="#{package.duration}" target="#{packageView.packageDuration}" />
</p:commandButton>
</h:panelGrid>
</p:panel>
</p:column>
</p:dataGrid>
</h:form>
When an suscribe or unsuscribe action is completed, you should actualize the DataGrid trough its ID, it is, set an ID to the DataGrid and put such id in the update property of the buttons.
For example:
<p:dataGrid id="datalist" .../>
<p:commandButton action="#{packageView.Unsubscribe}" update="datalist" .../>
And when the action of the button is submited set the packages in null, so when the update action of the DataGrid update the packages they should be called again of the persistence or data base.
It is important to consider how to reference the elements in update property. You can see this answer

JSF2 - selectOneMenu opens outside overlayPanel

I'm working with a <p:overlayPanel> that includes a couple of <p:selectOneMenu>s, as well as several other components. When the <p:selectOneMenu>s are opened, some of the fields fall outside of the <p:overlayPanel>, and clicking on them causes the panel to close. (See image below).
.
.
.
One solution would be to modify the <p:overlayPanel> as follows:
dismissable="false"
showCloseIcon="true"
Another would be to modify the <p:selectOneMenu>:
height="50"
I'm looking for some options for solutions that are as simple as possible and preferably don't involve a change to the UI (the above solutions both change the UI). Is there a way to keep the <p:overlayPanel> open when a click outside of it falls within one of its <p:selectMenu>s?
More Complete Code
<p:overlayPanel styleClass="col-settings-panel"
id="colSettingsPanel"
for="columnSettingsBtn"
hideEffect="fade"
widgetVar="wvcolSettingsPanel"
rendered="#{empty rendered ? 'true' : rendered}" >
<p:pickList id="pickList"
value="#{fileSearchPersonalizationBean.columns}"
var="column"
showSourceFilter="true"
itemLabel="#{column}"
itemValue="#{column}"
itemDisabled="#{column eq 'Ref No'}">
<p:ajax event="transfer" listener="#{fileSearchPersonalizationBean.onTransfer}" update="pickList availableCount selectedCount selectSortBy" />
<f:facet name="sourceCaption">
<h:outputText value="Available Columns ("/>
<h:outputText id="availableCount" value="#{fileSearchPersonalizationBean.sourceCount}"/>
<h:outputText value=")"/>
</f:facet>
<f:facet name="targetCaption">
<h:outputText value="Selected Columns ("/>
<h:outputText id="selectedCount" value="#{fileSearchPersonalizationBean.targetCount}"/>
<h:outputText value=")"/>
</f:facet>
</p:pickList>
<p:panelGrid columns="1">
<p:outputPanel styleClass="col-settings-panel-option">
<h:outputLabel value="Sort By: " />
<p:selectOneMenu id="selectSortBy"
value="#{fileSearchPersonalizationBean.sortBy}" >
<p:ajax listener="#{fileSearchPersonalizationBean.sortByChanged}" />
<f:selectItems id="sortByList" value="#{fileSearchPersonalizationBean.columns.target}" />
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel styleClass="col-settings-panel-option">
<h:outputLabel value="Items per Page:"/>
<p:selectOneMenu id="selectRows" value="#{fileSearchPersonalizationBean.sRows}" >
<f:selectItem itemLabel="10" itemValue="10" />
<f:selectItem itemLabel="25" itemValue="25" />
<f:selectItem itemLabel="50" itemValue="50" />
<f:selectItem itemLabel="100" itemValue="100" />
</p:selectOneMenu>
</p:outputPanel>
</p:panelGrid>
<p:panelGrid styleClass="toolbar" columns="2">
<p:outputPanel>
<p:commandButton styleClass="btn-secondary"
id="loadDefaults"
value="Reset Defaults"
update="selectSortBy pickList selectRows"
actionListener="#{fileSearchPersonalizationBean.loadDefaultVO}" />
</p:outputPanel>
<p:outputPanel styleClass="toolbar-right">
<p:commandButton styleClass="btn-secondary"
id="columnClose"
value="Cancel"
actionListener="#{fileSearchPersonalizationBean.panelCancel}"
immediate="false">
<f:attribute name="panelId" value="#{formId}:colSettingsPanel" />
</p:commandButton>
<p:commandButton styleClass="btn-primary"
id="columnSubmit"
value="Save & Apply"
actionListener="#{fileSearchPersonalizationBean.panelSave}"
oncomplete="refreshSearchResults();" >
<f:attribute name="panelId" value="#{formId}:colSettingsPanel" />
</p:commandButton>
</p:outputPanel>
</p:panelGrid>
</p:overlayPanel>`

How to update component on clientside in primefaces?

I want to create add children button with dialog form feature.
On the page there are tree and modal dialog form. On every node of tree will be the create child button. If you click on create child button, there will be shown modal form, where parentId will be set as id of node where button was clicked
Tree:
<h:form id="TestGroupListForm">
<p:tree value="#{testTreeController.root}" var="node" dynamic="true" cache="false"
selectionMode="single" selection="#{treeBean.selectedNode}" id="tree">
<p:treeNode>
<h:outputText value="#{node.getName()}" /> <p:commandButton id="createButton#{node.getIdTestGroup()}" icon="ui-icon-plus" value="#{bundle.Create}" update="tree" oncomplete="TestGroupCreateDialog.show()"/>
</p:treeNode>
</p:tree>
</h:form>
Dialog Box:
<h:form id="TestGroupCreateForm">
<h:panelGroup id="display">
<p:panelGrid columns="2" >
<p:outputLabel value="#{bundle.CreateTestGroupLabel_name}" for="name" />
<p:inputText id="name" value="#{testGroupController.selected.name}" title="#{bundle.CreateTestGroupTitle_name}" />
<h:inputHidden id="parentId" value="#{testGroupController.selected.parentId}" />
</p:panelGrid>
<p:commandButton actionListener="#{testGroupController.saveNew}" value="#{bundle.Save}" update="display,:TestGroupListForm:tree,:growl" oncomplete="handleSubmit(xhr,status,args,TestGroupCreateDialog);"/>
<p:commandButton value="#{bundle.Cancel}" onclick="TestGroupCreateDialog.hide()"/>
</h:panelGroup>
</h:form>
</p:dialog>
I want that click on
<p:commandButton id="createButton#{node.getIdTestGroup()}" icon="ui-icon-plus" value="#{bundle.Create}" update="tree" oncomplete="TestGroupCreateDialog.show()"/>
Will set value of:
<h:inputHidden id="parentId" value="#{testGroupController.selected.parentId}" />
UPDATE
I have to use action listener testGroupController.nodeListener to set parentId of the new item.
<p:commandButton process="#this" id="createButton" actionListener="#{testGroupController.nodeListener}" icon="ui-icon-plus" value="#{bundle.CreateGroup}" update=":TestGroupCreateForm" oncomplete="TestGroupCreateDialog.show()">
<f:attribute name="rawParentId" value="#{node.getIdTestGroup()}" />
</p:commandButton>
You can add parentId to the existing update= attribute like so:
update="tree parentId"
This will render parentId and set its value to testGroupController.selected.parentId.
Edit
You can process any values from the UI to the been too, by using:
process="myInputId"
Example
<h:form>
<h:inputText id="input"
value="#{bean.value}" />
<h:outputText id="output"
value="#{bean.value}" />
<p:commandButton process="input"
update="output"
value="Submit" />
Upon clicking your button, the value of id="input" will be set in bean.value (as ordered by process="input"). Next your id="output" will be rendered (or updated) with bean.value (as ordered by update="output").

Resources