0
votes

How bind primefaces datatable in managedbean? How put the data, and how put columns?

My bean class:

public class BeanTest implements Serializable{
private String name;
private String email;
private int age;
//getters and setters
}

My managed bean:

public class TestTable implements Serializable{
private DataTable tabela;
private List<BeanTest> lista;

@PostConstruct
public void init() {
int age= 18;
this.lista = new ArrayList<>();
this.lista.add(new BeanTest("name1", "email1", age));
this.lista.add(new BeanTest("name2", "email2", age++));
this.lista.add(new BeanTest("name3", "email3", age++));

this.tabela = new DataTable();
Column column1 = new Column();
column1.setHeaderText("Nome");

Column column2 = new Column();
column2.setHeaderText("Email");

Column column3 = new Column();
column3.setHeaderText("Idade");

this.getTabela().getChildren().add(column1);
this.getTabela().getChildren().add(column2);
this.getTabela().getChildren().add(column3);

this.getTabela().setValue(this.lista);
}
}

JSF page:

<p:dataTable id="datalist" binding="#{testeTabela.tabela}">
</p:dataTable>

This display the table with three columns (correct, number and headers) and three rows(correct numbers), but there's no data in my rows. Empty table only with borders cells.

What's happening? How could i bind columns and data?

1
Avoid binding and tedious Java code ways until/unless absolutely necessary in some (very) special cases which in this case appears to be absolutely superfluous. Check out examples on the showcase. (Do not forget to click the respective links on that page).Tiny

1 Answers

6
votes

In general, a JSF component has 3 parts: a tag, a component class and a renderer.

The tag is responsible for the component configuration. It will instantiate your component and set the appropriate attributes, listeners and facets. Once configured, the component will be put on the component tree.

Using your example, the page code will look similar to this:

<p:dataTable id="dataTable" var="item" value="#{bean.list}">
    <p:column headerText="Name">#{item.name}</p:column>
    <p:column headerText="Email">#{item.email}</p:column>
    <p:column headerText="Age">#{item.age}</p:column>
</p:dataTable>

It's easier to do that way. However, if you want to do in code, you need to add some components inside the columns to make it work.

First, set the var attribute on the datatable. The component (datatable) will iterate over your items and bind the current item to that name, so the child components can use an expression to dynamically get that value.

this.getTabela().setVar("item");

Second, add a child UIOutput to the column and add an expression to the its value property. For the name column, it would be something like this:

FacesContext context = FacesContext.getCurrentInstance();
//Creates the output and sets the value to an expression language
UIOutput output1 = new UIOutput();
output1.setValueExpression("value",context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(),"#{item.name}", String.class));
//Add the output to the column
column1.getChildren().add(output1);

For the other columns, it's the same idea, except for the type of the third UIOutput's value:

...createValueExpression(context.getELContext(),"#{item.age}", Integer.class));

As you can probably see, this can be hard to maintain.

Using tags is cleaner and easier to read.