How to add DataList to panel programmatically with PrimeFaces? - jsf

I am new to PrimeFaces and I need little help.
I want to add dynamic dashboard and into each panel add datalist.
I can see dashboard with datalists, but there are no strings in rows.
Thanks for your help
My code:
Panel panel=(Panel)application.createComponent(fc,"org.primefaces.component.Panel","org.primefaces.component.PanelRenderer");
panel.setId("measure_" + i);
panel.setHeader(lists.get(i).getName());
panel.setToggleable(true);
panel.setVisible(true);
DataList dataList = (DataList) application.createComponent(fc, "org.primefaces.component.DataList", "org.primefaces.component.DataListRenderer");
List<String> test = new ArrayList();
test.add("foo");
test.add("foo2");
dataList.setValue(test);
panel.getChildren().clear();
panel.getChildren().add(dataList);
getDashboard().getChildren().add(panel);
DashboardColumn column = model.getColumn(i%getColumnCount());
column.addWidget(panel.getId());

Try to use value expression approach:
#ManagedBean(name="bean")
public class ManagedBean{
public List<String> test;
//getter and setter of test
...
DataList dataList = (DataList) application.createComponent(fc, "org.primefaces.component.DataList", "org.primefaces.component.DataListRenderer");
//init test on PostConstruct Method
this.getTest().add("foo");
this.getTest().add("foo2");
ValueExpression ve = application.getExpressionFactory().createValueExpression(fc.getELContext(), "#{bean.test}", Collection.class);
dataList.setValueExpression("value", ve);
...
}
Actually I doesn't test that codelines, but I used this approch successfully and I think is more useful because you can binding datamodel to bean and doesn't lose control of your data.

Related

Dropdown list is not populating in JSF

