primefaces p:ajax update not working - jsf-2

I am using primefaces 3.4.2 datatable with in-cell editing. I would like after the edit event method is called, the datatable itself to be updated. I did it like this:
<p:dataTable id="timeTable" var="log" value="#{reviewTimesheetBean.lazyModel}" paginator="true"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="15,30,45,60"
paginatorPosition="bottom" rows="2" currentPageReportTemplate="{currentPage} de {totalPages}" lazy="true" editable="true" emptyMessage="#{label['empty.message']}">
<p:ajax event="rowEdit" listener="#{reviewTimesheetBean.onEdit}" update="timeTable" />
<p:ajax event="rowEditCancel" listener="#{reviewTimesheetBean.onCancel}" update="timeTable" />
....
</p:datatable>
But the load method is never called after the rowEdit event. I also tried using the selectors, but it did not work either. Can't the datatable be updated this way?
Thanks
Kelly

Have you tried remoteCommand?
<p:remoteCommand name="onCellEdit" action="#{bean.init}" update="formId" ignoreAutoUpdate="true" />
And then in your datatable:
<p:ajax event="cellEdit" oncomplete="onCellEdit()" listener="#{bean.onCellEdit}" />
PS. the remoteCommand is just above the datatable... not sure if that has any impact.
Note the onComplete value must match the name of the remote command.

Related

Primefaces datatable pagination resets filter

I'm using a p:datatable with filters and pagination. Both work fine individually, but if I filter first then move to the second page of results, the filter is removed and I'm seeing the second page of the original data set. Here's what my table looks like :
<p:dataTable value="#{bean.products}" var="product"
paginator="true" paginatorPosition="bottom" rows="5"
filteredValue="#{bean.filteredProducts}"
rowKey="#{product.prdctId}">
<p:ajax event="sort" skipChildren="false" />
<p:column headerText="Description" filterBy="#{product.description}" filterMatchMode="contains"
sortBy="#{product.prdctId}">
<h:outputText value="#{product.description}" />
</p:column>
(other columns)
</p:dataTable>
Any ideas?
Using Primefaces 5.2, JSF 2.0.3
Edit : After searching a bit more, I found another post dealing with the same issue, but it was never answered.
<p:dataTable value="#{bean.products}" var="product"
paginator="true" paginatorPosition="bottom" rows="5"
filteredValue="#{bean.filteredProducts}"
rowKey="#{product.prdctId}">
<p:ajax event="sort" skipChildren="false" />
<p:column headerText="Description" filterBy="#{product.description}" filterMatchMode="contains"
sortBy="#{product.prdctId}">
<h:outputText value="#{product.description}" />
</p:column>
(other columns)
Add in your datatable: widgetVar="productTable"
in your button add this: oncomplete="PF('productTable').clearFilters();"

Primefaces data table Row selection and multiple checkbox selection not working

I am using primeface 3.5 where i find the check box to select and unselect or row select work perfectly independently . While I tried to have both the row selection and check box selection ,row selection event is not triggering . Could any one clarify this for me ?
row select is not working thou check all event is working
<p:dataTable id="myBookDTable" var="car" value="#{myBean.pageViews}" paginatorPosition="bottom" paginator="true" rows="30" scrollable="true" scrollHeight="400" scrollRows="30" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="30,50,100"rowKey="#{car.carID}" rowIndexVar="rowIndex" draggableColumns="true" lazy="true">
<p:ajax event="rowSelect" listener="#{myBean.onRowSelect}" update="certainpart"
async="true"/>
<p:ajax event="rowSelectCheckbox" listener="#{myBean.rowSelectCheckbox}"/>
<p:ajax event="rowUnselectCheckbox" listener="#{myBean.rowUnselectCheckbox}"/>
<p:ajax event="rowUnselect" listener="#{myBean.rowUnselect}"/>
<p:column width="30" selectionMode="multiple" style="width:2%" />
</p:datatable>
For column header event we have a different header name exist in primeface/jsf:
"toggleSelect".
You can use like this:
<p:ajax event="toggleSelect" update="#this" process="#this" />
In your datatable tag,
Use this
<p:ajax event="rowSelectCheckbox" update="someComponent" />
<p:ajax event="rowUnselectCheckbox" update="someComponent" />
<p:ajax event="rowSelect" update="someComponent" />
<p:ajax event="rowUnselect" update="someCompoent" />
<p:column selectionMode="multiple" style="width:4%" />
you need to fire these four ajax events and make sure you make the column selectionMode as multiple
Try this:
<p:ajax event="toggleSelect" update=":form:component" partialSubmit="true" />
The source:
PrimeFaces 4.0 User Guide.- Ajax Behavior Events

