I have a datatable in my primefaces application . The code for the frontend has
<!-- Start of customer datatable -->
<p:dataTable var="customer" value="#{customerBean.customers}" paginator="true" selection="#{customerBean.selectedCustomer}"
selectionMode="single" onRowSelectUpdate=":custList" onRowSelectComplete="custTab.show()" id="custList" widgetVar="custList" update=":custList">
<f:facet name="header">
List of Customers
<p:outputPanel>
<p:commandButton value="+" type="button" onclick="addCustDlg.show()"/>
</p:outputPanel>
</f:facet>
<p:column sortBy="#{customer.id}" filterBy="#{customer.id}" update=":custList">
<f:facet name="header">
<h:outputText value="ID"/>
</f:facet>
<h:outputText value="#{customer.id}"/>
</p:column>
<p:column sortBy="#{customer.name}" filterBy="#{customer.name}" headerText="NAME" filterMatchMode="contains" update=":custList">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{customer.description}" filterBy="#{customer.description}" headerText="DESCRIPTION">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.description}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.description}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{customer.signupDate}" filterBy="#{customer.signupDate}" headerText="SIGN UP DATE">
<f:facet name="output">
<h:outputText value="#{customer.signupDate}"/>
</f:facet>
</p:column>
<p:column sortBy="#{customer.validUntil}" filterBy="#{customer.validUntil}" headerText="EXPIRY DATE">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.validUntil}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.validUntil}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column sortBy="#{customer.status}" filterBy="#{customer.status}" headerText="STATUS">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{customer.status}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{customer.status}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="CREATION DATE" sortBy="#{customer.creationDate}" filterBy="#{customer.creationDate}">
<f:facet name="output">
<h:outputText value="#{customer.creationDate}"/>
</f:facet>
</p:column>
<p:column headerText="LAST UPDATE DATE" sortBy="#{customer.lastUpdateDate}" filterBy="#{customer.lastUpdateDate}">
<f:facet name="output">
<h:outputText value="#{customer.lastUpdateDate}"/>
</f:facet>
</p:column>
<p:column headerText="Options">
<p:rowEditor/>
</p:column>
</p:dataTable>
<!-- End of dataTable (customer datatable) -->
And the function for handling the rowEvent is specified in the bean as
public void custRowEdit(RowEditEvent event){
Customer cust = (Customer) event.getObject();
EntityManagerHelper.beginTransaction();
custDao.update(cust);
EntityManagerHelper.commit();
}
However , on an update event , when I am editing the cell in the table , I do not get the new updated value of the attribute .
Like in the image below , when I edit the status of the entry with ID 1 from 11 to 4 , in the function custRowEdit , when I try to get the customer object , I still get the status of the customer as 11 and not 4 .
Can anyone help me with understanding why the value of the cell is not being set ?
from Where You are invoking custRowEdit(RowEditEvent event) method. I have not any related thing in your code.
In order to make your listener invoke add below attribute in your datatable declaration.
rowEditListener="#{customerBean.listenerInBackingBean}"
<p:dataTable var="customer" value="#{customerBean.customers}" paginator="true" selection="#{customerBean.selectedCustomer}"
selectionMode="single" onRowSelectUpdate=":custList" onRowSelectComplete="custTab.show()" id="custList" widgetVar="custList" update=":custList">
<f:facet name="header"
rowEditListener="#{customerBean.cutRowEvent}"
>
Check the implementation of customerBean.customers. I reloaded the content from the database every time the method got called. Wrong. This should happen in the constructor instead. Now everything works fine. Thought it was a JavaScript error ...
Thanks this helped me.
May I add that instead of loading the list from a query in the constructor, if one has a #SessionScoped managed bean one can instead use a reset() method to reset lists to null and then lazily populate the lists from the query. The reset can then be called on page load using an f:event:
<f:view>
<f:metadata>
<f:event type="preRenderView" listener="#{sessionScopedBean.reset}"/>
</f:metadata>
</f:view>
I encountered a similar situation that was resolved by removing the update="" tag from the dataTable. The table's default behavior is to update the row, which evidently, in my case, was not occurring.
You are missin the p:ajax event to trigger the method, function or whatever you wanna do after the cell editing
it's something like
<p:ajax event="cellEdit" listener="#{mBean.onCellEdit}" update="elementX" />
Related
I have a requirement for an editable datatable that has a single column, lets say brand, that when set to "Other" will replace the editor in the next column, model - with an inputText rather than a selectOne. If any particular car brand is selected then the list of models for that brand is displayed. If "Other" is chosen then they can type in a model in an input text field. I can't seem to get the mechanics of this to work in primefaces using various combinations of rendered and events. Is this sort of inline switching of editing components based on the data in the row possible? I've built a simple example using the primefaces datatable demo for cars (and adding a field Model) to illustrate what I am attempting.
Page snippet
<p:dataTable id="cars1" var="car" value="#{dtEditView.cars1}"
editable="true" style="margin-bottom:20px">
<f:facet name="header">
Row Editing
</f:facet>
<p:ajax event="rowEdit" listener="#{dtEditView.onRowEdit}"
update="cars1" />
<p:ajax event="rowEditCancel" listener="#{dtEditView.onRowCancel}"
update="cars1" />
<p:column headerText="Id">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.id}" />
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput" value="#{car.id}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Year">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.year}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{car.year}" style="width:100%" label="Year" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Brand">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.brand}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{car.brand}" style="width:100%">
<f:selectItems value="#{dtEditView.brands}" var="man"
itemLabel="#{man}" itemValue="#{man}" />
<p:ajax event="change" immediate="true" update="model model_ti"></p:ajax>
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Model">
<p:cellEditor rendered="#{car.brand != 'Other'}">
<f:facet name="output">
<h:outputText value="#{car.model}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{car.model}" style="width:100%"
id="model">
<f:selectItems value="#{dtEditView.getModels(car.brand)}"
var="man" itemLabel="#{man}" itemValue="#{man}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
<p:cellEditor rendered="#{car.brand == 'Other'}">
<f:facet name="output">
<h:outputText value="#{car.model}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{car.model}" style="width:100%"
id="model_ti" />
</f:facet>
</p:cellEditor>
</p:column>
Thanks!
I was able to solve this problem by putting an ID on the cell editor for model, and adding that to the update list when changing brand.
I've a scenario Like i'll use cell Edit in Data Table.
I've two cells
I've 1st Cell is Editable
2nd Cell Value needs to be Displayed by doing some arithmetic operations on 1st Cell input (Eg: 2nd cell value =(1st cell value)*.14
My Code is Like
<p:dataTable id="cars2" var="car" value="#{dtEditView.cars2}" editable="true" editMode="cell" widgetVar="cellCars">.
<p:ajax event="cellEdit" listener="#{dtEditView.onCellEdit}" update=":form:msgs" />
<p:column headerText="Cell 1">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{car.id}" /></f:facet>
<f:facet name="input"><p:inputText id="modelInput" value="#{car.id}" style="width:96%"/>
<p:ajax event="keyup" listener="#{car.yearupdate}" update="2:3"></p:ajax></f:facet>
</p:cellEditor>
</p:column>
<p:column id="2" headerText="Cell 2">
<f:facet name="output"><h:outputText id="3" value="#{car.year}" /></f:facet>
</p:column>
</p:dataTable>
I want to Know the Java Code for Listener method code to update the 2nd cell value
In xhtml we need to call the listener (p:ajax tag).
in bean update the other column data in bulk ( iterate over all search records and update corressponding valuefor all recs ) ..
xhtml code like
<p:dataTable id="listDetails" value="${managedBean.searchList}" var="row">
<p:ajax event="rowEdit" listener="#{managedBean.onRowEdit}"
update=":managedBean:messages" />
<p:ajax event="rowEditCancel" listener="#{managedBean.onRowCancel}" update=":managedBean:messages" />
<p:column priority="17"
headerText="col 1"
styleClass="wrap text-right" style="width: 140px;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{row.val1}" />
</f:facet>
<f:facet name="input">
<p:inputText id="modelInput" value="#{row.val1}"
<p:ajax event="blur" listener="#{managed.valueUpdate}"
update="tempValue></p:ajax>
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<p:column priority="2" headerText="Col 2" exportable="true">
<p:cellEditor>
<f:facet name="output">
<h:outputText id="value" value="#{row.value}" />
</f:facet>
<f:facet name="input">
<h:outputText id="tempValue" value="#{row.tempValue}" />
</f:facet>
</p:cellEditor>
</p:column>
in Bean
public void valueUpdate(){
for (BO bo : searchList) {
if(bo.val1!=null)
{
bo.value = bo.val1+50; // here u can do calc and assihn to the
bo.tempValue=bo.value;
}
}
}
I need to create a table where the headers list are brought from a model. The table contents are also stored in the model and p:dataTable loop on the data to show the content based on the column name.
The issue is that I need to make some specific cells editable. For outputting data there is no problem since I use model method which takes both the entity and the column name and return the correct info from the entity based on the column name. The issue is with inputs of the editable cells which I don't know how to set in the entity.
<p:dataTable id="processTable" var="entity" value="#{home.process.headerEntities}" tableStyle="width:auto" draggableColumns="true" editable="true" editMode="cell">
<p:columns value="#{home.process.columns}" var="columnHead" >
<f:facet name="header">
<h:outputText value="#{columnHead}"/>
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{home.process.getData(entity, columnHead)}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{home.process.getData(entity, columnHead)}" rendered="#{home.process.isEditable(columnHead)}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:columns>
</p:dataTable>
After change based on BEST ANSWER
<p:dataTable id="processTable" var="entity" value="#{home.process.headerEntities}" tableStyle="width:auto" draggableColumns="true" editable="true" editMode="cell">
<p:columns value="#{home.process.columns}" var="columnHead" >
<f:facet name="header">
<h:outputText value="#{columnHead}"/>
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{entity[home.process.columnPropertyMap[columnHead]]}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{entity[home.process.columnPropertyMap[columnHead]]}" rendered="#{home.process.isEditable(columnHead)}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:columns>
</p:dataTable>
The input component's value must be bound to a writable value expression. What you've there is a direct getter method invocation and thus essentially read-only. This is indeed not going to work. You need to specify a property name of the #{entity}. You can use the brace notation to specify the property name as a variable like so #{entity[propertyName]}.
So, basically:
<p:dataTable value="#{bean.entities}" var="entity" editable="true" editMode="cell">
<p:columns value="#{bean.propertyNames}" var="propertyNames">
<p:cellEditor>
<f:facet name="output">
#{entity[propertyName]}
</f:facet>
<f:facet name="input">
<p:inputText value="#{entity[propertyName]}" />
</f:facet>
</p:cellEditor>
</p:columns>
</p:dataTable>
As to the column header, rather refactor out that into a Map<String, String> where the key is the propertyName and the value is the header.
<f:facet name="header">
#{bean.columnHeaders[propertyName]}
</f:facet name="header">
Or better yet, use a normal i18n resource bundle for that where the propertyName represents part of the bundle key.
<f:facet name="header">
#{bundle['table.column.header.' += propertyName]}
</f:facet name="header">
As to the editable check, rather wrap propertyName and editable in another bean (and perhaps also columnHeader if you don't want to use a i18n bundle), e.g. Field and then use like below:
<p:columns value="#{bean.fields}" var="field">
<p:cellEditor>
<f:facet name="output">
#{entity[field.propertyName]}
</f:facet>
<f:facet name="input">
<p:inputText value="#{entity[field.propertyName]}" rendered="#{entity[field.editable]}" />
</f:facet>
</p:cellEditor>
</p:columns>
All in all, it just boils down to preparing and providing the right model the view expects. This way the getData() thing isn't necessary.
My web page looks like this:
<h:form>
<p:dataTable var="car" value="#{tableBean.carsSmall}">
<f:facet name="header">
Expand rows to see detailed information
</f:facet>
<p:column style="width:16px">
<p:rowToggler />
</p:column>
<p:column style="width:250px">
<f:facet name="header">
Model
</f:facet>
<h:outputText value="#{car.model}" />
</p:column>
<p:column style="width:250px">
<f:facet name="header">
Year
</f:facet>
<h:outputText value="#{car.year}" />
</p:column>
<p:rowExpansion>
<p:fieldset legend="Detail">
<p:dataTable value="#{car.colors}" var="color">
<p:column>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{color.disable}" />
</f:facet>
<f:facet name="input">
<h:selectBooleanCheckbox value="#{color.disable}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:fieldset>
</p:rowExpansion>
</p:dataTable>
</h:form>
This component is automatically updating the wrong values in database, for example it is setting false for the color.disable property upon just expanding the row.
I am using:
JSF 2.0.9
Primefaces 2.2.1
I am working on a sample app with primefaces 3 , using datatables incell editing mode. Although when i edit , i see the event.getObjects gives me the object which is not modified.
Changed the property of the object on debug mode, it does update.
So i couldn't figure out why i cant get the edited property.
Below are my eventlistener method and the xhtml;
Any pointers are welcomed
Thanks in advance
EventListener
public void editListener(RowEditEvent event){
System.out.println("EDIT LISTENER");
update((Employer)event.getObject());
}
JSF :
<h:form id="form">
<h1><h:outputText value="List"/></h1>
<p:dataTable value="#{employer.employers}" var="item" paginator="true" rows="10" style="width:300px">
<p:column>
<f:facet name="header">
<h:outputText value="Id"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{item.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{item.name}"></p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Surname"/>
</f:facet>
<h:outputText value="#{item.surname}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Phone"/>
</f:facet>
<h:outputText value="#{item.phone}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{item.email}"/>
</p:column>
<p:column headerText="Options" style="width:50px">
<p:rowEditor />
</p:column>
<p:ajax event="rowEdit" listener="#{employer.editListener}"></p:ajax>
</p:dataTable>
</h:form>
After this...
<p:dataTable value="#{employer.employers}" var="item" paginator="true"
rows="10" style="width:300px">
...put the following:
<p:ajax event="rowEdit" update="#this" listener="#{HandlerClassName.rowEditListener}" />