How to refresh a p:dataTable after closing a dialog in PrimeFaces? - ajax

I need your help in refreshing the whole dataTable with pagination once I closed the dialog. With the current code after closing the dialog, the dataTable will be refreshed if the selected item is in the first page and I can see the updates.
However, if I have searched for a particular item using the filter and then I clicked on the view icon to view the dialog and then close the dialog. The dataTable will not be refreshed unless I deleted the searched item from the filter and then I tried to search for it again, I will find the updates.
The code for the page is:
<h:form id="Requests">
<p:dataTable id="PendingRequests"
var="hr"
value="#{hrd.pendingRequests}"
paginator="true"
rows="15"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15"
paginatorPosition="bottom"
filteredValue="#{hrd.filteredPendingRequests}">
<p:column headerText="Req. No." sortBy="#{hr.reqNo}" filterMatchMode="contains" filterBy="#{hr.reqNo}">
<h:outputText value="#{hr.reqNo}"/>
</p:column>
<p:column headerText="Print Count" filterMatchMode="contains" filterBy="#{hr.printCount}">
<h:outputText value="#{hr.printCount}"/>
</p:column>
<p:column>
<f:facet name="header">View</f:facet>
<p:commandButton id="submitbutton"
update=":Requests:#{hr.dialogueName} "
oncomplete="PF('#{hr.certificateDialogue}').show()"
title="View">
<f:setPropertyActionListener value="#{hr}" target="#{hrd.selectedRequest}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
And the code for the dialog is:
<p:dialog id="employmentCertificateDialog"
header="Certificate"
widgetVar="employmentCertificateDialog"
modal="true"
showEffect="fade"
hideEffect="fade"
resizable="true">
<p:ajax event="close"
listener="#{hrd.UpdateDatatable}"
update=":Requests:PendingRequests"/>
</p:dialog>
And the UpdateDatatable() method has the code:
public void UpdateDatatable(CloseEvent event) {
listPendingRequests = new ArrayList<PendingRequests>();
try {
//Select Statement
while (result.next()) {
PendingRequests pendingList = new PendingRequests();
reqNo = result.getString("REQ_SEQ_NO");
printCount = result.getString("DOC_PRINTED_CNT" + 1);
pendingList.setReqNo(reqNo);
pendingList.setPrintCount(printCount);
}
} catch (Exception e) {
e.printStackTrace();
}
}

Add the widgetvar to the dataTable widgetVar="dtWidgetVar"
and then:
<p:ajax event="close" listener="#{hrd.UpdateDatatable}" update=":Requests:PendingRequests" onComplete="PF('dtWidgetVar').filter()" />

I hope this helps:
<p:dialog id="dialog-test" onHide="refreshTable();">
...
</p:dialog>
Place at the end of your page:
<p:remoteCommand name="refreshTable" action="#{hrd.UpdateDatatable}"
partialSubmit="true" process="#this" update="Requests" />
If you need send information from your dialog to backBean maybe you need change the process, adding the dialog id or the element id what you want to send:
<p:remoteCommand name="refreshTable" action="#{hrd.UpdateDatatable}"
partialSubmit="true" process="#this, dialog-test" update="Requests" />
Good Luck!

Related

Getting Primefaces datatable row variable via non-ajax button post request

I have a datatable and polling in my Primefaces page. On Datatable on every row there is a commanButton. Because of polling, f:setPropertyActionListener does not works properly on button click. So I set ajax=false at button and trying to get datatable row "var" via a POST request. Is there a way to do that?
<p:poll interval="15"
listener="#{batchOperation.generateImportFTDBatchFileReport}"
update=":batchOperationsForm:growl :batchOperationsForm:batchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDbatchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDerrorbatchfilestbl
:batchOperationsForm:dataimporttypeselectiontabview:importFTDStatusTxtId"
widgetVar="myPoll" autoStart="true"/>
<p:dataTable id="batchfilestbl" var="batchFile"
value="#{batchOperation.batchFileModel}" paginator="true"
rows="#{batchOperation.batchFileModel.pageSize}"
paginatorPosition="bottom"
sortBy="#{batchOperation.createTime}"
sortOrder="descending"
emptyMessage="#{messages['common.datatable.emptymessage']}"
selectionMode="single"
selection="#{batchOperation.selectedFile}">
<p:column headerText="#{messages['content.batchoperations.datatable.header']}">
<p:commandButton actionListener="#{batchOperation.createBatchFileForDownloadLatestRevision}"
id="excelCreate" disabled="#{disableExcelVar}"
value="#{messages['content.batchoperations.createexcel.button.label']}"
ajax="false">
<f:setPropertyActionListener value="#{batchFile}"
target="#{batchOperation.selectedFile}" />
</p:commandButton>
</p:column>
</p:dataTable>
If you want to send the whole model object as a parameter to a backing bean method, you can send it in using your var for the data table.
<p:dataTable var="myVar">
<p:column>
<p:commandButton actionListener="#{bean.method(myVar)}" />
</p:column>
</p:dataTable>
Alternatively, if you are only interested in the row index, you can send just that using the rowIndexVar value for the data table.
<p:dataTable rowIndexVar="rowIndex">
<p:column>
<p:commandButton actionListener="#{bean.method(rowIndex)}" />
</p:column>
</p:dataTable>
It looks like you are trying to do file download here. You may want to checkout this question.
Instead of using f:setPropertyActionListener, f:attribute solved my problem.
<p:commandButton actionListener="#{batchOperation.createBatchFileForDownloadLatestRevision}"
id="excelCreate" disabled="#{disableExcelVar}"
value="#{messages['content.batchoperations.createexcel.button.label']}"
ajax="false">
<f:attribute name="bf" value="#{batchFile}" />
</p:commandButton>
Method:
public synchronized void createBatchFileForDownloadLatestRevision(ActionEvent event) throws Exception {
selectedFile = (BatchFile) ((CommandButton) event.getSource()).getAttributes().get("bf");
.
.
}

