Primefaces dynamic columns p:columns sort specific columns - jsf

i have a datatable with dynamic columns, defined by a columnModel. The String property links to the correct field (used for value output). The sort String equals the property, but some columns should not be sortable, sort is null or emtpy (tried both) there:
public class ColumnModel {
private String property;
private String sort;
private int width;
//GETTER
...
}
I use a List of that models to create my dynamic columns. The use of the width is working well:
<p:dataTable value="#{bean.items}" var="item" ... >
<p:columns value="#{bean.columnModel}" var="column" sortBy="#{column.sort}" width="#{column.width}">
...
</p:columns>
</p:dataTable>
My Question:
sortBy does not allow a null or an emtpy value. Otherwise i get a parse exception where it says, it cannot parse #{item.}. primefaces seems to add 'item' (my var of the datatable) automatically before the given sortfield.
How can some columns be ignored?
Thanks for your answeres!
Using primefaces 5.0.9 with Wildfly 9.0.2

Primefaces added new attributes for p:column(s) in version 5.1.3 and 5.2.0:
sortable
filterable
Here is the link to the solved Issue:
https://code.google.com/archive/p/primefaces/issues/5021
Example depending on my code above:
public class ColumnModel {
private String property;
private boolean sortable;
private int width;
//GETTER
...
}
With a given List<ColumnModel> columnModel in bean:
<p:dataTable value="#{bean.items}" var="item" ... >
<p:columns value="#{bean.columnModel}" var="column" sortBy="#{item[column.property]}" field="#{column.property}" sortable="#{column.sortable}" width="#{column.width}">
...
</p:columns>
</p:dataTable>

Related

List in omnifaces.ListConverter is not set

I'm developing a JSF Application with PrimeFaces.
For a Picklist I'm trying to use the omnifaces.ListConverter but the list property in this converter is not set.
reporting-edit.xhtml
<p:pickList id="picklist_columns" value="#{reportingEditView.columns}" var="repcolumn"
itemLabel="#{repcolumn.column.name}" itemValue="#{repcolumn}" responsive="true"
showSourceFilter="true" filterMatchMode="contains">
<o:converter converterId="benni.ListConverter" list="#{reportingEditView.columns.source}"/>
<f:facet name="targetCaption">Spalten</f:facet>
<p:ajax event="transfer" listener="#{reportingEditView.handleColumnTransfer}"/>
reportingEditView.java
#ManagedBean
#SessionScope
public class ReportingEditView
{
private DualListModel<RepColumn> columns;
public void initPickList()
{
List<RepColumn> availableColumns = new ArrayList<>();
List<RepColumn> selectedColumns = new ArrayList<>();
... populate availableColumns and selectedColumns ...
this.columns = new DualListModel<RepColumn>();
this.columns.setSource(availableColumns);
this.columns.setTarget(selectedColumns);
}
}
All the columns are displayed in my PickList but when I put one column from the source list into the target list a NullPointer is thrown because the list in the converter is not set.
Also the listener Method is not called when transferring an element in the PickList.
Any ideas what I am doing wrong?
Shame on me!
I fixed that issue. I don't know how but there was xmlns:o="http://java.sun.com/jsf/core" in my reporting-edit.xhtml. After replacing that with xmlns:o="http://omnifaces.org/ui" everything works like a charm.

Primefaces datatable's p:columns not iterating over Map

I am having a two level map Map<String,HashMap<String,String>> which i need to display using a <p:dataTable>. The code of managed bean is as follows:
#ManagedBean(name="MyBean")
public class MyBean{
private Map<String,HashMap<String,String>> twoDimentionalMap;
public void getMapData(){
twoDimentionalMap=getDataFromDataStore();
}
}
Now I am using this map in my view.xhtml file as follows:
<p:dataTable var="entrySet1" value="#{MyBean.twoDimentionalMap.entrySet()}">
<p:columns var="entrySet2" value="#{entrySet1.getValue()}">
#{entrySet2.getKey()} - #{entrySet2.getValue()}
</p:columns>
</p:dataTable>
I also tried using
<p:dataTable var="entrySet1" value="#{MyBean.twoDimentionalMap.entrySet()}">
<p:columns var="entrySet2" value="#{MyBean.twoDimentionalMap.get(entrySet1.getKey()).getValue()}">
#{entrySet2.getKey()} - #{entrySet2.getValue()}
</p:columns>
</p:dataTable>
I even tried converting the outer map to a list:
List<HashMap<String,String>> twoDimentionalMap;
However nothing is displayed on datatable. The execution shows no error but there is nothing displayed on the page.
Kindly suggest if I am doing something wrong or if <p:columns> is having any issue handling maps.
Thanks
since the keys of outer map do not have a meaning, converting the outer map to a list is correct.
but your approach to retrieve column names from xhtml does not seem valid. you need to get them independently from the current iteration variable entrySet1, otherwise you add a third dimension to the operation, which data table cannot handle.
we need to assume that all keys are same across the listed maps.
here is the code for xhtml:
<p:dataTable var="entrySet1" value="#{testMB.twoDimensionalMap}">
<p:columns var="keySet2" value="#{testMB.columnNames}">
#{keySet2} - #{entrySet1[keySet2]}
</p:columns>
</p:dataTable>
and for the bean:
#Named
#ViewScoped
public class TestMB implements Serializable {
private List<HashMap<String,String>> twoDimensionalMap;
public TestMB()
{
getMapData();
}
private void getMapData(){
//twoDimentionalMap=getDataFromDataStore();
twoDimensionalMap = new ArrayList<HashMap<String,String>>();
twoDimensionalMap.add(new HashMap<String,String>());
twoDimensionalMap.get(0).put("key0", "value00");
twoDimensionalMap.get(0).put("key1", "value01");
twoDimensionalMap.add(new HashMap<String,String>());
twoDimensionalMap.get(1).put("key0", "value10");
twoDimensionalMap.get(1).put("key1", "value11");
}
public Set<String> getColumnNames()
{
return twoDimensionalMap.size() > 0 ? twoDimensionalMap.get(0).keySet() : new HashSet<String>();
}
public List<HashMap<String, String>> getTwoDimensionalMap() {
return twoDimensionalMap;
}
}

