JSF dataTableで、行の横に行インデックスを表示します...
Column A Column B
1 xxx
2 yyy
#{rowIndex}のような暗黙のel変数を使用できると考えましたが、これは機能していません。
私が見つけた解決策は、データテーブルのバインディングを作成し、次のようなバインディングを使用することです:
<h:dataTable var="item" value="#{controller.items}" binding="#{controller.dataTable}">
<h:column>#{controller.dataTable.rowIndex}</h:column>
<h:column>value</h:column>
</h:dataTable>
しかし、このソリューションは複雑で、ページに多くのネストされたdataTableがある場合はうまく機能しません。
これをより良い方法で解決する方法についてのアイデアはありますか?
既存のソリューションは、私を悪いものとしては思いません。 rowIndexは、ネストしたテーブルのモデルを参照している限り、ネストしたテーブルで機能するはずです。
<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>
サンプルモデル:
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();
}
}
DataTablesのネストは一般的に避けるべきです-注意しない場合(たとえば、フォームの子にするなど)、これにより、サブミットのライフサイクルの各フェーズでテーブルの子をO(N ^ 2)で渡すことができます(そしてライフサイクルには6つのフェーズがあります)。
モデルの外部にあるものについては、マネージドBeanで単純なカウンターを使用できます。
public class RowCounter implements Serializable {
private transient int row = 0;
public int getRow() {
return ++row;
}
}
構成:
<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>
見る:
<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>
これは、Beanが要求スコープであり、フォームの外部の読み取り専用コントロールにバインドされているため機能します。行カウンターをビューに対してグローバルにする場合を除き、ネストされたdataTableでは機能しません。しかし、その後、私は行インデックスがビューの関数であるべきだとは確信していません。
ネストされたdataTableの場合、行Beanから行インデックスを提供する方が適切です。データセットのページネーションのようなことをすることに決めた場合、それはあなたにより多くの制御を与えます。
このソリューションは CodeRanch でJamie Williamsによって投稿されました。彼はそれがトマホークで動作すると言います。プライムフェイスを使用していますが、これもサポートしています。
<t:dataTable rowIndexVar="row" value="#{someBean.value}">
<h:column>
<h:outputText value="#{row + 1}"/>
</h:column>
</t:dataTable>
RichFacesには、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>
これは私から働いた
<h:dataTable var="item" value="#{controller.items}">
<h:column>#{controller.items.indexOf(item)}</h:column>
<h:column>value</h:column>
</h:dataTable>
私は単にこのリストのリストとvarの位置に依存しています:
<h:column>
<f:facet name="header">#</f:facet>
#{bean.listValue.indexOf(varObject)+1}
</h:column>