Primefaces dataTable rowIndexVar with pagination

I'm using a primefaces datatable with single row selection and pagination. For each row I have some commandlinks (one of which is disabled) that I want the user to click to perform operations on that row (example: delete, edit).
In order to provide visual confirmation that the user clicked the button on the right row, I want the row to be selected upon clicking and then proceed to the desired bean method.
This is working as intended if the table has only one page or if it's page 1; on all other pages I get a NullPointerException.
I figured out why this happens: I use rowIndexVar to perform the selection but it seems to be returning the index related to the whole table and the selectRow method expects an index related to the current page. Meaning that if I have 10 rows per page and I click on the third row in the second page, the index returned is "12" and not "2" and selectRow(12, false) returns null as there are only 10 items on that page.
My question is: how can I pass the correct rowIndex so I get the correct selection on all pages?
The backing bean is ViewScoped and the methods aren't nothing extraordinary but since it has a lot of code related to webservices and jaxb generated classes and I signed an NDA I can't paste it here (I'm already pushing it by sharing the datatable code).
<p:dataTable id="dataTable" var="item" rowIndexVar="rowIndex"
value="#{dgRefTypePubBean.itemList}"
widgetVar="itemsTable"
filteredValue="#{dgRefTypePubBean.filteredItems}" paginator="true"
rows="10"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="2,5,10,20" rowKey="#{item.EID}"
selection="#{dgRefTypePubBean.selectedItem}" selectionMode="single"
emptyMessage="#{msgs['dgreftype.datatable.message.emptyList']}"
resizableColumns="false">
<p:ajax event="page" oncomplete="itemsTable.unselectAllRows(); itemsTable.selectRow(0, false)" />
<p:ajax event="rowSelect" listener="#{dgRefTypePubBean.onRowSelect}"
update=":form:obs :form:index_info :form:elimination_just :form:left_footer :form:right_footer" />
<p:ajax event="rowUnselect" listener="#{dgRefTypePubBean.onRowUnselect}" update=":form:obs" />
<p:column style="text-align:right; width:22px; border:none; background:white">
<h:graphicImage rendered="#{item.EState==2}" library="images" name="data-delete.png" width="15" height="15" style="border:none; padding:0" />
</p:column>
<p:column id="codColumn" headerText="#{msgs['dgreftype.datatable.label.functionalCode']}" filterStyle="height:10px; font-weight:normal" style="text-align:left; width:120px" filterBy="#{item.EFunctionalCode}">
<h:outputText value="#{item.EFunctionalCode}" />
</p:column>
<p:column id="designationColumn" headerText="#{msgs['dgreftype.datatable.label.name']}" filterStyle="height:10px; font-weight:normal" style="text-align:left; word-wrap: break-word" filterBy="#{item.EName}">
<h:outputText value="#{item.EName}" />
</p:column>
<p:column id="variableColumn" headerText="#{msgs['dgreftype.datatable.label.variableTypeName']}" filterStyle="height:10px; font-weight:normal" style="text-align:left; width:200px" filterBy="#{item.EVariableTypeName}">
<h:outputText value="#{item.EVariableTypeName}" />
</p:column>
<p:column id="buttonsColumn" style="width:55px">
<h:panelGrid columns="3" style="border-collapse:separate; border:none !important">
<h:commandLink onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}, false)" action="#{dgRefTypePubBean.editSelectedItem()}">
<h:graphicImage library="images" name="edit-text.png" width="15" height="15" style="border:none" />
</h:commandLink>
<h:graphicImage library="images" name="detail-disabled.png" width="15" height="15" style="border:none" onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}, false)" />
<h:commandLink onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}, false); confirmation.show(); return false;">
<h:graphicImage library="images" name="edit-delete.png" width="15" height="15" style="border:none" />
</h:commandLink>
</h:panelGrid>
</p:column>
</p:dataTable>
I'm using JSF 2.0 and Primefaces 3.4.2.
Thanks in advance
It is possible to get the current page from the paginator with this function :
itemsTable.paginator.getCurrentPage()
So, we can calculate the correct row index from this value, the value of #{rowIndex} and the maximum number of row per page.
<h:commandLink onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}-itemsTable.paginator.getCurrentPage()*10)" action="#{dgRefTypePubBean.editSelectedItem()}">
<h:graphicImage library="images" name="edit-text.png" width="15" height="15" style="border:none" />
</h:commandLink>
I hope this help.
Regards.

