I have a primefaces datatable
where the commandButton's action addItem
within the columns header
facet always fires the CDI @ViewScoped
beans @PostConstruct
method, while the commandButton's action editItem
from the column does not?!
Curiously enough this happens only, if the action methods return a non-null string?! Means, if both methods return null
, the @PostConstruct
method is not called, but I use a non-null string, because clicking the buttons should show a new @ViewScoped
page.
The main problem in my real application is, that I do some initialization stuff within @PostConstruct
, which should really happen only once during page construction!
datatable.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
<p:messages autoUpdate="true" showDetail="true"/>
<h:outputLabel value="Datatable Test"/>
<h:form>
<p:dataTable var="item" value="#{datatableBean.items}">
<p:column>
<f:facet name="header">
<p:commandButton value="Add Item" action="#{datatableBean.editItem(null)}"/>
</f:facet>
<p:commandButton value="Edit Item" action="#{datatableBean.editItem(item)}"/>
</p:column>
<p:column headerText="Id">
<p:outputLabel value="#{item.id}"/>
</p:column>
<p:column headerText="Name">
<p:outputLabel value="#{item.name}"/>
</p:column>
</p:dataTable>
</h:form>
</f:view>
</html>
addItem.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
<h:outputLabel value="Add Item"/>
</f:view>
</html>
editItem.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
<h:outputLabel value="Edit Item"/>
</f:view>
</html>
DatatableBean.java
package my.web.datatable;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@ViewScoped
@Named
public class DatatableBean implements Serializable {
private List<Item> items = new ArrayList<>();
@PostConstruct
private void init() {
System.out.println(DatatableBean.class.getName() + " -> init()");
for (int i = 1; i <= 5; i++) {
items.add(new Item(i, "Item " + i));
}
System.out.println(DatatableBean.class.getName() + " <- init()");
}
public List<Item> getItems() {
return items;
}
public String editItem(Item item) {
System.out.println(DatatableBean.class.getName() + " -> editItem(): " + item);
if (item == null) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO, "add item", null));
System.out.println(DatatableBean.class.getName() + " <- editItem()");
return "addItem.xhtml";
} else {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO, "edit item", item.toString()));
System.out.println(DatatableBean.class.getName() + " <- editItem()");
return "editItem.xhtml";
}
}
}
Item.java
package my.web.datatable;
public class Item {
private final int id;
private final String name;
public Item(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return String.format("[id=%d,name=%s]", id, name);
}
}
Is this a bug regarding command button within datatable column header facet? Or is there a better way, to do what I want?
I am using primefaces 6.0 on wildfly-10.0.0.Final with Mojarra 2.2.12!
Update: removed logger; call same method for addItem / editItem; added redirect / forward pages