Dynamic p:column with c:forEach. Filter ans sort problem

UI Components for JSF
anatolse
Posts: 19
Joined: 14 Apr 2011, 11:09
Location: Russia, Moscow
Contact:

26 Apr 2011, 14:28

Hello.
I'm using primefaces-3.0.M1, Mojarra 2.0.4, Glassfish 3.0.1
I set list of datatable column using <c:forEach> tag. I use this approach instead of <p:columns> because it need to have filter and sort for each column.
All works good except two things. In filter and sort fields in p:column are not using value expression for getting field's value. Instead this fields use function resolveField which just removes symbols "#{}" from value expression and further adds it like fields into a FilterMap. Therefore my LazyDataModel.load method can't work properly. i.e. FilterMap always contains field named "filter" and also sort field always equals "sort".
Why it was done by this way?
How I can decide this problem?

Code: Select all

<p:dataTable id="wpsTable"
             lazy="true"
             rows="#{wpsBean.pageSize}"
             var="wps"
             selectionMode="single"
             selection="#{wpsBean.selectedWPS}"
             value="#{wpsBean.topLevelWPS}">
    <f:facet name="header">
        #{bundle.TopLevelWorkProcessSegment}
    </f:facet>

    <c:forEach items="#{userConfig.getTable('wps-base').columns}" var="col">
        <p:column filterBy="#{col.filter}"
                  sortBy="#{col.sort}"
                  filterMatchMode="#{col.filterMatchMode}"
                  filterStyle="#{col.filterStyle}"
                  headerText="#{bundle[col.name]}"
                  style="width: #{col.width}">
            <h:outputText value="#{col.valueExpression}" style="#{col.style}"/>
        </p:column>
    </c:forEach>
</p:dataTable>

dham
Posts: 30
Joined: 11 Feb 2011, 16:46

26 Apr 2011, 15:07

You need to use ui:repeat instead. Try that and get back to me.

anatolse
Posts: 19
Joined: 14 Apr 2011, 11:09
Location: Russia, Moscow
Contact:

27 Apr 2011, 09:46

I already tried it. And <ui:repeat> don't works because container of <ui:repeat> sees only one component - <ui:repeat>, i.e. <p:datatable> doesn't see <p:columns> inside <ui:repeat> and doesn't show any columns, just shows empty table.

aliirawan
Posts: 26
Joined: 15 Nov 2010, 20:09
Location: Jakarta, Indonesia
Contact:

27 Apr 2011, 23:18

I prefer dont use JSTL forEach or <ui:repeat/>
for looping <p:column> inside the <p:dataTable/>
it won't work.

I prefer you do binding the dataTable
<p:dataTable binding="#{bean.table} >

...
</p:dataTable>

and you loop the column and add to the table in the backing bean.
I like to explore new things. There's a way for everything. I believe.

anatolse
Posts: 19
Joined: 14 Apr 2011, 11:09
Location: Russia, Moscow
Contact:

28 Apr 2011, 16:38

I prefer separate view and model so I would not like to add column from backing bean. My solution with <c:forEach> works well inside <p:dataTable> and also I make changes in the org.primefaces.component.datatable.DataHelper file. Changes is follows:

Code: Select all

    String resolveField(ValueExpression expression)
    {
        String expressionString = expression.getExpressionString();
        expressionString = expressionString.substring(2, expressionString.length() - 1);      //Remove #{}

        return expressionString.substring(expressionString.indexOf(".") + 1);                //Remove var
    }
replaced by

Code: Select all

    String resolveField(ValueExpression expression)
    {
        Object newValue = expression.getValue(FacesContext.getCurrentInstance().getELContext());

        if (newValue == null || !(newValue instanceof String))
            return resolveField_old (expression);
        else {
            String val = (String)newValue;
            return val.substring(val.indexOf(".") + 1); 
        }
    }

    String resolveField_old(ValueExpression expression)
    {
        String expressionString = expression.getExpressionString();
        expressionString = expressionString.substring(2, expressionString.length() - 1);      //Remove #{}

        return expressionString.substring(expressionString.indexOf(".") + 1);                //Remove var
    }
