Search code examples
jsfprimefacesprimefaces-datatable

Primefaces weird behaviour with datatable, overlayPanel and filter/sort


I'm having some trouble with primefaces datatables and dynamic overlay for each row.

Basically I have a main datatable containing a certain number of rows. For each row, I have a button and a linked overlay that, when clicked, shows a small datatable in the overlay (it lists the lasts changes concerning the row).

Here is the simplified code:

//the main datatable
<p:dataTable id="terminauxDataTable" var="terminalBean" widgetVar="dataTableWidgetVar" value="#{cc.attrs.listAllTerminals}" 
filteredValue="#{cc.attrs.listFilteredTerminals}">
...
<p:columnGroup>
  <p:row>
    <p:commandButton id="changelogButton"
               type="button"/>
    <p:overlayPanel id="changelogPanel" for="changelogButton"
       dynamic="true">
       //the small datatable for each row
       <p:dataTable var="changelog" value="#{terminalBean.lastChangelogs}">
          <p:column headerText="#{msg['commun.changelog.table.label.date']}">
              <h:outputText value="#{changelog.dateHr}">
                  <f:converter converterId="dateTimeConverter" />
              </h:outputText>
          </p:column>
          ... some other colums
       </p:dataTable>
    </p:overlayPanel>
</p:row></p:column></p:datatable>

everything works fine at first sight. When I click on any button i do get the content that I want to load. it's supposed to look like this : https://i.sstatic.net/n9GrW.png (sorry, cannot post image directly)

Problems start to arise as soon as I make any filtering od sorting on the main datatable. If a specific button was never clicked since page load, the overlay and the contained datatable are load successfuly. It dosen't matter if I applied a filter or a sort. If I already clicked a button at least once and then I apply a sort/filter, if I try to click again on the button the overlay is shown but is empty, there is no datatable inside.

here is an exemple of a click after a filter on a button that was clicked before : https://i.sstatic.net/eLGLo.png

Do you have any lead on how to address this problem ? Thank you


Solution

  • Using the overlay opitimally with a datatable, requires a little different approach as can be seen in the PrimeFaces showcase of the overlayPanel

    You need to put the overlayPanel outside the datatable, put a updatable container in there, e.g. an outputPanel and on the button in your column, update the panel and call the show function of the overlay panel with a specific parameter. Something like this:

    <p:dataTable>
        ....
        <p:column style="width:32px;text-align: center">
             <p:commandButton update=":form:terminalDetail" oncomplete="PF('myTerminalOP').show('#{component.clientId}')" icon="ui-icon-search" title="Details">
                <f:setPropertyActionListener value="#{selectedTerminal}" target="#{mySelectionView.selectedTerminal}" />
            </p:commandButton>
        </p:column>
    </p:dataTable>
    
    <p:overlayPanel widgetVar="myOP" showEffect="fade" hideEffect="fade" dismissable="false" showCloseIcon="true">
        <p:outputPanel id="terminalDetail" style="text-align:center;">
        ...
        </p:outputPanel>
    </p:overlayPanel>
    

    (Disclaimer: done on my phone, so typos may be there)