Search code examples
jsfprimefacescommandlink

Primefaces' commandLink works only on the first page of a dataTable


I have a column with p:commandLink inside p:dataTable, which has a paginator. When user clicks on a commandLink, a dialog opens, displaying data of that row.

datatable html code:

<p:dataTable id="dtSample" value="#{sessionBean.sampleList}"
    binding="#{requestBean.dtSampleList}"
    paginator="true" paginatorPosition="bottom"
    paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
    rowsPerPageTemplate="#{10,25,50}"
    currentPageReportTemplate="({startRecord} of {totalRecords})"
    var="item" emptyMessage="No entries." rows="10" rowKey="#{item.id}">
    <p:column headerText="Id">
        <p:commandLink id="lnkSample"
            action="#{requestBean.onLinkClick(item)}"
            oncomplete="PF('dlgSample').show();"
            update="@(.dialogClass)">
            <h:outputText value="#{item.id}" />
                        </p:commandLink>
    </p:column>
    <p:column headerText="Code">
        <h:outputText value="#{item.code}" />
    </p:column>
    <p:column headerText="Description">
        <h:outputText value="#{item.descr}" />
    </p:column>
</p:dataTable>

Request bean:

public class RequestBean {

    private SessionBean sessionBean;

    private DataTable dtSampleList;

    public void init() {
        // load samle list
        loadSampleList();
    }

    public String onLinkClick(Sample sample) {
        getSessionBean().setSelectedSample(sample);
        return "success";
    }

    private void loadSampleList() {
        List<Sample> list = new ArrayList<Sample>();

        for (int i = 0; i < 100; i++) {
            Sample tmp = new Sample();
            tmp.setId(new BigDecimal(i + 1));
            tmp.setCode("code" + (i + 1));
            tmp.setDescr("desc" + (i + 1));
            list.add(tmp);
        }
        getSessionBean().setSampleList(list);

    }

// getters and setters

}

Session bean:

public class SessionBean implements Serializable {
    private static final long serialVersionUID = 1L;

    private List<Sample> sampleList;
    private Sample selectedSample;

    // getters and setters

}

dialog html code:

<p:dialog id="dlgSample" closeOnEscape="true" widgetVar="dlgSample"
                    styleClass="dialogClass" modal="true">
    <p:panelGrid columns="1">
        <h:outputText value="Id: #{sessionBean.selectedSample.id}" />
        <h:outputText value="Code: #{sessionBean.selectedSample.code}" />
        <h:outputText value="Description: #{sessionBean.selectedSample.descr}" />
    </p:panelGrid>
</p:dialog>

When I click on a link on the first page of a datatable, link action is executed and a dialog, displaying row data, is properly refreshed. But when I move to any of the following pages of a datatable, clicking a link doesn't refresh the data in a dialog (the link action is not called, so the data in a dialog is wrong - selectedSample variable has old value). Of course when I go back to the first page of the datatable, command link works again (action method is called and data is refreshed).

What am I doing wrong? Why is action method not called on any datatable page?

I'm using Primefaces 5.2.


Solution

  • Looks like the problem was in a PF dataTable component. There were first and rows attributes missing and after adding them, commandLinks on all pages work as expected.