Can 'update' attribute update two components simultanously? - jsf

I have a question. Is that possible to update two components at a time?
I am trying a code like this:
<h:panelGroup id="pickList">
<p:panel rendered="#{customCalender.visible}" widgetVar="searchTableBox">
//Some codes.....
<p:commandButton value="Cancel" update="pickList" actionListener="#{customCalender.closeList}" style="background:#25A6E1;color:red;font-family:'Helvetica Neue',sans-serif;font-size:10px;border-radius:4px;" />
<p:commandButton value="Save" update="custDataTablePanel" actionListener="#{customCalender.saveTargetList}" style="background:#25A6E1;color:red;font-family:'Helvetica Neue',sans-serif;font-size:10px;border-radius:4px;"/>
</p:panel>
</h:panelGroup>
....
.....
<h:panelGroup id="custDataTablePanel">
<p:panel rendered="#{customCalender.dataTableVisible}">
..
..
</p:panel>
</h:panelGroup>
Now I want when I click on the Save button it hides the <h:panelGroup id="pickList"> and displays the <h:panelGroup id="custDataTablePanel"> so I have two boolean values to control their visibility. but I need to update two of these panels. One I did with update="custDataTablePanel" it displays the data table after the button click.(in the method saveTargetList I updated the visibility of the custDataTablePanel to true.) but cant manage to hide the panel pickList.
So I was wandering is there any way to hide and show these two panels in one button click.
Please suggest.

You can use many elements in the update attribute separated by a space
<p:commandButton update="element1 element2"/>
also you can update the whole form by using update="#form"

Related

Primefaces - Customize p:confirmDialog content conditionally