I am working on Managedbeans and JSF. As shown below that my ManagedBean contains all the requirements that are required for the JSF to get the value. I have initialised my dropdown list as below. In selectOneMenu, I have chosen the country as a string where it will store the value selected by the dropdown list and the dropdown list will bring up the list that I declared in the Beans.
Unfortunately, it is not happening like that. Every time dropdown renders it gives me an empty value. I have spent days on it but cannot figure out the exact solution to it. I have cleaned my server, build workspace and also change servers but nothing is working.
** ManagedBean_list **
private List<String> listCountry;
private String country;
public void tada(){
listCountry=Arrays.asList("India", "pakisatan","America");
}
public List<String> getListCountry() {
return listCountry;
}
public void setListCountry(List<String> listCountry) {
this.listCountry = listCountry;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
JSF
<p:selectOneMenu id="country" value="#{loginBeans.country}">
<f:selectItems value="#{loginBeans.listCountry}" />
</p:selectOneMenu>
Your help is appreciated. Empty dropdown list image
enter image description here
Which bean annotation are you using? You say "Managedbeans", but the source you posted does not show the entire bean, or does it? Check to make sure you are not mixing old style JSF managed bean annotations with CDI annotations.
The issue is that on initialization, the list is not being called up. I resolved it by including the list function inside the constructor of managed beans class. so that when the constructor fired up. It also generates the dropdown list.
Either convert your listCountry to a
private Map<String, String> listCountry = new HashMap<>();
listCountry.put("India", "India");
listCountry.put("Pakistan", "Pakistan");
listCountry.put("America", "America");
or
private List<SelectItem> listCountry = new ArrayList<>();
listCountry.add(new SelectItem("India", "India"));
listCountry.add(new SelectItem("Pakistan", "Pakistan"));
listCountry.add(new SelectItem("America","America"));

MethodExpression not firing in HtmlCommandLink

I have a dynamically generated Datatable, like this
DataTable dataTable = new DataTable();
dataTable.setValue(relatorioVOList);
dataTable.setVar("rVO");
Column checkBoxColumn = new Column();
checkBoxColumn.getChildren().add(this.viewComponentBuilder.createExpressionTextWithLink("#{rVO.iRelatorio}","#{rVO.nNome}"));
dataTable.getColumns().add(checkBoxColumn);
public HtmlForm createExpressionTextWithLink(String iRelatorioExpressionValue, String valueExpressionValue) {
HtmlForm form = new HtmlForm();
HtmlCommandLink link = new HtmlCommandLink();
//config
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ExpressionFactory ef = application.getExpressionFactory();
ELContext elc = context.getELContext();
//value that is the reports name
ValueExpression nameValueExp = ef.createValueExpression(elc, valueExpressionValue, Object.class);
link.setValueExpression("value", nameValueExp);
//action that goes to method teste when link is clicked
MethodExpression methodExpression = createMethodExpression("#{componenteC.teste(rVO.iRelatorio)}", String.class, Integer.class);
link.setActionExpression(methodExpression);
form.getChildren().add(link);
return form;
}
private static MethodExpression createMethodExpression(String expression, Class<?> returnType, Class<?>... parameterTypes) {
FacesContext facesContext = FacesContext.getCurrentInstance();
return facesContext.getApplication().getExpressionFactory().createMethodExpression(
facesContext.getELContext(), expression, returnType, parameterTypes);
}
In ComponenteC, a RequestScopedBean, the teste function
public String teste(Integer iRelatorio) {
System.out.println("cheguei");
return "componente";
}
The goal is that the teste function will generate an url according to the iRelatorio parameter.
The issue here is that the function is never called. I tried replacing the rVO.iRelatorio with an explicit 10, "#{componenteC.teste(10)}" and even then the action seems to not be fired.
The report name is displayed correctly.
Dynamically created UIInput, UICommand and UINamingContainer components must have a fixed id assigned. Otherwise it will get an autogenerated one which is not necessarily the same when the view is restored. The component ID is used in request parameter names in submitted form data, which JSF would then use to collect the submitted input values and identify the invoked commands during apply request values phase. If the component ID changes, then JSF won't be able to perform the apply request values phase as intented.
Thus, act accordingly:
dataTable.setId("tableId");
// ...
form.setId("formId");
// ...
link.setId("linkId");
There are other potential causes, but they are not visible in the information provided so far in the question. To cover that, take your time to carefully read the following related answers on "dynamically" creating components/views:
Create inputtext dynamically
How does the 'binding' attribute work in JSF? When and how should it be used?
How to create dynamic JSF form fields
That said, you're really better off using XHTML to declare and create components instead of all that Java code mess. XHTML(+XML) is much more declarative and readable and therefore better understandable and maintainable. JSTL may be very helpful in this all.

How bind primefaces datatable from managedbean

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?
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.

java.lang.NumberFormatException: Trying to extract rowIndex from clientId

I'm developing a dynamic form using Mojarra 2.2.5 and Primefaces 4.0 and i need to implement a datatable with dynamic content. Unfortunately when i try to submit form appears this error:
java.lang.NumberFormatException: Trying to extract rowIndex from clientId 'id_of_my_datatable:j_id1:j_id1'
I generated datatable by code using it, inspired by Primefaces Showcase (http://primefaces.org/showcase/ui/datatableDynamicColumns.jsf) and from (Stack Overflow discussion)
private DataTable addList(UIComponent parent, String labelStr, String id, List<ColumnModel> rowItems, List<Map<String, String>> values, String styleClass,
boolean isRequired, String updateComponents)
{
OutputPanel outputPanel = new OutputPanel();
outputPanel.setStyleClass("question_panel col-md-11");
if (labelStr != null)
{
addLabel(outputPanel, id, labelStr, "component_label col-md-11");
}
DataTable dataTable = new DataTable();
dataTable.setValue(values);
//mapModel = values;
//ValueExpression veTable = super.createValueExpression("#{composerTestBean.mapModel}", List.class);
//dataTable.setValueExpression("value", veTable);
dataTable.setVar("model");
dataTable.setId(id);
dataTable.setRowIndexVar("rowIndex");
Columns columns = new Columns();
columns.setValue(rowItems);
//columnModel = rowItems;
//ValueExpression veColumns = super.createValueExpression("#{composerTestBean.columnModel}", List.class);
//columns.setValueExpression("value", veColumns);
columns.setVar("column");
columns.setColumnIndexVar("colIndex");
HtmlOutputText headerText = new HtmlOutputText();
ValueExpression veHeader = super.createValueExpression("#{column.header}", String.class);
headerText.setValueExpression("value", veHeader);
columns.getFacets().put("header", headerText);
HtmlOutputText valueText = new HtmlOutputText();
ValueExpression veValue = super.createValueExpression("#{model[column.property]}", String.class);
valueText.setValueExpression("value", veValue);
columns.getChildren().add(valueText);
dataTable.getChildren().add(columns);
outputPanel.getChildren().add(dataTable);
parent.getChildren().add(outputPanel);
return dataTable;
}
As you can see I've also tried to use valueExpression and the property bean binding, but nothing is changed. setRowIndexVar() and setColumnIndexVar() methods are just attempts to resolve the question.
I also read that it could be a Mojarra bug on this discussion (it should be resolved) and in another one that is a Primefaces bug (I can't apply patches on project libraries).
Also I try to follow this post and this remove this exception but brings others problem to my page about update.
Do You think I'm doing something wrong? Or Is it just an unresolvable case?
Thanks in advance.

Dynamically created input components do not show model values

I have some fields of a bean that I need to show programmatically. Is something like this:
HtmlPanelGrid panel = new HtmlPanelGrid();
panel.setColumns(4);
HtmlOutputLabel fieldOut = new HtmlOutputLabel();
fieldOut.setId("fieldOutId");
fieldOut.setValue("name");
panel.getChildren().add(fieldOut);
HtmlInputText fieldIn = new HtmlInputText();
fieldIn.setId("fieldInId");
fieldIn.setPartialSubmit(true);
fieldIn.setValueExpression(
"field", UtilFaces.createValueExpression("#{newElementBean.fieldName}",String.class));
panel.getChildren().add(fieldIn);
mainForm.getChildren().add(panel);
In newElements.xhtml i've defined a form which is binded to mainForm, in this way:
<ice:form binding="#{newElementBean.mainForm}">
<ice:inputText id="ANOTHERFIELD" value="#{newElementBean.anotherField}"/>
<ice:commandButton action="#{newElementBean.save}" value="Save"/>
</ice:form>
When I click on the save button and I go to the next view, the field "ANOTHERFIELD" has taken the value from the bean, and shows up correctly, but the fields that were dinamically generated shows empty. Its values in the backing bean also are null. It's like the ValueExpression is not working for the HtmlInputText that I created in the backing bean. I'm using Icefaces 3.3 with Mojarra 2.1.17.
How is this caused and how can I solve it?
I solved it. I made two mistakes:
The proper setValueExpression call is like this:
fieldIn.setValueExpression("value", UtilFaces.createValueExpression("#newElementBean.fieldName}");
I was incorrectly using "field1" as 1st argument instead of "value".
This is not visble in the question, but my createValueExpression() helper method was also wrong. The following is working for me:
public static ValueExpression createValueExpression(String expression) {
Application app = FacesContext.getCurrentInstance().getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
return elFactory.createValueExpression(elContext, expression, Object.class);
}

Resources