2008-11-18 11 views
20

w A JSF DataTable chcę wyświetlić indeks wiersza obok wierszy ... takich jak:Jak wyświetlić indeks wiersza w JSF elementu datatable

Column A Column B 
1   xxx 
2   yyy 

myślałem, że mogę używać ukrytą zmienną el jak # {rowIndex}, ale to nie działa.

Rozwiązanie znalazłem jest stworzenie wiążące dla tabeli danych i używać wiązania jak:

<h:dataTable var="item" value="#{controller.items}" binding="#{controller.dataTable}"> 
    <h:column>#{controller.dataTable.rowIndex}</h:column> 
    <h:column>value</h:column> 
</h:dataTable> 

ale rozwiązanie to jest skomplikowane i nie działa dobrze, gdy mam wiele zagnieżdżonych DataTables na stronie .

Wszelkie pomysły, jak rozwiązać ten problem w lepszy sposób?

+0

Zobacz [http: // stackoverflow.com/questions/14633008/jsf-2-datatable-row-index-without-datamodel]. Ta odpowiedź jest nowsza niż te poniżej - również krótkie i słodkie. – fr13d

Odpowiedz

15

Istniejące rozwiązanie nie wydaje mi się takie złe. Argument rowIndex powinien działać w tabelach zagnieżdżonych, o ile odwołujesz się do modelu tabeli zagnieżdżonej. Model

<h:dataTable border="1" value="#{nestedDataModel}" var="nested"> 
     <h:column> 
      <h:dataTable border="1" value="#{nested}" var="item"> 
       <h:column> 
        <h:outputText value="#{nested.rowIndex}" /> 
       </h:column> 
       <h:column> 
        <h:outputText value="#{item}" /> 
       </h:column> 
      </h:dataTable> 
     </h:column> 
    </h:dataTable> 

Próbka:

public class NestedDataModel extends DataModel implements Serializable { 

    private List<List<String>> nestedDataModel = populateModel(); 
    private int index; 

    private List<List<String>> populateModel() { 
     List<List<String>> list = new ArrayList<List<String>>(); 
     for(int x=0; x<3; x++) { 
      List<String> nestedTableData = new ArrayList<String>(); 
      for(int y=0; y<3; y++) { 
       nestedTableData.add("Foo x="+x+" y="+y); 
      } 
      list.add(nestedTableData); 
     } 
     return list; 
    } 

    @Override 
    public int getRowCount() { 
     return nestedDataModel.size(); 
    } 

    @Override 
    public Object getRowData() { 
     List<String> list = nestedDataModel.get(index); 
     return new ListDataModel(list); 
    } 

    @Override 
    public int getRowIndex() { 
     return index; 
    } 

    @Override 
    public Object getWrappedData() { 
     return nestedDataModel; 
    } 

    @Override 
    public boolean isRowAvailable() { 
     return index >= 0 && index < nestedDataModel.size(); 
    } 

    @Override 
    public void setRowIndex(int arg0) { 
     index = arg0; 
    } 

    @Override 
    public void setWrappedData(Object arg0) { 
     throw new UnsupportedOperationException(); 
    } 

} 

zagnieżdżanie DataTables powinny być ogólnie unikać - jeśli nie jesteś ostrożny (np ich dzieci w formie), może to prowadzić do O (n^2) przekazywać dzieciom w tabeli dla każdej fazy cyklu życia na przesłanym (i jest 6 faz w cyklu życia).


czegoś, co jest na zewnątrz modelu, można użyć prostego licznika w zarządzanym fasoli:

public class RowCounter implements Serializable { 

    private transient int row = 0; 

    public int getRow() { 
     return ++row; 
    } 

} 

config:

<managed-bean> 
    <managed-bean-name>rowCounter</managed-bean-name> 
    <managed-bean-class>tablerows.RowCounter</managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

Widok:

<f:view> 
    <h:dataTable border="1" value="#{tableDataBean.tableDataModel}" 
     var="rowBean"> 
     <h:column> 
      <h:outputText value="#{rowCounter.row}" /> 
     </h:column> 
     <h:column> 
      <h:outputText value="#{rowBean}" /> 
     </h:column> 
    </h:dataTable> 
</f:view> 

Działa to, ponieważ fasola i s zakres żądania i związany z formantem tylko do odczytu poza formularzem. Nie działałoby to w zagnieżdżonej tabeli danych, chyba że chcesz, aby licznik wierszy był globalny dla widoku. Ale nie jestem przekonany, że indeks wiersza powinien być funkcją widoku.

W przypadku zagnieżdżonej tabeli danych lepiej byłoby podać indeks wiersza z komponentu bean wiersza. Zapewnia to większą kontrolę, jeśli zdecydujesz się również na podział stron na zestawy danych.

+2

Nice. Dlaczego tak trudno uzyskać numer wiersza z datownika JSF? Czy ludzie, którzy utrzymują JSF nienawidzą wszystkich innych programistów i celowo starają się to utrudnić? –

18

To rozwiązanie zostało opublikowane przez Jamie Williams pod numerem CodeRanch. Mówi, że działa z Tomahawk. Używam primefaces, który również to obsługuje.

<t:dataTable rowIndexVar="row" value="#{someBean.value}"> 
    <h:column> 
     <h:outputText value="#{row + 1}"/> 
    </h:column> 
</t:dataTable> 
+3

Komentarz Ursuli: "Dziękuję za rozwiązanie za pomocą rowIndexVar. Używam JSF 1.2 i myFaces, działa tylko bez spacji w wierszu + 1 ' '" –

4

W RichFaces istnieje rozwiązanie podobne do Brent:

<rich:dataTable value="#{backingBean.list}" var="v" rowKeyVar="index"> 
    <rich:column> 
     <f:facet name="header">Index</f:facet> 
     <h:outputText value="#{index + 1}" /> 
    </rich:column> 
    <rich:column> 
     <f:facet name="header">Name</f:facet> 
     <h:outputText value="#{v.name}" /> 
    </rich:column> 
</rich:dataTable> 
0

To działało tworzą mi

<h:dataTable var="item" value="#{controller.items}"> 
    <h:column>#{controller.items.indexOf(item)}</h:column> 
    <h:column>value</h:column> 
</h:dataTable> 
0

po prostu zależy na listy i stanowiska var na tej liście:

<h:column> 
      <f:facet name="header">#</f:facet> 
      #{bean.listValue.indexOf(varObject)+1} 
</h:column>