Missing param using primefaces datatable with lazy loading and viewparam - jsf-2

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.

Related

Datatable cellEditor functionality in forEach generated Datatable

I am trying to generate a editable datatable dynamically dependend on the resultset of an previously executed SQL-Query.
Depending on which columns would have a constant value I am trying to not render them. That part of the code works just fine, everything is displayed as i would like it to be.
My issues are with the cellEditor. I generate my datable as follows:
<p:dataTable ajax="true" var="mBT" value="#{stammdaten.bbvList}" id="meldeBearbeitungsTable" editable="true" editMode="cell" scrollable="true" scrollHeight="400" style="width:600px">
<p:ajax event="cellEdit" listener="#{stammdaten.onCellEdit}" update=":Mb:message"/>
<c:forEach var="column" items="#{stammdaten.columns}">
<p:column headerText="#{column.header}">
<f:attribute name="myCol" value="#{column}" />
<span>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{mBT[column.property]}"></h:outputText>
</f:facet>
<f:facet name="input">
<p:inputText value="#{mBT[column.property]}">
<p:keyFilter regEx="/[0-9]/i"/>
</p:inputText>
</f:facet>
</p:cellEditor>
</span>
</p:column>
</c:forEach>
</p:dataTable>
bbvList is a List of beans with different values.
columns is a List of beans to identify the header-Texts coresponding to the respective variables.
So now the issue itself:
This is how the cellEditor looks like when i click on it:
Issue-Picture
So in that example i tried to edit the field with the value "8" in it. onCellEdit gets triggered (a System.out.println is getting printed on the console) but i cant actually change the value in the respective field.
Does have cellEdit issues with the forEach initialisition of the dataTable? If yes is there a way to fix it? Else what am i doing wrong?
Since only a specific component of the html-side of code isnt working as it should be i won't post unnecessary java-Code for now. If needed i will add that as well.
Hope someone can help :)
Turns out the attribute and/or span where the cause of the problem. Simply removing them solved the issue with the cellEdit.
following works fine :
<p:dataTable ajax="true" var="mBT" value="#{stammdaten.bbvList}" id="meldeBearbeitungsTable" editable="true" editMode="cell" scrollable="true" scrollHeight="400" style="width:600px">
<p:ajax event="cellEdit" listener="#{stammdaten.onCellEdit}" update=":Mb:message"/>
<c:forEach var="column" items="#{stammdaten.columns}">
<p:column headerText="#{column.header}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{mBT[column.property]}"></h:outputText>
</f:facet>
<f:facet name="input">
<p:inputText value="#{mBT[column.property]}">
<p:keyFilter regEx="/[0-9]/i"/>
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
</c:forEach>
</p:dataTable>

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();"

Jsf2 - Richfaces4 - Data scroller actionListener not called with datatable

To make it short, in a jsf page, I have 2 rich:dataTable.
The first one is loaded within the onLoad event of the page.
The second one is loaded when a row is clicked within the first.
Both tables have a rich:dataScroller.
Everything is working fine except that I don't find how to make working the actionListener of the dataScroller.
Schematically I have
<rich:collapsiblePanel>
<h:form>
<h:panelGroup id="table1">
<rich:dataTable>
<f:facet name="header">
</f:facet>
<rich:column>
</rich:column>
<f:facet name="footer">
<rich:dataScroller reRender="table1,table2" page="1" actionListener="#{mybean.ac}"/>
</f:facet>
</rich:dataTable>
</h:panelGroup>
<h:panelGroup id="table2">
<rich:dataTable rendered="#{myBean.rowSelected != null}">
<f:facet name="header">
</f:facet>
<rich:column>
</rich:column>
<f:facet name="footer">
<rich:dataScroller reRender="table1" page="1" />
</f:facet>
</rich:dataTable>
</h:panelGroup>
</h:form>
</rich:collapsiblePanel>
In my bean I have
Long rowSelected;
public void ac()
{
rowSelected = null;
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxx");
}
But nothing to do, never succeeded to make it work.
I also tried without any différence
public void ac(ActionEvent ae) - using javax.faces.event.ActionEvent
and
action="#{mybean.ac}"
<rich:dataScroller> has neither action nor actionListener attributes. If you're using RichFaces 4.3 you can use scrollListener. See the docs.

When to use :(colon) in rendering in jsf components

i have read that, we should use :(colon) to render components in other form. but in my case
<h:form id="form">
<p:growl id="messages"></p:growl>
<p:dataTable var="e" value="#{employees.eList}" id="elist1"
editable="true">
<f:facet name="header">
In-Cell Editing
</f:facet>
<p:ajax event="rowEdit" listener="#{employees.onEdit}" update=":form:messages"/>
<p:ajax event="rowEditCancel" listener="#{employees.onCancel}" />
<p:column headerText="name" style="width:30%">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{e.name}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{e.name}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
.......... ...........
</p:datatable>
i want to update messages(growl) from datatable component why i have to use colon update=":form:messages"
All relative client IDs (the ones not starting with :) are searched relative to the parent component which implements the NamingContainer interface. As you can see in the linked javadoc, that are at least all UIForm and UIData components. The <h:form> is such one. The <p:dataTable> is another one.
In your particular case, the <p:ajax> is enclosed in <p:dataTable>. So, the <p:ajax update="messages"> would look for a child component with ID messages inside the context of <p:dataTable>. However, since there is none, it won't find anything. You actually need to use an absolute client ID instead because it's outside the context of the current NamingContainer parent.
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"

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