Missing param using primefaces datatable with lazy loading and viewparam

So, I have a datatable like this:
<p:dataTable var="object" value="#{objectBean.objects}"
paginator="true" rows="10" editable="true" id="tableObjects"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" style="border: 0px">
<p:column sortBy="#{object.etc}">
..
</p:column>
...
<p:column sortBy="#{object.someValue}" id="sucessoColumn"
headerText="Value">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{object.someValue}" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{object.someValue}" effect="fade"
id="opt">
...
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column id="bColumn" headerText="Options">
<p:rowEditor />
</p:column>
<p:ajax event="rowEdit" listener="#{objectBean.update}"></p:ajax>
</p:dataTable>
On a page that receives a parameter like this:
<f:metadata>
<f:viewParam name="id" value="#{objectBean.object}"
converter="#{objectConverter}" converterMessage="Converter error !"
required="true" requiredMessage="Missing object !" />
</f:metadata>
When the page is loaded, there is no problem at all, and everything works fine. But when I click on next page or try editing the row, then the "required message" from the viewparam appears. It looks like that the param disappears when anything on the datatable changes.
Any ideas ?
Thank you.
The problem was with the scope of the Bean we were using.
It seems that, every time that the state of the datatable changes, it makes another request for the bean. If it was request scoped, the parameter was only available for the first request.
Changing to ViewScope solved half of the problem. The datatable worked as it should, but the message still appears. Taking of the "required" and "requiredMessage" attributes solved the last part of the problem and everything worked like a charm.
Maybe my answer is too late, but i had same problem like yours.
I will explain my solution from you piece of code.
I dont know why but when your are using lazy loading and cell editor, rowEdit function doesnt work.
<p:ajax event="rowEdit" listener="#{objectBean.update}"></p:ajax>
If you remove you cellEditor from code you will see that objectBean.update method will run.
I remove
<p:ajax event="rowEdit" listener="#{objectBean.update}"></p:ajax>
and in every cell editor i change my code to this one.
<p:column sortBy="#{object.someValue}" id="sucessoColumn" headerText="Value"> <p:cellEditor>
<f:facet name="output">
<h:outputText value="#{object.someValue}" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{object.someValue} effect="fade" id="opt">
<p:ajax event="valueChange" process="#this" listener="#{objectBean.update(object)}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
In Bean in change update method from first one to second one.
public void update(RowEditEvent event) {
Object editingRow = (Object) event.getObject();
objectService().saveOrUpdate(editingRow);
}
public void update(HospitalDoctor obj) {
objectService().saveOrUpdate(obj);
}
In this way I solved my problem, I hope it will help to others.

p:dataTable not updating after deleting row

