3

I'm using p:dataTable from Primefaces 3.5 with lazy loading and dynamic columns.

I have three types of columns, the difference is in input for filtering. One has p:inputText, one has p:selectCheckboxMenu and last one hasn't anything.

Columns are rendered via c:foreach tag.

<c:forEach var="col" items="#{cc.attrs.bean.sortedModelColumns}">

Everything works fine, but not "lazy". I also have p:tabView, where each tab includes this dataTable and with every request, all beans are initialized. I know, that c:forEach is being evaluated in build time so it's before tabView.

Therefore, my question is: How to render different columns inside p:dataTable?

I've tried ui:repeat as follows:

<p:dataTable 'datatableDefinition' />
    <ui:repeat var="#col" value="#{cc.attrs.bean.sortedModelColumns}">
        columnsRendering
    </ui:repeat>
</p:dataTable>

but that will an empty dataTable. When I put the ui:repeat outside the p:dataTable it works.

I've also tried p:columns it renders everything just fine, but the listeners for filtering on p:inputText

<p:ajax event="keyup" listener="#{cc.attrs.bean.filterListener}" />

don't work.

I think, I've two options. First: make p:columns work somehow or try to use c:if in p:tabView, but I don't know how to trigger evaluation the test inside c:if on tab switch event.

Anyway, I'll be glad for any help.

EDIT: Full code of datatable

<p:dataTable widgetVar="entityTable" var="entity" value="#  {cc.attrs.bean.loadEntities(cc.attrs.groupId)}" 
                     resizableColumns="true" lazy="true"
                     rowStyleClass="#{entity.updated ? 'updatedRow' : ''}"                      
                     paginator="true" rows="10"
                     paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"  
                     rowsPerPageTemplate="5,10,20" paginatorPosition="bottom"
                     scrollable="true" scrollWidth="#{userSessionBean.windowWidth -35}">   
            <p:ajax event="colReorder" listener="#{cc.attrs.bean.onReorder}" />
            <p:ajax event="sort" listener="#{cc.attrs.bean.sortListener}" />
            <p:column style="width:20px" >                    
                <f:facet name="header">
                <p:selectBooleanCheckbox value="#{cc.attrs.bean.checkbox}">
                    <p:ajax onstart="return selectAll('#{component.clientId}');"/>
                </p:selectBooleanCheckbox>
                </f:facet>-->
                <p:selectBooleanCheckbox value="#{cc.attrs.bean.checkbox}" styleClass="entitySelectCheckbox">
                    <p:ajax listener="#{cc.attrs.bean.onEntitySelected(entity.id)}"/>
                </p:selectBooleanCheckbox>
                <p:commandLink id="notifIcon" styleClass=" #{entity.notification?'notification':''}" />
            </p:column>
            <p:column style="width:13px" rendered="#{not empty cc.attrs.subview}">
                <p:commandLink process="@this" value="&nbsp;&nbsp;&nbsp;" id="loadEntity" styleClass="loadEntity"
                               immediate="true" onstart="hideRows('#{component.clientId}');" actionListener="#{cc.attrs.bean.setSelectedRowId(component.clientId)}" action="#{cc.attrs.bean.selectEntity(entity.id)}"
                               update="@(##{pe:escapeSelector(cc.clientId)}\\\\:entityTableForm)"/>
            </p:column>
            <p:columns var="col" value="#{cc.attrs.bean.sortedModelColumns}">
                <f:attribute name="property" value="#{col.property}" />
                <f:facet name="header">
                    <div style="width: #{col.width}">
                        #{col.header}
                    </div>
                    <p:outputPanel rendered="#{not cc.attrs.bean.isColDate(col.property)}" >
                        <p:inputText id="#{col.property}Id" styleClass="filterInput" rendered="#{not cc.attrs.bean.isColEnum(col.property) and not cc.attrs.bean.isColVisual(col.property)}" size="10" onkeyup="delay(function(){entityTable.filter();console.log('x');}, 500 );" >
                            <p:ajax event="keyup" listener="#{cc.attrs.bean.filterListener}" />
                            <f:attribute name="property" value="#{col.property}" />
                            <f:attribute name="operator" value="#{col.operator}" />
                            <f:event id="filterEvent" type="javax.faces.event.PreRenderComponentEvent" listener="#{cc.attrs.bean.filterRendered}"/>
                        </p:inputText>  

                        <p:selectCheckboxMenu rendered="#{cc.attrs.bean.isColEnum(col.property)}" label="Choose" styleClass="filterInput">
                            <f:attribute name="property" value="#{col.property}" />
                            <f:selectItems value="#{cc.attrs.bean.getEnumStrings(col.property)}" var="item" />
                            <p:ajax event="change" listener="#{cc.attrs.bean.onEnumFilterChange}" oncomplete="setTimeout('entityTable.filter()',200);"/>
                        </p:selectCheckboxMenu>
                    </p:outputPanel>
                    <p:outputPanel rendered="#{cc.attrs.bean.isColDate(col.property)}" >
                        <p:calendar pattern="#{userSessionBean.person.settings.timeFormat}" styleClass="filterInput filterInputDate">
                            <f:attribute name="property" value="#{col.property}" />
                            <f:attribute name="operator" value=">=" />
                            <p:ajax event="dateSelect" listener="#{cc.attrs.bean.onDateFilterChange}" oncomplete="setTimeout('entityTable.filter()',200);" />  
                        </p:calendar>
                        <p:calendar pattern="#{userSessionBean.person.settings.timeFormat}" styleClass="filterInput filterInputDate">
                            <f:attribute name="property" value="#{col.property}" />
                            <f:attribute name="operator" value="&lt;=" />
                            <p:ajax event="dateSelect" listener="#{cc.attrs.bean.onDateFilterChange}" oncomplete="setTimeout('entityTable.filter()',200);" />  
                        </p:calendar>
                    </p:outputPanel>
                </f:facet>
                <p:outputPanel rendered="#{not cc.attrs.bean.isColDate(col.property)}">
                    <p:outputPanel rendered="#{not cc.attrs.bean.isColVisual(col.property)}">
                        <h:outputText rendered="#{empty col.chainedProperty}"
                                          value="#{entity[col.property]}" />
                        <h:outputText rendered="#{not empty col.chainedProperty}"
                                          value="#{entity[col.primaryProperty][col.chainedProperty]}" />
                        <h:outputText rendered="#{not empty col.middleProperty}"
                                          value="#{entity[col.primaryProperty][col.middleProperty][col.chainedProperty]}" />
                    </p:outputPanel>
                </p:outputPanel>
                <kwe:inlineprogress status="#{entity.status}" rendered="#{cc.attrs.bean.isColVisual(col.property)}" />
                <h:outputText rendered="#{cc.attrs.bean.isColDate(col.property)}" value="#{cc.attrs.bean.dateTimeDisplay(entity[col.property])}"/>
        </p:columns>
        <f:event id="event2" type="javax.faces.event.PreRenderComponentEvent" listener="#{cc.attrs.bean.allRendered}"/>
    </p:dataTable>