Site doesn't reload after button click

I developed a view to save Child-objects. Everything works fine but to see my additional objects in the <p:dataTable> I always have to reload the site manually.
Below the code for the <p:commandButton> which sends the form-data to my controller class.
<h:panelGrid columns="3">
<p:commandButton value="Save"
action="#{childController.doSaveChild}"
oncomplete="PF('childAddDialog').hide()"
update=":childForm"/>
</h:panelGrid>
I already tried to use ajax="false", but it doesn't work.
What can I do to get the site reloaded after click on save-button?
UPDATE:
<p:dataTable> from my view.xhtml:
<h:form id="childForm">
<p:dataTable id="childTable" var="child"
widgetVar="childTable" value="#{childController.children}"
paginator="true" rows="10" paginatorPosition="bottom"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink}
{PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}
{Exporters}"
rowsPerPageTemplate="10,25,50">
<p:column headerText="Firstname"
filterBy="#{child.firstName}"
sortBy="#{child.firstName}" filterStyle="display:none">
<h:outputText value="#{child.firstName}"/>
</p:column>
<p:column headerText="Lastname"
filterBy="#{child.lastName}"
sortBy="#{child.lastName}"
filterStyle="display:none">
<h:outputText value="#{child.lastName}"/>
</p:column>
<p:column headerText="Birthday"
filterBy="#{child.birthday}"
sortBy="#{child.birthday}"
filterStyle="display:none">
<h:outputText value="#{child.birthday}"/>
</p:column>
</dataTable>
</form>
Here the methods for providing the children for the view:
public Collection<Child> getChildren(){
return children;
}
#PostConstruct
public void initList(){
setChildren(childService.getAllChildren());
}
The xhtml-code from above is fine.
To get the site auto-updated it is necessary to load the list with all children again after the save-method in controller.
public void doSaveChild(){
childService.saveChild(child);
child = null;
initNewChild();
initList(); //this is needed to get up-to-date list in view
}
You could either do it via javascript:
<p:commandButton value="Save"
action="#{childController.doSaveChild}" process="#form" update="#none" oncomplete="location.reload();"/>
or a return String in your action method:
public String doSaveChild(){
//your logic
return "/yourpage?faces-redirect=true"}

Highlight row when single selection with a command component

Based on the primefaces documentation:
Single Selection with a Command Component
This method is implemented with a command component such as commandLink or
commandButton. Selected row can be set to a server side instance by passing as a parameter if you
are using EL 2.2 or using f:setPropertyActionListener.
<p:dataTable var="car" value="#{carBean.cars}">
<p:column>
<p:commandButton value="Select">
<f:setPropertyActionListener value="#{car}"
target="#{carBean.selectedCar}" />
</p:commandButton>
</p:column>
...columns
</p:dataTable>
I need the row get highlighted when I press the button without selecting the row directly
This is my code:
<p:dataTable
rowKey="${xxx.y1}-${xxx.y2}"
selection="${managedBean.selectedRow}"
selectionMode="single"
value="#{managedBean.listOfBeans}" var="xxx">
<p:column>
<p:commandButton action="${managedBean.saveSomethingInDB}"
update="vvvComponent">
<f:setPropertyActionListener value="#{currentRow}"
target="#{managedBean.selectedRow}" />
</p:commandButton>
</p:column>
</p:dataTable>
I solved it in this way:
<p:dataTable
rowKey="${xxx.y1}-${xxx.y2}"
selection="${managedBean.selectedRow}"
selectionMode="single"
value="#{managedBean.listOfBeans}" var="xxx">
<p:column>
<p:commandButton action="${managedBean.saveSomethingInDB}" onclick="highlightRow(jQuery(this));"
update="vvvComponent">
<f:setPropertyActionListener value="#{currentRow}"
target="#{managedBean.selectedRow}" />
</p:commandButton>
</p:column>
</p:dataTable>
function highlightRow(commandButton) {
$('.ui-state-highlight').removeClass('ui-state-highlight');
commandButton.closest('table').closest('tr').addClass('ui-state-highlight');
}
Your code works for me.
thanks to the propertyActionListener, the row is highlighted when I press the button
<f:setPropertyActionListener value="#{currentRow}"
target="#{managedBean.selectedRow}" />
i know its too late but this works
<p:commandButton action="${managedBean.saveSomethingInDB}" onclick="$('.ui-state-highlight').removeClass('ui-state-highlight');PF('tableWidgetVar').selectRow($(this).parents('tr:first').addClass('ui-state-highlight'));" >
<f:setPropertyActionListener value="#{currentRow}"
target="#{managedBean.selectedRow}" />
</p:commandButton>
and this way u dont need to selection or select mode on datatable