This function calls from both sort and filter decoders. And now it works fine. I use maven and to avoid problem with updates of primefaces library I just added corrected file in my project.

anatolse
Posts: 19
Joined: 14 Apr 2011, 11:09
Location: Russia, Moscow
Contact:

04 May 2011, 07:30

This is topic about adding columns to <p:datatable> from managed bean. Can anybody help?
http://primefaces.prime.com.tr/forum/vi ... 535#p36535

monakhv
Posts: 42
Joined: 08 Feb 2010, 14:01

05 May 2011, 12:19

Hi!
I use dynamic column with c:forEach. I do not test filter function but sortBy work very well.

Here is working example

Code: Select all

<p:dataTable id="#{TableId}" var="supportS" value="#{Values}"
                     rows="#{bundle.Config_Row_NumberDialogs}" paginator="true"
                     selectionMode="multiple" selection="#{Selection}">
            
            <c:forEach var="column" items="#{sessionController.settings.supportDialogTable.columns}">
                <p:column sortBy="#{supportS[column.sortByName]}" >
                    <f:facet name="header">
                        <h:outputText value="#{column.headerName}"/>
                    </f:facet>
                    <h:outputText value="#{supportS[column.name]}"/>
                </p:column>
            </c:forEach>


        </p:dataTable>
Column class

Code: Select all

public class Column implements Serializable{
    private String name;//prop name
    private String headerName;//Column header
    private String sortByName;//Object to make sorting

    public Column(String propName, String headerName, String sortByName) {
        this.name = propName;
        this.headerName = headerName;
        this.sortByName = sortByName;
    }


    public String getHeaderName() {
        return headerName;
    }

    public void setHeaderName(String headerName) {
        this.headerName = headerName;
    }
.....

Code: Select all

public abstract class DataTable<T> {
 private List<Column> columns;//active column

 public List<Column> getColumns() {
        return columns;
    }

    public void setColumns(List<Column> columns) {
        this.columns = columns;
    }
...
}


anatolse
Posts: 19
Joined: 14 Apr 2011, 11:09
Location: Russia, Moscow
Contact:

10 May 2011, 09:09

My opinion is:
There are one difference between the sorting and filtering of <p:dataTable> in a lazy and in not lazy mode. In the lazy mode the DataHelper class doesn't use real values from sortBy and filterBy attributes. When table is "lazy loaded" then sorting and filterring make request to "LazyDataModel" function load (...) and it uses as parameters column names defined in the sortBy and filterBy column attribute names but not values. To do this it should use this attributes as is. It just removes braces and managed bean name from attribute's expression. E.g. if sortBy = #{xxx.sortBy} then the sort attribute for load function will be equals to sortBy. However for not lazy model for sorting real value of attribute's expression will be used to internal comparing within DataHelper class.
I may be mistaken.

sirius
Posts: 1
Joined: 07 Jun 2011, 15:11

07 Jun 2011, 15:19

Hello.
anatolse, I'm interested in your suggested solution very much.
Are you'd have to show definitions of UserConfig and Columns (userConfig.getTable('wps-base').columns) class ?

I have problem with show values in cells. What type of col.valueExpression is ?

Second solution : supportS[column.name] provide values in cells but it work only if provided entity have simple properties.

Example:

Code: Select all

@Entity
public class Order  {
...
User createUser;
...
}

@Entity
public class User  {
...
String fullName;
...
}
Statically defined dataTable column which works great:
<p:column sortBy="#{grid.createUser.fullName}"
headerText="Created by">
<h:outputText value="#{grid.createUser.fullName}" />
</p:column>

When I want to provide createUser.fullName in grid[column.name] (column.name= "createUser.fullName"), I get exception
Property 'createUser.fullName' not found on type com.xxxxx.model.Order

gizmo1177
Posts: 29
Joined: 18 Oct 2010, 15:48

17 Oct 2011, 20:01

I have the same problem with the DataHelper clazz :(. How can I use the quickfix of Anatolse? We get the primefaces lib through Maven repository. I don't know where to place the customized DataHelper clazz.

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 14 guests