I have a problem with primefaces datatable. I'm getting the data from my database and it's saved in a list. That's works great! But the datatable just displays one column instead of four and this column is copied in every row.
<h:form id="userslistform">
<p:dataTable id="userlist" var="users" value="#{userBean.usersList}"
rowKey="#{userBean.username}">
<p:column headerText="ID">
<h:outputText value="#{userBean.id}" />
</p:column>
<p:column headerText="Username">
<h:outputText value="#{userBean.username}" />
</p:column>
<p:column headerText="Firstname">
<h:outputText value="#{userBean.firstname}" />
</p:column>
<p:column headerText="Surname">
<h:outputText value="#{userBean.surname}" />
</p:column>
</p:dataTable>
</h:form>
Bean:
#Named
#SessionScoped
#ManagedBean(name = "userBean")
public class UserBean implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private String password;
private String firstname;
private String surname;
private Long id;
private String email;
private Long treeId;
private Boolean isadmin;
private List<User> usersList;
private User selectedUser;
private UserDataQuery query = new UserDataQuery();
//getter and setters of every attribute
...
#PostConstruct
public void init() {
usersList = query.getAllUsers();
}
}
DAO:
public class UserDataQuery {
private EntityManagerFactory enf;
private EntityManager em;
public UserDataQuery() {
enf = Persistence.createEntityManagerFactory("xxxx");
em = enf.createEntityManager();
em.getTransaction().begin();
}
public List<User> getAllUsers() {
List<User> usersList = em.createNamedQuery("User.findAll", User.class)
.getResultList();
return usersList;
}
...
}
You need to use value from var inside your table, to display the data
<h:form id="userslistform">
<p:dataTable id="userlist" var="users" value="#{userBean.usersList}"
rowKey="#{userBean.username}">
<p:column headerText="ID">
<h:outputText value="#{users.id}" />
</p:column>
<p:column headerText="Username">
<h:outputText value="#{users.username}" />
</p:column>
<p:column headerText="Firstname">
<h:outputText value="#{users.firstname}" />
</p:column>
<p:column headerText="Surname">
<h:outputText value="#{users.surname}" />
</p:column>
</p:dataTable>
</h:form>
var value represents a reference to current row, at the time the table is rendered. With #{userBean.<attribute>} you were always displaying values that were fixed. And, now you don't need those attributes in the bean itself, just the list (unless, of course, you need them for another purpose).
Related
With a PrimeFaces dataTable I try to edit a row. But when I click on the 'Save Row' button, the old value is send to the bean.
I tried to copy the database object to a normal pojo, but still the old value is send to the bean.
I use PrimeFaces 12
XHTML:
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<div class="container-fluid">
<h1><h:outputText value="#{txt['rider.title']}"/></h1>
<p:dataTable id="dt_riders" class="table table-striped" value="#{riderView.allRiders}"
var="rider" editable="true">
<p:ajax event="rowEdit" listener="#{riderView.onRowEdit}" update=":form:msgs"/>
<p:ajax event="rowEditCancel" listener="#{riderView.onRowCancel}" update=":form:msgs"/>
<p:column headerText="#{txt['rider.header.id']}">
<h:outputText value="#{rider.id}"/>
</p:column>
<p:column headerText="#{txt['rider.header.name']}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{rider.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="nameInp" value="#{rider.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<!-- and a few more -->
<p:column>
<p:rowEditor editTitle="Edit Row" cancelTitle="Cancel Edit" saveTitle="Save Row"/>
</p:column>
</p:dataTable>
</div>
</h:form>
The bean:
#ViewScoped
#Named("riderView")
public class RiderView implements Serializable {
private final RiderEjb riderEjb;
private final SecurityOfficer securityOfficer;
public RiderView() {
this(null, null);
}
#Inject
public RiderView(RiderEjb riderEjb, SecurityOfficer securityOfficer) {
this.riderEjb = riderEjb;
this.securityOfficer = securityOfficer;
}
public List<Rider> getAllRiders() {
return riderEjb.findAll(securityOfficer.getTeam());
}
public void onRowEdit(RowEditEvent<Rider> event) {
FacesMessage msg = new FacesMessage("Rider Edited", String.valueOf(event.getObject().getName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
riderEjb.addOrUpdate(event.getObject());
}
public void onRowCancel(RowEditEvent<Rider> event) {
FacesMessage msg = new FacesMessage("Edit Cancelled", String.valueOf(event.getObject().getName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
The Java object (getters and setters are generated by Lombok):
#Entity
#Getter
#Setter
public class Rider extends AbstractEntity {
#Id
private Long id;
private String name;
private Double weight;
private String gpxNames;
}
The problem was the method getAllRiders(). That calls the bean to gather the riders from the database. I changed it to retrieve all those riders from the database in a new #PostConstruct init() method.
Thanks to Jasper de Vries, I used the primefaces-test to pinpoint the problem.
I have a problem with using the setCommand() on a DefaultMenuItem in a p:megaMenu.
I want that when I click on an item in buttonTables.jsf the function afficherTable() will be excuted and redirect me to affichageTable.jsf. The problem is when I run the project my megaMenu filled, and when I click on an item, it redirect me to the other page, but the fuction afficherTable() passed in setCommand does not run. So my datatable in the other page is empty. In the console of eclipse I don't have any error. Thank you.
My bean:
public class MonBean implements Serializable{
private static final long serialVersionUID = -5773011533863117274L;
private GestionTableImpl gestionTable;
private Table table;
private List<Colonne> columns;
private DefaultMenuModel megaModel;
public void afficherTable(ActionEvent event){
MenuItem menuItem = ((MenuActionEvent) event).getMenuItem();
String nTable = menuItem.getParams().get("tableNom").get(0);
gestionTable=new GestionTableImpl();
columns=new ArrayList<Colonne>();
columns=gestionTable.afficherTable(nTable);
}
public DefaultMenuModel listTablesMenu() {
gestionTable=new GestionTableImpl();
List<Table> mesTables=gestionTable.getTables();
megaModel = new DefaultMenuModel();
DefaultSubMenu firstSubmenu = new DefaultSubMenu("Tables");
for(int i=0;i< mesTables.size();i++){
String tableNom=mesTables.get(i).getNomTable();
DefaultMenuItem item= new DefaultMenuItem(tableNom);
item.setUrl("//AffichageTable.jsf");
item.setIcon("ui-icon-document-b");
item.setParam("tableNom",item.getValue());
item.setCommand("#{monBean.afficherTable}");
firstSubmenu.addElement(item);
megaModel.addElement(firstSubmenu);
}
return megaModel;
}
//getters and setters
public static long getSerialversionuid() {
return serialVersionUID;
}
public void setModel(DynaFormModel model) {
this.model = model;
}
public Table getTable() {
return table;
}
public void setTable(Table table) {
this.table = table;
}
public List<Colonne> getColumns() {
return columns;
}
public void setColumns(List<Colonne> columns) {
this.columns = columns;
}
public GestionTableImpl getGestionTable() {
return gestionTable;
}
public void setGestionTable(GestionTableImpl gestionTable) {
this.gestionTable = gestionTable;
}
public DefaultMenuModel getMegaModel() {
return megaModel;
}
public void setMegaModel(DefaultMenuModel megaModel) {
this.megaModel = megaModel;
}
}
This is buttonTables.jsf
<body>
<p:megaMenu autoDisplay="false" styleClass="menu-bar" style="">
<p:submenu label="Maintenance Services" icon="ui-icon-check">
<p:column>
<p:scrollPanel style="height:200px;width:250px" mode="native">
<p:menu model="#{monBean.listTablesMenu()}" />
</p:scrollPanel>
</p:column>
</p:submenu>
</p:megaMenu>
</body>
This is AffichageTable.jsf
<h:form>
<p:outputLabel value="#{monBean.table.nomTable}"/>
<p:dataTable id="tbl" var="col" value="#{monBean.columns}"
paginator="true" rows="5" style="margin-bottom:20px">
<p:column>
<f:facet name="header">
<h:outputText value="Nom colonne" />
</f:facet>
<h:outputText value="#{col.nomColonne}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Type colonne" />
</f:facet>
<h:outputText value="#{col.typeColonne}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText />
</f:facet>
<p:commandButton icon="ui-icon-pencil" />
<p:commandButton icon="ui-icon-trash" />
</p:column>
</p:dataTable>
</h:form>
I had exact the same issue. I made it work by not combining setCommand and setUrl. When I use setUrl, setCommand is not triggered, but everything else gets executed. This is not clear from the primefaces user guide...
What you can do is use the method in you command to retun the xhtml that you want to redirect something like this:
public String afficherTable(){
MenuItem menuItem = ((MenuActionEvent) event).getMenuItem();
String nTable = menuItem.getParams().get("tableNom").get(0);
gestionTable=new GestionTableImpl();
columns=new ArrayList<Colonne>();
columns=gestionTable.afficherTable(nTable);
return "/AffichageTable.jsf"
}
Can I use radio button to select a single row then edit some of data on that row then use
commandButton to submit what I edit it in that row. I'm trying to edit username cell for now as test.
this a snap of my code:
Xadmin.xhtml
<h:form id="form" enctype="multipart/form-data">
<p:growl id="msgs" showDetail="true" />
<p:dataTable id="DT" value="#{Jadmin.messages}"
var="o"
selection="#{Jadmin.selectedUser}"
rowKey="#{o.id}"
style="margin-bottom:20px">
<f:facet name="header">
Users List
</f:facet>
<p:column selectionMode="single" />
<p:column>
<f:facet name="header">
<h:outputText value="id" />
</f:facet>
<h:outputText value="#{o.id}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="username" />
</f:facet>
<p:inputText value="#{o.username}" />
</p:column>
<f:facet name="footer">
<h:commandButton value="Update" action="#{Jadmin.update}" />
<p:commandButton value="Delete"
action="#{Jadmin.delete}"
ajax="false"
update=":form:msgs"/>
</f:facet>
</p:dataTable>
JadminBeans.java
#ManagedBean(name = "Jadmin")
#SessionScoped
public class JadminBeans implements Serializable {
private static final long serialVersionUID = 1L;
private JadminController selectedUser;
List<JadminController> userslist = new ArrayList<JadminController>();
public List<JadminController> getMessages() {
System.out.println("List<JadminController> getMessages()");
userslist = JadminDAO.getAllUsers();
return userslist;
}
public void delete() {
//System.out.println(usr);
//System.out.println(itemList.remove(item)+"!!");
System.out.println("JadminBeans >> delete() ---------- id= ");
JadminDAO.deleteUser(selectedUser);
}
public JadminController getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(JadminController selectedUser) {
this.selectedUser = selectedUser;
}
public void update() {
//o=(JadminBeans) objct;
JadminDAO.updateUser(selectedUser);
}
}
JadminDAO.java
public static void deleteUser(JadminController user) {
try {
PreparedStatement preparedStatement = connection.prepareStatement("delete from users where id=?");
// Parameters start with 1
preparedStatement.setLong(1, user.getId());
preparedStatement.executeUpdate();
System.out.println("JadminDAO >> deleteUser ----------");
} catch (SQLException e) {
System.out.println("JadminDAO >> deleteUser----------- SQLException :(");
e.printStackTrace();
}
}
public static void updateUser(JadminController user) {
try {
PreparedStatement preparedStatement = connection.prepareStatement("update users username=?, password=?, permission=? where username=?");
// Parameters start with 1
//System.out.println(new java.sql.Date(user.getRegisteredon().getTime()));
preparedStatement.setString(1, user.getUsername());
preparedStatement.setString(2, user.getPassword());
preparedStatement.setString(3, user.getPermission());
//preparedStatement.setDate(3, new java.sql.Date(user.getRegisteredon().getTime()));
preparedStatement.setString(4, user.getUsername());
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
JadminController.java
public class JadminController implements Serializable {
private static final long serialVersionUID = 1L;
private String username, password, permission;
private long id;
// Getters and setters.
}
If you use Editable Datatable you don't need any command button to submit what you've edited.
As shown in the same link, inside in datatable is usually used a selectOneMenu instead of radioButton for making choices.
To use input element inside your datatable don't forget to put <f:facet name="output"></f:facet> and <f:facet name="input"></f:facet>
I hope it helps.
Im trying to send data from one jsf page to another, but without success.
firstPage.xhtml
<h:form>
<p:dataTable id="dataList" value="#{firstBean.dataList}" var="data">
<p:column>
<f:facet name="header">Column 1</f:facet>
#{data.column1.id}
</p:column>
<p:column>
<f:facet name="header" >Column 2</f:facet>
#{data.colum2.name}
</p:column>
<p:column>
<f:facet name="header" >Detail Row</f:facet>
<!-- I need this button send me to another page where i will detail information about an certain id -->
<h:commandButton value="Detalhar" action="#{firstBean.someMethod}">
<f:param name="dataId" value="#{data.column1.id}"/>
</h:commandButton>
</p:column>
</p:dataTable>
</h:form>
First Bean
#ManagedBean
#ViewScoped
public class FirstBean implements Serializable{
private static final long serialVersionUID = 1L;
//list with some data
private List<Data> dataList; //getter setter
#EJB
MyDataManager manager;
#PostConstruct
public void init() {
dataList = manager.getDataList();
}
public void someMethod() throws IOException {
//do something
FacesContext.getCurrentInstance().getExternalContext().redirect("secondPage.xhtml");
}
}
secondPage.xhtml
<h:body>
<f:metadata>
<f:viewParam name="dataId" value="#{secondBean.dataDetailId}" />
<f:viewAction action="#{secondBean.init}" />
</f:metadata>
<p:dataTable value="#{secondBean.dataDetailList}" var="dataDetail">
<p:column>
<f:facet name="header">Data Detail 1</f:facet>
#{dataDetail.data1}
</p:column>
<p:column>
<f:facet name="header">Data Detail 2</f:facet>
#{dataDetail.data2}
</p:column>
<p:column>
<f:facet name="header">Data Detail 3</f:facet>
#{dataDetail.data3}
</p:column>
</p:dataTable>
</h:body>
Second Bean
#ManagedBean
#ViewScoped
public class CarteiraDetalheBean implements Serializable{
private static final long serialVersionUID = 1L;
private Integer dataId; //getter setter
private List<DataDetail> dataDetailList; //getter setter
#EJB
MyDataManager manager;
#PostConstruct
public void init() {
dataDetailList = manager.getDataDetail(dataId);
}
}
When i use:
<f:viewAction action="#{secondBean.init}" />
I gotthe message: The metadata component needs to be nested within a f:metadata tag. Suggestion: enclose the necessary components within
and when i use:
<f:event type="preRenderView" listener="#{secondBean.init()}" />
i got a null pointer exception in line:
dataDetailList = manager.getDataDetail(dataId);
What im doing wrong?
I'm using a datatable with a roweditor, my code is more or less the same as the code on the showcase example on the primefaces website but for some reason, the values are not updated.
Also when I click on the pencil to edit, the current value is not showing up in the editing cell.
Here's my code:
xhtml:
<h:form id="updateform">
<p:dataTable id="updatetable" value="#{EditingBean.row}" var="column"
editable="true"
style="width: 780px; overflow-x: auto; white-space: normal;">
<f:facet name="header">TEST</f:facet>
<p:column rendered="#{column.display}" style="white-space: normal;">
<h:outputText value="#{column.alias}" />
</p:column>
<p:column rendered="#{column.display}" style="white-space: normal;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{column.value}" />
</f:facet>
<f:facet name="input">
<p:inputText value="{#column.value}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column rendered="#{column.display}" style="white-space: normal;">
<p:rowEditor rendered="#{column.modify}" />
</p:column>
</p:dataTable>
</h:form>
EditingBean:
#ManagedBean(name = "EditingBean")
#ViewScoped
public class EditingBean implements Serializable {
private static final long serialVersionUID = -772702647887310138L;
private List<Result> row;
public List<Result> getRow() {
return row;
}
public void setRow(List<Result> row) {
this.row = row;
}
}
Result:
public class Result implements Serializable {
private static final long serialVersionUID = 1L;
private String alias;
private String name;
private String value;
private String modify;
private String display;
// getters + setters
You have a typo in the code, change {#column.value} to #{column.value}.