Site doesn't reload after button click - ajax

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"}

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");
.
.
}

ActionListener not calls with ajax=false

I'm facing a strange issue with JSF, primefaces 5.2, glassfish 4, CDI ViewScoped Named beans. I've searched the forum but mostly people got stuck with ajax not working, while here Command button actionListener works with process="#form" but with ajax="false" it does not, rather just a full page refresh occurs. What i
understand that JSF default behavior is process="#form" but here i have to explicitly define it, without which ajax does not work. I've double checked and there are no nested forms in the hierarchy. Could it be something wrong with my development environment or am i doing something terribly wrong. Here is my jsf page
<h:panelGroup id="selectedtestpanel3">
<h:form id="SelectedTests3" >
<p:dataTable id="selectedTestDataTable3" value="#{aTestRegController.testprofilelist}" var="seltestprofile"
rowKey="#{aTestRegController.selectedToString(seltestprofile)}" tableStyle="width:auto" resizableColumns="true"
selectionMode="single" selection="#{aTestRegController.selected}" style="vertical-align:top;"
>
<p:ajax event="rowSelect" listener="#{aTestRegController.testprofilePull(aTestRegController.selected)}"
update="patientRegWizard:SelectedTests3, patientRegWizard:displayprices"/>
<p:column headerText="Test/Profile Name" width="10">
<h:outputText value="#{aTestRegController.selectedTestProfileName(seltestprofile)}"/>
</p:column>
<p:column headerText="Price" width="10">
<h:outputText value="#{aTestRegController.selectedTestProfilePrice(seltestprofile)}"/>
</p:column>
<p:column headerText="Container" width="10">
<h:outputText value="#{aTestRegController.selectedTestProfileContainer(seltestprofile)}"/>
</p:column>
</p:dataTable>
<p:commandButton id="saveReg" icon="ui-icon-plus" value="Save Test Registration01"
actionListener="#{aTestRegController.createVoucher()}"
disabled="#{empty aTestRegController.testprofilelist}"
ajax="false"
/>
</h:form>
</h:panelGroup>
Here are some lines of managed bean
#Named("aTestRegController")
#ViewScoped
public class ATestRegController implements Serializable {
#EJB
private facades.PatientFacade patientFacade;
#Inject
private facades.VoucherFacade voucherFacade;
#Inject
private facades.TestFacade testFacade;
public void createVoucher(){
this.biolist2=null;
this.hemolist2=null;
this.microlist2=null;
this.speclist2=null;
this.radiolist2=null;
try{
//if(this.getItem()!=null){
if(true){
tempSessionVars();
this.item=fillVoucher();
this.create();
List<Voucherdetails> cashvdlist = new ArrayList<>(this.item.getVoucherdetailsCollection());
String testprofilecashsliplist=AReportPrint.convertVoucherdetailsToString(cashvdlist);
AReportPrint.printCashSlip(testprofilecashsliplist, item);
iterateSelection();
profilelist=new ArrayList();
profilemap.clear();
testlist=new ArrayList();
testmap.clear();
}
}catch(Exception e){
e.printStackTrace();
}
}

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

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!

Navigate to another page on rowselect of datatable in primefaces

I have a primefaces datatable where number of records are displaying.
I want navigate to another page on the rowSelect event (to edit the selected entity for example).
The closest sample/demo I could find was use the p:ajax tag to bind the rowSelect event to a listener method
http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionInstant.jsf
I also got one article for the same http://forum.primefaces.org/viewtopic.php?f=3&t=14664
, I tried to implement in same as they did.But it also didn't worked.
I am trying in this way and guide me If I missed anything.
<p:dataTable var="product" value="#{addPatientBB.patientAddList}" paginator="true" rows="10"
selection="#{addPatientBB.pat}" selectionMode="single">
<p:ajax event="rowSelect" listener="#{addPatientBB.onRowSelect}" />
<p:column>
<f:facet name="header">
<h:outputText value="FirstName" />
</f:facet>
<h:outputText value="#{product.firstName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Email" />
</f:facet>
<h:outputText value="#{product.email}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Gender" />
</f:facet>
<h:outputText value="#{product.gender}" />
</p:column>
</p:dataTable>
And Backing bean is :
#ManagedBean
#ViewScoped
public class AddPatientBB implements Serializable
{
private Patient pat;
public Patient getPat()
{
System.out.println("tried to get pat");
return pat;
}
public void setPat(Patient pat)
{
this.pat = pat;
System.out.println("tried to set pat");
}
public void onRowSelect()
{
System.out.println("inside onRow select Method");
ConfigurableNavigationHandler configurableNavigationHandler = (ConfigurableNavigationHandler) FacesContext.getCurrentInstance().getApplication().getNavigationHandler();
System.out.println("navigation objt created");
configurableNavigationHandler.performNavigation("Page?faces-redirect=true");
// Page is my navigation page where I wish to navigate named as
// "Page.xhtml"
System.out.println("Navigation executed");
}
}
So how can I navigate to another page on rowselect event? and how can display its values after navigationg the form.
I am able to go inside onRowSelect() method , actually problem is he is not able to get or understood that path :
configurableNavigationHandler.performNavigation("Page?faces-redirect=true");
so he is not able to print any logs after this line.
why is it so? is it because of I am using Liferay?
Pla guide me.
Well i think the onRowSelect is never executed because you defined it wrong.
Try this:
public void onRowSelect(SelectEvent event)
{
FacesContext.getCurrentInstance().getExternalContext().redirect("page.xhtml?id=" +pat.getId());
}
If u are using FacesServlet then use.jsf instead of .xhtml
public void onRowSelect(SelectEvent event)
{
FacesContext.getCurrentInstance().getExternalContext().redirect("page.jsf?id="+pat.getId());
}

Removing a single row from DataTable using Ajax

I have a JSF view that lists items in a collection in a Primefaces DataTable. The rightmost columns contain remove buttons. When a remove button is clicked, it is supposed to make an Ajax call, remove the corresponding item from the session variable Cart and update the view in-place. I would like the request and the view change to be as minimal as possible.
Here is what I have for this purpose:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Register user</title>
</h:head>
<h:body>
<f:view>
<h:form id="itemsForm">
<p:outputPanel id="items">
<p:dataTable value="#{cart.itemList}" var="item">
<p:column>
<f:facet name="header">
<h:outputText value="name" />
</f:facet>
<h:outputText value="#{item.product.description}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="quantity" />
</f:facet>
<h:outputText value="#{item.quantity}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="" />
</f:facet>
<p:commandButton icon="ui-icon-close" title="remove from cart">
<p:ajax listener="#{cart.removeItem}"
update="form:itemsForm"
process="#this" />
</p:commandButton>
</p:column>
<f:facet name="footer">
Total amount: ${cart.totalAmount}
</f:facet>
</p:dataTable>
</p:outputPanel>
</h:form>
</f:view>
</h:body>
</html>
Accordingly, I have the following method in Cart.java
public void removeItem() {
System.out.println("REMOVE REQUEST ARRIVED");
}
However, the removeItem method isn't even executing when I click a remove button.
So my questions are:
1) What is wrong with my Ajax call? What changes should I make to my XHTML?
2) How do I handle the request in the removeItem method and return a response?
3) How do I update the footer, which displays the totalAmount?
You can pass #{item} as a parameter of your method call in the actionListener.
Your .xhtml page should look like this:
<p:dataTable id="cartTable" value="#{cart.itemList}" var="item">
<p:column>
<f:facet name="header">
<h:outputText value="" />
</f:facet>
<p:commandButton icon="ui-icon-close" title="remove from cart"
actionListener="#{cart.removeItem(item)}" update="cartTable" />
</p:column>
</p:dataTable>
And this is the method removeItem of your ManagedBean:
#ManagedBean
#ViewScoped
public class Cart {
private List<Item> itemList;
public void removeItem(Item item) {
itemList.remove(item);
}
}
1) <p:commandButton uses ajax by default , so instead placing the p:ajax use the action or actionListener of the <p:commandButton
2) I would use the action of the button and return null
3) update="#form" should update the entire form and this will update the entire table
here an example of a working button (link) from my page , i used the f:setPropertyActionListener to "pass" some data to the delete method
<p:commandButton action="#{cart.removeItem}" icon="ui-icon-close" title="remove from cart" update="#form" process="#this" >
<f:setPropertyActionListener
target="#{cart.selectedItem}"
value="#{item}" />
</p:commandButton>
in your class add this
private Item selectedItem;
public Item getSelectedItem() {
return selectedItem;
}
public void setSelectedItem(Item selectedItem) {
this.selectedItem = selectedItem;
}

Resources