Auto-updating filter values on DataTable

I'm currently using filters with options list on my lazy loaded DataTables. Everything works just fine except I'd like to be able to reload my filter options depending on currently selected filters.
For example, my DataTable has two fields country and region, and I want to filter
DataTable snippet :
<p:dataTable var="d" widgetVar="personneContactTable" value="#{bean.dataModel}" id="myDataTable" lazy="true">
<p:column sortBy="country" filterBy="country" filterOptions="#{bean.getCountryOptions()}">
[...]
</p:column>
<p:column sortBy="region" filterBy="region" filterOptions="#{bean.getRegionOptions()}">
[...]
</p:column>
</p:dataTable>
And my bean :
#ManagedBean(name = "bean")
#SessionScoped
public class MyBean implements Serializable {
LazyDataModel<MyStuff> dataModel;
String country;
String region;
public SelectItem[] getCountryOptions() {
return service.someMagic();
}
public SelectItem[] getRegionOptions() {
return service.someMoreMagic(country);
}
// + getters, setters, etc.
}
I tried using properties instead of methods, adding <p:ajax event="filter"> tags to try reloading part of the DataTable, but nothing worked. I found http://forum.primefaces.org/viewtopic.php?f=3&t=38087 too, but again not workable solution emerged.
How can I automaticaly refresh my filterOptions? (this is using Primefaces 4 ELITE branch)

How to get selected row of a datable in JSF 1.2 using OpenFaces?

I used data table (OpenFaces) for selecting a row in data table using the attribute o:checkboxColumn rowDatas this will filter the selected rows only.
<o:checkboxColumn rowDatas="#{tBean.srInventoryList}">
<f:facet name="header">
<o:selectAllCheckbox />
</f:facet>
</o:checkboxColumn>
When I click a button it displays all the list, but I want only other rows which are not selected whether any attributes for filter the row list.
Actually it's not possible by the API of checkboxColumn by itself, You need to add some additional logic inside your bean for example:
<o:dataTable id="bookMultipleSelection"
var="book"
value="#{BookList.books}">
<o:multipleRowSelection rowDatas="#{BookList.list}"/>
<o:selectionColumn>
<f:facet name="header">
<o:selectAllCheckbox/>
</f:facet>
</o:selectionColumn>
/**other columns here**/
</o:dataTable>
<o:commandButton execute="bookMultipleSelection" action="#{BookList.updateList}" render="bookMultipleSelection" value="Click ME"/>
End something like this in your backing bean :
private List<Book> books;
private List list = new ArrayList();
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public List<Book> getBooks() {
return books;
}
public void updateList(){
books.removeAll(list);
}

Changing h:datatable cell color or style dynamically in JSF

I have a datatable where I want to change the color of a cell based on some analysis that is run on the contents. The table is linked to an array of Comment objects, which I have given a String cssClass that gets updated once the analysis is run. This is what I have tried plugging into the rowClasses property of the datatable. It's not working and I think the issue may be that I cannot access the variable created for each row of the datatable, from inside the datatable declaration.
Datatable code:
<h:dataTable value="#{post.comments}" var="comment" class="hs-table" rowClasses="#{comment.cssClass}" >
<h:column>
#{comment.name}
</h:column>
<h:column>
#{comment.email}
</h:column>
<h:column>
#{comment.msg}
</h:column>
</h:dataTable>
The Comment class:
public class Comment {
private String msg;
private String email;
private String name;
private Date date;
private String cssClass;
public Comment(){
cssClass = "normColumn";
}
epublic String getCssClass() {
return cssClass;
}
public void setCssClass(String cssClass) {
this.cssClass = cssClass;
}
}
Where the cssClass is updated in the managed bean:
if(tone>0)
c.setCssClass("commentPos");
else if(tone<0)
c.setCssClass("commentNeg");
The class never gets assigned. Am I doing something wrong, or is this simply not possible?
In the standard JSF <h:dataTable> component, the rowClasses attribute is unfortunately not evaluated on a per-row basis. It's evaluated on a per-table basis. Component libraries like Tomahawk and PrimeFaces however support the kind of attribute which you're looking for on their <t:dataTable> and <p:dataTable>.
With the standard JSF <h:dataTable> component you need to supply a comma-separated string of all row classes. This can look something like this:
public String getRowClasses() {
StringBuilder rowClasses = new StringBuilder();
for (Comment comment : comments) {
if (rowClasses.length() > 0) rowClasses.append(",");
rowClasses.append(comment.getCssClass());
}
return rowClasses.toString();
}
which is then to be referenced as
<h:dataTable ... rowClasses="#{post.rowClasses}">
See also:
<h:dataTable> tag documentation - lists all attributes and the accepted values

Resources