I have a list of objects (let's call each object a record object), shown through a <p:datatable> component. Each record has a delete button column.
When a user clicks on the delete button of the record, a <p:confirmDialog> is shown, asking for user confirmation. What I want is to customize the content of the confirmDialog under corresponding circumstances (for example show/do not show a checkbox concerning the value of a property of the record, f.e if record.isPersonal, show the checkbox, else not.
Unfortunately, that does not seem to be working as the checkbox is always shown in case the first record satisfies the condition, and the opposite in case it does not. After some research I found out that especially in previous Primefaces versions, they used to use the "JS way" (creating two separate confirm dialogs and proportionally use PF('widgeName').show(), but I would like to know whether any out of the box solution exists in Primefaces 7.0 version which I use through the <p:confirm> tag or something else. Code example below:
<p:dataTable id="recordsTable" lazy="true" value="#{myBean.myList.records}" var="record...">
<p:column styleClass="deleteColumn">
<p:commandButton ...>
<p:confirm .../>
</p:commandButton>
<p:confirmDialog widgetVar="delete_record_dialog" global="true" showEffect="fade" hideEffect="fade">
<p:selectBooleanCheckbox
rendered="#{record.isPersonal}"
....>
</p:selectBooleanCheckbox>
<p:commandButton value="#{msg.yes}" type="button"
styleClass="ui-confirmdialog-yes" icon="pi pi-check"
/>
<p:commandButton value="#{msg.no}" type="button" styleClass="ui-confirmdialog-no"
icon="pi pi-times"
/>
</p:confirmDialog>
</p:column>
</p:dataTable>
Thanks in advance!
I think rather than using ConfirmDialog, you may have to revert to building you own custom dialog, either using p:dialog or using the dialog framework. Using dialog framework you can create a simple confirm dialog box and can pass the data into the dialog programatically - e.g. a flag based on the current row to indicate if the checkbox should be shown. The dialog framework also gives an easy way to return data back from the dialog to the calling page using the dialogReturn ajax event.
You could use the <p:confirmDialog message=""/> to conditionally display different messages like this:
<p:confirmDialog widgetVar="delete_record_dialog"
header="Record delete"
message="Are you sure you want to delete #{record.isPersonal ? 'your personal' : 'this'} record?">
<h:form id="recordDeleteForm">
<p:commandButton value="#{msg.yes}" update=":tableForm"
oncomplete="PF('deleteDialog').hide(); PF('recordsTableWidgetVar').filter()"/>
<p:commandButton value="#{msg.no}" type="button"
onclick="PF('delete_record_dialog').hide()"/>
</h:form>
</p:confirmDialog>
If you want to fit in more content then you could use <f:facet name="message">...</f:facet/>
See also:
<p:confirmDialog> with a parameter message

Primefaces form is not updating from within dialog

I have a view like so:
<h:form id="productForm">
<p:messages
id="productFormMessages"
autoUpdate="true"
redisplay="true"
globalOnly="true" />
<p:panelGrid
id="detailsGrid">
<p:row>
...
<p:column>
...
<p:outputLabel
id="fieldToUpdateId"
value="XYZ" />
<p:commandButton
action="#{bean.prepareDialog}"
update="dialogFormId"
oncomplete="PF('dialogModal').show();" />
</p:column>
</p:row>
</p:panelGrid>
</h:form>
<ui:include src="/../.../dialog.xhtml" />
And this is what dialog.xhtml looks like:
<p:dialog
id="dialogId"
widgetvar="dialogModal"
appendTo="#(body)"
modal="true"
dynamic="true">
<h:form
id="dialogFormId">
...a selectOneMenu...
<p:commandButton
id="saveButtonId"
value="Save"
actionListener="#{bean.save}"
oncomplete="PF('dialogModal').hide();"
process="#form"
update=":productForm" />
</h:form>
But the save button just refuses to update the productForm. It does update productFormMessages (which I'm guessing is because of the autoUpdate) but the form just doesn't update. I need to do a page reload from the browser in order for it to reflect the latest data. I have tried many different ways of doing this.
1. Using p:component to directly refer to the outputLabel in the update attribute.
2. (1) also using the form ID and the panelGrid ID.
3. Using the full client ID (with and without the preceeding ':') in the update attribute. Similarly using the form ID and the panelGrid ID.
4. Adding the client ID to the render IDs in the bean and then calling the partialViewContext#update method on that.
4. Setting partialViewContext#setRenderAll to true.
4. And as a last ditch attempt, as demonstrated by the code, updating the entire productForm. Which isn't so bad, because fieldToUpdateId is just one of the fields that I need to update in the form. But either way, it's not working.
Clearly, the data is being saved on the back end, because a page reload gives me the latest data. But I just can't get the dialog to update the form where it's being called from. I'm out of ideas. What am I doing wrong?
Theoretically this should work, But please inspect the button in the Html source, to make sure which part of the html it refresh. it should have something like this.
onclick="PrimeFaces.ab({s:'dialogFormId:saveButtonId1',u:'productForm',onco:function(xhr,status,args){PF('dialogModal').hide();;}});return false;"

<p:overlayPanel> shows blank white after updating via command link/button

I am looking for solution that p:overlayPanel content should update it self while clicking commendButton or commendLink. But its showing blank white p:overlayPanel when i click the button. The updating with the p:overlayPanel id in that button or link. I have tried many ways nothing worked out. Is my code wrong?
Please suggest some solution.
Here is my code :
<ui:repeat id="profiles" value="#{items.lstProfiles}" var="profile">
<p:commandLink id="profileLink" value="show" update="moviePanel"
actionListener="#{dashBoardController.showProfileOverlay}"/>
<p:overlayPanel id="moviePanel" for="profileLink" hideEffect="fade"
dynamic="true" style="width:300px; height: 150px;">
<h:panelGrid columns="2">
<h:outputText value="Name : "/>
<h:outputText value="#{dashBoardController.selectedProfile.name}"/>
</h:panelGrid>
</p:overlayPanel>
</ui:repeat>
Usually dynamic="true" should do the job but some times it fails.So to update the contents inside the Overlay.
There are many ways to do this by tweaking Jquery.
Simplest one I can think of is:
Since ui:repeat generates dynamic ID for p:overlayPanels you can update by providing unique css class name from every iteration.
In Primefaces you can select a component using css class also using: #(.myclass).
And so you can update that component also:- update="#(.mystyle)"
Example:
<h:form>
<ui:repeat var="patient" value="#{dataCenter.patientList}">
<p:commandLink value="#{patient.firstName}" id="patientNameLnk" update="#(.overlay-class-#{patient.patientId})"/><br/>
<p:overlayPanel for="patientNameLnk">
<h:panelGroup styleClass="overlay-class-#{patient.patientId}">
#{patient.firstName}
#{patient.lastName}
#{patient.dob}
</h:panelGroup>
</p:overlayPanel>
</ui:repeat>
</h:form>
In the above example css class name for every h:panelGroup will be generated as overlay-class-<PATIENT_ID> so every h:panelGroup will have unique class name(if patientId is unique).
Note: Note that I'm updating h:panelGroup inside p:overlayPanel because if you update p:overlayPanel then it might start flickering(it happened to me while executing above example).

Primefaces process attribute in reseting form inputs

I have a form inside a modal dialog and after closing (hiding in fact) one I wanted to reset all inputs that user might have changed. I though about something like as follow:
<p:dialog widgetVar="myDialog">
<h:form id="formId">
<!-- ... -->
<p:commandButton value="Cancel" onclick="myDialog.hide();"
update="formId">
<p:resetInput target="formId" />
</p:commandButton>
</h:form>
</p:dialog>
But the result was not that I expected. After a while of searching I found a solution that was to add process="#this" attribute to the <p:commandButton>. And my question is why it is necessary? What is really happening in backgroud that this process is desired. I don't really get the idea of process attribute at all.
I have done some work with dialog boxes and the way I did to make the form null is, when clicking the button to open dialog box, I ran a method in backing bean which cleared my pojo so my form had empty values.
In your case it could be something like this:
<h:form id="form-button">
<p:commandButton id="AddButton" value="open dialog box"
update=":form" action="#{myBean.myMethodToSetPojoNull}" immediate="true"
oncomplete="PF('myDialog').show()" />
</h:form>
When clicking this button, the called method will set to null all the fields and your dialog box will be empty. Getting back to your question of why process=#this is neccessary much better explained answer is here
What is the function of #this exactly?
You can also reset input after submitting through this method:
<p:commandButton value="Reset Non-Ajax"
actionListener="#{pprBean.reset}" immediate="true" ajax="false">
<p:resetInput target="panel" />
</p:commandButton>
If you don't add process="#this" then by default attribute value will be set to process="#form" which means all the elements in the form are processed. In command buttons process="#this" is mandatory to execute the corresponding actions associated with that button.
You can directly refer the answer from Balusc in this link
What is the function of #this exactly?

Two h:forms inside one h:form

I have two primefaces dialog that are inside in one h:form and i want to submit some required values from one dialog without submit required values from the other one:
<h:form>
<p:dialog modal="true" widgetVar="A">
<h:inputText value="#{bean.value}" required="true" />
<p:commandButton value="A" action="#{bean.someAction}" />
</p:dialog>
<p:dialog modal="true" widgetVar="B" >
<h:inputText value="#{bean.otherValue}" required="true" />
<p:commandButton value="B" action="#{bean.someOtherAction}" />
</p:dialog>
</h:form>
If i press commandButton A the validation of required value inside dialog B dont let me submit values from dialog A.
How can i do that?
The best and the logical solution is to split dialogs into separate forms. Moreover, the best practice is to put the form inside the dialog, and not vice versa.
Another solution is to explicitly tell JSF/PrimeFaces what to update and to process during an ajax request by specifying the corresponding attribute of your command button, or nesting an ajax tag inside the button.

Resources