如何从ManagedBean获取原始数据列的顺序和宽度 [英] how to get primefaces datatable columns order and width from ManagedBean
问题描述
我使用的是原点4.0,JSF Mojarra 2.2.2
,这里是我的datatable代码:
< p:dataTable id =tabexam
paginatorPosition =bottom
var =exam
value =#{dyna.examViewDataModel}
widgetVar =examTable
emptyMessage =aucunrésultattrouvé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}
render =#{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);
列表< UIColumn> coler = tabler.getColumns(); (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()
总是给空字符串。
你错了什么:
- 不要嵌套
p:column
in
p:columns
-
DataTable.getColumns不返回您的期望:
public List< UIColumn> getColumns(){
if(columns == null){
columns = new ArrayList< UIColumn>();
FacesContext context = getFacesContext();
char separator = UINamingContainer.getSeparatorChar(context); (UIComponent child:this.getChildren()){
if(child instanceof Column){
columns.add((UIColumn)child);
}
else if(child instanceof Columns){
列uiColumns =(Columns)child;
String uiColumnsClientId = uiColumns.getClientId(context); (int i = 0; i< uiColumns.getRowCount(); i ++){
DynamicColumn dynaColumn = new DynamicColumn(i,uiColumns);
dynaColumn.setColumnKey(uiColumnsClientId + separator + i);
columns.add(dynaColumn);
}
}
}
}
返回列;
}
仿真:每列只有 columnKey
,正如你所说,正确的列数。
一般来说, p:columns
是一个组件,当您从控制器层访问它时,您必须参考其声明(单个组件)而不是其REPRESENTATION(多列)
p:columns
,所以- .table} 您应该已经以反向设计的方式拥有您尝试从DataTable组件获取的所有信息。
更新
哦,现在我意识到你想要做什么您必须使用事件监听器。
从PF展示:
< p:dataTable var =carvalue =#{tableBean.carsSmall}widgetVar =carsdraggableRows =true>
< p:ajax event =colReorderlistener =#{tableBean.onColReorder}update =:some:component/>
< p:ajax event =colResizelistener =#{tableBean.onColResize}update =:some:component/>
<! - 这里列 - >
< / p:dataTable>
在支持bean和mantain中监听这些事件,这些信息应该可以解决你的问题。
$ b
更新2
whew,这根本不简单。
由于原始动态列调整大小的错误(至少对我的尝试)和不完整的列重新排序事件实现,这是出来的:
< h:form id =form>
< h:panelGroup id =model>
< ui:repeat var =column2value =#{testBean.columnList2}>
< div>#{column2.title} - #{column2.width}< / div>
< / ui:repeat>
< / h:panelGroup>
< p:dataTable var =elemvalue =#{testBean.elementList}resizableColumns =truedraggableColumns =true>
< p:ajax event =colReorderlistener =#{testBean.onColumnReorder}update =:form:model/>
< p:ajax event =colResizelistener =#{testBean.onColumnResize}update =:form:model/>
< c:forEach var =columnitems =#{testBean.columnList}>
< p:column headerText =#{column.title}rendered =#{column.visible}width =#{column.width}>
< f:attribute name =myColvalue =#{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;
私人列表< MyColumn> columnList;
私人列表< MyColumn> columnList2;
私人列表< 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;
}
// getter和setter
}
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;
}
// getter和setter
}
@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)列;
MyColumn myCol =(MyColumn)colComponent.getAttributes()。get(myCol);
myCol.setWidth(width);
}
public void onColumnReorder(AjaxBehaviorEvent event)
{
DataTable table =(DataTable)event.getSource();
columnList2.clear();
(UIColumn列:table.getColumns())
{
UIComponent colComponent =(UIComponent)列;
MyColumn myCol =(MyColumn)colComponent.getAttributes()。get(myCol);
columnList2.add(myCol);
}
}
// getters和setter
}
更新的代码,您可以在 columnList2
中找到有序列。现在也以形式显示。
现在您可以使用 columnList2
来存储oreder和宽度到db。
i'm using primefaces 4.0, JSF Mojarra 2.2.2 and here is my datatable code :
<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>
Here what I've tried so far, but I get empty Strings for getHeaderText in the console and empty width too, i wonder what i'm missing
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());
Note that coler.size()
gives the number of columns shown on the datatable.
but the coler.get(i).getHeaderText()
always gives empty String.
you are mistaking something:
- do not nest
p:column
insidep:columns
DataTable.getColumns does not return what you expect:
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; }
this returns a synthetic emulation: only columnKey
per column, and, as you stated, the correct number of columns.
generally speaking, p:columns
is ONE component and when you access it from controller layer, you have to refer to its DECLARATION (single component) instead of its REPRESENTATION (multiple columns)
- since you are backing
p:columns
with your#{datatableBean.table}
you should already have all the information you are trying to get from DataTable component, in a reverse-engineered fashion.
update
oh, now i realize what you want to do. you have to use event listeners for that.
from PF showcase:
<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>
listening for these events in backing bean and mantain these informations should solve your problem
update 2
whew, it was not simple at all.
due to Primefaces bug for dynamic column resizing (at least for my tries) and incomplete column reordering event implementation, this is what came out:
<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>
and this 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
}
updated code, you can find ordered columns in columnList2
. now are also shown in the form.
now you can use columnList2
to store oreder and widths to db.
这篇关于如何从ManagedBean获取原始数据列的顺序和宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!