I have searched this topic and tried all the suggestions, however I just cannot seem to get what seems to be a very simple thing to work.
I have a PrimeFaces 3.4 <p:dataTable> with data populated from a List in my backing bean and with a <p:commandLink> in one of the columns for every row. I am just trying to implement a simple delete and refresh of the data table. However although the element is removed from the List object, the data table does not refresh.
Bean (view scoped):
public void deleteRow(rowType row){
this.tableDataList.remove(row);
}
View:
<h:form id="form">
<p:dataTable id="dt" var="dt" value=#{managedBean.tableDataList}
rowKey="#{dt.id}" selection="#{managedBean.selectedRow}"
selectionMode="single">
<p:column><h:outputText value="#{dt.field1}"/></p:column>
<p:column><h:outputText value="#{dt.field2}"/></p:column>
<p:column><h:outputText value="#{dt.field3}"/></p:column>
<p:column width="60">
<p:commandLink id="deleteCl"
value="Delete"
actionListener="#{managedBean.deleteRow(dt)}"
update=":form:dt"
/>
</p:column>
</h:form>
From what I can see, a data table in PrimeFaces 3.4 should be able to be updated via a child component such as a command link, but I just can't get it to work. I have a phase listener implemented so I can see that there are no validation or other errors before the render response phase, but the data table continues to display the deleted row unless I refresh the browser window, then it will disappear.
It works if I set ajax="false" in the command link, but then the entire page is updated unnecessarily.
I have tried:
Changing between action and actionListener
Making the following changes in various combinations to the command link attributes:
process="#this"
update="#this"
update="#form"
The annoying thing is that I have a similar table with a command link where each link opens up a dialog window containing another data table that is populated with data retrieved based upon the row that was initially clicked. Works perfectly on the same page. Agh!
Try modeling some points from this to see if it helps you.
<h:outputText escape="false" value="#{message.noCompaniesFound}" rendered="#{companyController.companyModel.rowCount == 0}"/>
<h:panelGroup rendered="#{companyController.companyModel.rowCount > 0}">
<p:commandButton id="addButton" value="#{message.newCompany}" oncomplete="companyDialog.show()" icon="ui-icon-plus" title="#{message.addCompany}" rendered="#{loginController.privileges.contains(bundle.SuperUser)}"/>
<p:dataTable id="companyList" var="company" widgetVar="companyTable" value="#{companyController.companyModel}" rowKey="#{company.name}" selection="#{companyController.selectedCompany}" selectionMode="single"
paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,20,50,100">
<p:ajax event="rowEdit" update="#this" listener="#{companyController.saveCompany(company)}">
<f:param name="company" value="#{company}"/>
</p:ajax>
<f:facet name="header">
<p:outputPanel>
<h:outputText value="#{message.search}: "/>
<p:inputText id="globalFilter" onkeyup="companyTable.filter()"/>
</p:outputPanel>
</f:facet>
<p:column id="name" headerText="#{message.name}" filterBy="#{company.name}" filterMatchMode="contains" filterStyle="display: none;">
<h:outputText value="#{company.name}"/>
</p:column>
<p:column headerText="#{message.editOptions}" style="width:10px;">
<p:commandButton id="editButton" update=":companyForm" oncomplete="editDialog.show()" icon="ui-icon-pencil" title="#{message.edit}">
<f:setPropertyActionListener value="#{company}" target="#{companyController.selectedCompany}"/>
</p:commandButton>
<p:commandButton id="deleteButton" update=":companyForm" oncomplete="confirmation.show()" icon="ui-icon-trash" title="#{message.delete}">
<f:setPropertyActionListener value="#{company}" target="#{companyController.selectedCompany}"/>
</p:commandButton>
</p:column>
<f:facet name="footer">
</f:facet>
</p:dataTable>
</h:panelGroup>
<p:confirmDialog id="confirmDialog" message="#{message.sureYouWantToDelete} #{companyController.selectedCompany.name} ?" severity="alert" widgetVar="confirmation">
<p:commandButton id="confirm" value="#{message.yes}" onclick="confirmation.hide()" actionListener="#{companyController.deleteCompany}" update="companyForm" />
<p:commandButton id="decline" value="#{message.no}" onclick="confirmation.hide()"/>
</p:confirmDialog>

Resources