3
votes

I'm using a primefaces datatable with single row selection and pagination. For each row I have some commandlinks (one of which is disabled) that I want the user to click to perform operations on that row (example: delete, edit). In order to provide visual confirmation that the user clicked the button on the right row, I want the row to be selected upon clicking and then proceed to the desired bean method. This is working as intended if the table has only one page or if it's page 1; on all other pages I get a NullPointerException.
I figured out why this happens: I use rowIndexVar to perform the selection but it seems to be returning the index related to the whole table and the selectRow method expects an index related to the current page. Meaning that if I have 10 rows per page and I click on the third row in the second page, the index returned is "12" and not "2" and selectRow(12, false) returns null as there are only 10 items on that page.

My question is: how can I pass the correct rowIndex so I get the correct selection on all pages?

The backing bean is ViewScoped and the methods aren't nothing extraordinary but since it has a lot of code related to webservices and jaxb generated classes and I signed an NDA I can't paste it here (I'm already pushing it by sharing the datatable code).

<p:dataTable id="dataTable" var="item" rowIndexVar="rowIndex"
    value="#{dgRefTypePubBean.itemList}"      
    widgetVar="itemsTable"
    filteredValue="#{dgRefTypePubBean.filteredItems}" paginator="true"
    rows="10"
    paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
    rowsPerPageTemplate="2,5,10,20" rowKey="#{item.EID}"
    selection="#{dgRefTypePubBean.selectedItem}" selectionMode="single"
    emptyMessage="#{msgs['dgreftype.datatable.message.emptyList']}"
    resizableColumns="false">

    <p:ajax event="page" oncomplete="itemsTable.unselectAllRows(); itemsTable.selectRow(0, false)" />
    <p:ajax event="rowSelect" listener="#{dgRefTypePubBean.onRowSelect}"
        update=":form:obs :form:index_info :form:elimination_just :form:left_footer :form:right_footer" />
    <p:ajax event="rowUnselect" listener="#{dgRefTypePubBean.onRowUnselect}" update=":form:obs" />

    <p:column style="text-align:right; width:22px; border:none; background:white">
        <h:graphicImage rendered="#{item.EState==2}" library="images" name="data-delete.png" width="15" height="15" style="border:none; padding:0" />
    </p:column>
    <p:column id="codColumn" headerText="#{msgs['dgreftype.datatable.label.functionalCode']}" filterStyle="height:10px; font-weight:normal" style="text-align:left; width:120px" filterBy="#{item.EFunctionalCode}">
        <h:outputText value="#{item.EFunctionalCode}" />
    </p:column>
    <p:column id="designationColumn" headerText="#{msgs['dgreftype.datatable.label.name']}" filterStyle="height:10px; font-weight:normal" style="text-align:left; word-wrap: break-word" filterBy="#{item.EName}">
        <h:outputText value="#{item.EName}" />
    </p:column>
    <p:column id="variableColumn" headerText="#{msgs['dgreftype.datatable.label.variableTypeName']}" filterStyle="height:10px; font-weight:normal" style="text-align:left; width:200px" filterBy="#{item.EVariableTypeName}">
        <h:outputText value="#{item.EVariableTypeName}" />
    </p:column>
    <p:column id="buttonsColumn" style="width:55px">
        <h:panelGrid columns="3" style="border-collapse:separate; border:none !important">
            <h:commandLink onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}, false)" action="#{dgRefTypePubBean.editSelectedItem()}">
                <h:graphicImage library="images" name="edit-text.png" width="15" height="15" style="border:none" />
            </h:commandLink>
            <h:graphicImage library="images" name="detail-disabled.png" width="15" height="15" style="border:none" onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}, false)" />
            <h:commandLink onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}, false); confirmation.show(); return false;">
                <h:graphicImage library="images" name="edit-delete.png" width="15" height="15" style="border:none" />
            </h:commandLink>
        </h:panelGrid>
    </p:column>
</p:dataTable>

I'm using JSF 2.0 and Primefaces 3.4.2.

Thanks in advance

1

1 Answers

2
votes

It is possible to get the current page from the paginator with this function :

itemsTable.paginator.getCurrentPage()

So, we can calculate the correct row index from this value, the value of #{rowIndex} and the maximum number of row per page.

 <h:commandLink onclick="itemsTable.unselectAllRows(); itemsTable.selectRow(#{rowIndex}-itemsTable.paginator.getCurrentPage()*10)" action="#{dgRefTypePubBean.editSelectedItem()}">
      <h:graphicImage library="images" name="edit-text.png" width="15" height="15" style="border:none" />
 </h:commandLink>

I hope this help.

Regards.