Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get row number in p:dataTable of dynamic element

Tags:

jsf

primefaces

I'm curious about how to get the row number of an element inside the <p:dataTable>.

<p:dataTable id="userDataTable" value="#{bean.rows}" rowIndexVar="rowIndex">
    <p:column headerText="RowCounter">
        <p:commandLink id="row#{rowIndex+1}" actionListener="#{bean.getRows}">
            <h:outputText value="Show Row #{rowIndex+1}" />
        </p:commandLink>
    </p:column>
</p:dataTable>

Bean:

public void getRows(ActionEvent ae) {                   
    System.out.println(ae.getComponent().getId().toString());
}

Always prints row1, no matter which <p:commandLink> is clicked. What am I missing?

like image 324
arket Avatar asked Oct 22 '22 12:10

arket


1 Answers

As to your concrete problem, the id attribtue of a JSF component is evaluated during view build time. However, the #{rowIndex} is only set during view render time. Thus, at the moment the id attribute is evaluated, the #{rowIndex} is nowhere been set and defaults to 0. This problem has essentially exactly the same grounds as already answered and explained here: JSTL in JSF2 Facelets... makes sense? Note thus that there's only one <p:commandLink> component, not multiple. It's just that it's been reused multiple times during generating HTML (everytime with the same component ID!).

To fix it, just use id="row" instead. The dynamic ID makes no sense in this particular case. JSF would already automaticlaly prepend the row index (check generated HTML output to see it). I'm not sure why exactly you incorrectly thought that you need to manually specify the row index here, so it's hard to propose the right solution as there are chances that you actually don't need it at all. See also How can I pass selected row to commandLink inside dataTable?

For the case you really need the row index, here's how you could obtain it:

Integer rowIndex = (Integer) ae.getComponent().getNamingContainer().getAttributes().get("rowIndex");

The UIComponent#getNamingContainer() returns the closest naming container parent which is in your particular case the data table itself, in flavor or UIData which in turn has thus the rowIndex property. You can alternatively also do so, which is a bit more self documenting:

UICommand commandLink = (UICommand) ae.getComponent();
UIData dataTable = (UIData) commandLink.getNamingContainer();
Integer rowIndex = dataTable.getRowIndex();
like image 70
BalusC Avatar answered Oct 24 '22 05:10

BalusC