Datatable not refreshing with ajax

I have two calendar controls and one command button. basically i want to give a range of date to pick the data from the database and then when i press the command button the datatable is displayed in the dialog box, the problem is java bean class is working it is loading the exact data which i want, but the datatable is not refreshing with command button click
my code is given;
<h:form id="form" >
<p:calendar value="#{calendarBean.dateFrom}" id="calFrom" pattern="yyyy-mm-dd">
<p:ajax event="dateSelect" listener="#{calendarBean.handleDateSelectFrom}" />
</p:calendar>
<p:calendar value="#{calendarBean.dateTo}" id="calTo" pattern="yyyy-mm-dd">
<p:ajax event="dateSelect" listener="#{calendarBean.handleDateSelectTo}" />
</p:calendar>
<p:commandButton value="Submit" action="#{calendarBean.submit()}" update="fTable" onclick="aDlg.show()">
<f:ajax render=":form:fTable" execute="#form"></f:ajax>
</p:commandButton>
<p:dialog id="aDialog" header="Filter List" widgetVar="aDlg"
modal="true" showEffect="explode"
hideEffect="explode" >
<p:panel id="pnl">
<p:dataTable id="fTable" value="#{calenderBean.list}" var="row" >
<p:column headerText="ID">
<h:outputText value="#{row.ID}"/>
</p:column>
<p:column headerText="Name">
<h:outputText value="#{row.Name}"/>
</p:column>
<p:column headerText="Time">
<h:outputText value="#{row.Time}"/>
</p:column>
<p:column headerText="User">
<h:outputText value="#{row.userName}"/>
</p:column>
</p:dataTable>
</p:panel>
</p:dialog>
</h:form>
kindly guide me regarding this issue
First thing to do, is remove the f:ajax, it's not working good with Primefaces. Also the update attribute should do everything.
This said, I have the very same code as yours which is working good.
If removing f:ajax is not working, try to check your managed bean scope (May be it's of request scope and data is re-initialized with every request)
Try Updating the dialog instead.
update="fTable"

Primefaces: dynamic content refresh issue

I have a webapp where I select some content to be deleted. A modal pops-up displaying a preview of the image/flash selected. I hit a button and everything works fine. But, when I select another content to be deleted, the modal pops-up and, for a microsecond, it displays the previously deleted file which is then replaced by the new content I want to delete.
The code for showing the dynamic content is as follows:
For images:
<p:graphicImage value="#{controller.tempImage}" height="110"
id="imageID" />
For flash:
<p:media value="#{controller.tempImage}" width="110" height="110"
id="imageID" player="flash" />
Controller:
public StreamedContent getTempImage() {
try {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getRenderResponse() ) {
return new DefaultStreamedContent();
}
else {
tempImage = new DefaultStreamedContent(new FileInputStream("pathToFile"), "image/jpeg");
}
} catch (FileNotFoundException e) {
tempImage = new DefaultStreamedContent();
}
return tempImage;
}
I tried setting tempImage to null before loading and autoUpdate=true in the modal but no luck.
Delete button (the one that shows the delete modal):
<p:commandButton id="btnDelete" value="Delete" onclick="deleteModal.show();" actionListener="#{controller.initDelete}" update=":deleteForm">
Delete form (xhtml):
<h:form id="deleteForm" enctype="multipart/form-data" >
<p:dialog id="deleteDialog" widgetVar="deleteModal" modal="true" resizable="false" draggable="false" autoUpdate="true">
<p:outputPanel autoUpdate="false" >
<p:panelGrid id="panelId">
<p:row>
<p:column>
<p:panelGrid id="bannerPanel">
<p:row>
<p:column>
<p:graphicImage value="#{controller.tempImage}" height="110" id="imageID" />
</p:column>
</p:row>
</p:panelGrid>
</p:column>
</p:row>
<f:facet name="footer">
<p:row>
<p:column>
<p:commandButton id="doDeleteBtn" value="Delete"
actionListener="#{controller.delete}" >
</p:commandButton>
</p:column>
</p:row>
</f:facet>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
Change from:
onclick="deleteModal.show();"
to:
oncomplete="deleteModal.show();"
This will ensure that your dialog is viewed after AJAX request is completed, not before it is started.
You should use onclick, when you are creating so called push buttons, the buttons with type="button", which are just executing some JavaScript. Default type of buttons in Primefaces is submit.

Resources