我正在使用primefaces 4.0,JSF Mojarra 2.2.2 这是我的数据表代码:
<p:dataTable id="tabexam"
paginatorPosition="bottom"
var="exam"
value="#{dyna.examViewDataModel}"
widgetVar="examTable"
emptyMessage="aucun résultat trouvé pour votre recherche"
paginator="true"
rows="40"
selection="#{dyna.selectedExamen}"
filteredValue="#{dyna.filteredexams}"
selectionMode="single"
resizableColumns="true"
draggableColumns="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="40,80,120">
<p:columns value="#{datatableBean.table}"
var="column"
headerText="#{column.userListname}"
rendered="#{column.visible}"
resizable="#{column.resizable}"
width="#{column.width}"
columnIndexVar="colIndex">
<h:panelGroup>
<p:outputLabel value="#{column.dbname}" styleClass="fonty"/>
</h:panelGroup>
</p:columns>
</p:dataTable>
这是我到目前为止所尝试的内容,但是我在控制台中为getHeaderText获取空字符串并且空宽度也是如此,我想知道我缺少什么
UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
DataTable tabler = (DataTable) view.findComponent(":form1:tabexam");
List<UIColumn> coler = tabler.getColumns();
for (int i = 0; i < coler.size(); i++) {
System.out.println("/////////////////");
System.out.println(coler.get(i).getValueExpression("headerText").getValue(FacesContext.getCurrentInstance().getELContext()));
System.out.println(coler.get(i).getHeaderText());
System.out.println(coler.get(i).isRendered());
System.out.println(coler.get(i).isResizable());
System.out.println(coler.get(i).getWidth());
System.out.println("/////////////////");
}
System.out.println(coler.size());
请注意coler.size()
给出了数据表中显示的列数。
但是coler.get(i).getHeaderText()
总是给出空字符串。
答案 0 :(得分:9)
p:column
p:columns
DataTable.getColumns不会返回您期望的内容:
public List<UIColumn> getColumns() {
if(columns == null) {
columns = new ArrayList<UIColumn>();
FacesContext context = getFacesContext();
char separator = UINamingContainer.getSeparatorChar(context);
for(UIComponent child : this.getChildren()) {
if(child instanceof Column) {
columns.add((UIColumn) child);
}
else if(child instanceof Columns) {
Columns uiColumns = (Columns) child;
String uiColumnsClientId = uiColumns.getClientId(context);
for(int i=0; i < uiColumns.getRowCount(); i++) {
DynamicColumn dynaColumn = new DynamicColumn(i, uiColumns);
dynaColumn.setColumnKey(uiColumnsClientId + separator + i);
columns.add(dynaColumn);
}
}
}
}
return columns;
}
这会返回一个合成仿真:每列只有columnKey
,并且正如您所说,正确的列数。
一般来说,p:columns
是一个组件,当你从控制器层访问它时,你必须引用它的DECLARATION(单个组件)而不是它的REPRESENTATION(多个列)
p:columns
支持#{datatableBean.table}
,因此您应该已经拥有了从DataTable组件获取的所有信息,并采用了反向工程方式。<强>更新强>
哦,现在我意识到你想做什么。你必须使用事件监听器。 来自PF展示的:
<p:dataTable var="car" value="#{tableBean.carsSmall}" widgetVar="cars" draggableRows="true">
<p:ajax event="colReorder" listener="#{tableBean.onColReorder}" update=":some:component" />
<p:ajax event="colResize" listener="#{tableBean.onColResize}" update=":some:component"/>
<!-- columns here -->
</p:dataTable>
在支持bean中监听这些事件并保留这些信息应解决您的问题
更新2
哇,这根本不简单。
由于动态列调整大小的Primefaces错误(至少对于我的尝试)和不完整的列重新排序事件实现,这就是出现的结果:
<h:form id="form">
<h:panelGroup id="model">
<ui:repeat var="column2" value="#{testBean.columnList2}">
<div>#{column2.title} - #{column2.width}</div>
</ui:repeat>
</h:panelGroup>
<p:dataTable var="elem" value="#{testBean.elementList}" resizableColumns="true" draggableColumns="true">
<p:ajax event="colReorder" listener="#{testBean.onColumnReorder}" update=":form:model" />
<p:ajax event="colResize" listener="#{testBean.onColumnResize}" update=":form:model"/>
<c:forEach var="column" items="#{testBean.columnList}">
<p:column headerText="#{column.title}" rendered="#{column.visible}" width="#{column.width}">
<f:attribute name="myCol" value="#{column}"/>
<span>#{elem[column.property]}</span>
</p:column>
</c:forEach>
</p:dataTable>
</h:form>
和这个bean:
@ManagedBean
@ViewScoped
public class TestBean implements Serializable
{
private static final long serialVersionUID = 1L;
private List<MyColumn> columnList;
private List<MyColumn> columnList2;
private List<MyElement> elementList;
public class MyColumn
{
private String title;
private String property;
private boolean visible = true;
private boolean resizable = true;
private int width = 100;
public MyColumn(String title, String property, boolean visible, boolean resizable, int width)
{
super();
this.title = title;
this.property = property;
this.visible = visible;
this.resizable = resizable;
this.width = width;
}
// getters and setters
}
public class MyElement
{
private String code;
private String name;
private String type;
public MyElement(String code, String name, String type)
{
super();
this.code = code;
this.name = name;
this.type = type;
}
// getters and setters
}
@PostConstruct
public void init()
{
columnList = new ArrayList<>();
columnList.add(new MyColumn("element code", "code", true, true, 100));
columnList.add(new MyColumn("element name", "name", true, true, 100));
columnList.add(new MyColumn("element type", "type", true, true, 100));
columnList2 = new ArrayList<>(columnList);
elementList = new ArrayList<>();
elementList.add(new MyElement("001", "foo", "normal"));
elementList.add(new MyElement("002", "bar", "strange"));
elementList.add(new MyElement("003", "xyz", "normal"));
elementList.add(new MyElement("004", "abc", "nothing"));
}
public void onColumnResize(ColumnResizeEvent event)
{
UIColumn column = event.getColumn();
int width = event.getWidth();
UIComponent colComponent = (UIComponent) column;
MyColumn myCol = (MyColumn) colComponent.getAttributes().get("myCol");
myCol.setWidth(width);
}
public void onColumnReorder(AjaxBehaviorEvent event)
{
DataTable table = (DataTable) event.getSource();
columnList2.clear();
for(UIColumn column : table.getColumns())
{
UIComponent colComponent = (UIComponent) column;
MyColumn myCol = (MyColumn) colComponent.getAttributes().get("myCol");
columnList2.add(myCol);
}
}
// getters and setters
}
更新了代码,您可以在columnList2
中找到有序列。现在也显示在表格中。
现在您可以使用columnList2
将oreder和width存储到db。