tvazac
  • 536
  • 2
  • 7
  • 21

1 Answers1

2

You can´t use ui:repeat or c:forEach in p:dataTable, but i think that you can use p:columns

Mathew Rock
  • 989
  • 2
  • 14
  • 32
  • Thanks for the answer. I tried to use `p:columns` but there is a problem with inputs, they have same ids (all of them). So ajax listeners for filtering don't work. – tvazac Aug 07 '13 at 06:43
  • What do you use *rowEdit* or *cellEdit* – Mathew Rock Aug 07 '13 at 06:48
  • I edited original question (added datatable code). I'm not using neither rowEdit nor cellEdit. The code with `c:forEach` instead of `p:columns` works just fine (but not lazy) – tvazac Aug 07 '13 at 06:55
  • In *header* and *footer* can´t use listener, but you can use in *p:columns* funtion **filterBy="XXXX"** – Mathew Rock Aug 07 '13 at 07:13
  • I can't use filterBy. I have different inputs for filters (Select Menu, input text, nothing...) – tvazac Aug 07 '13 at 07:29
  • I found this http://javaeeinsights.wordpress.com/2011/04/07/primefaces-datatable-lazyloading-using-hibernate-criteria-api/ I´ll hope this usefull and this http://forum.primefaces.org/viewtopic.php?f=3&t=14256 – Mathew Rock Aug 07 '13 at 07:49
  • Thanks for the response and links, but if I get it right, the load function in backing bean is triggered by fillterBy attribute in xhtml and that is a problem. I think that better solution would be to find out why all inputs have a same id. – tvazac Aug 07 '13 at 08:15
  • do you try delete id? – Mathew Rock Aug 07 '13 at 08:31
  • I don´t know dude. sorry – Mathew Rock Aug 07 '13 at 08:50