我正在尝试为我自己的项目扩展GWT的DataGrid功能,并希望添加到文件管理器列的功能。我已成功在Header中渲染过滤器框,但它没有响应事件。
以下是我的代码的relvant部分,它是根据此处给出的代码改编的:CellTable with custom Header containing SearchBox and Focus Problem
上述问题并不完全符合我的需求,因为如果列可以排序,它就不起作用。
相反,我开发了一个由2个表行(TR)组成的标题,第一行包含过滤框,第二行包含列标题并响应排序事件。 Sort事件工作正常,但过滤器框不响应任何事件。这是代码:
class HeaderBuilder extends AbstractHeaderOrFooterBuilder<Record> {
//HTML to render an Input Box
private InputBoxHTML inputBox = GWT.create(InputBoxHTML.class);
//List of columns in the table
private List<ListGridColumn<?>> columns = new ArrayList<ListGridColumn<?>>();
//Constructor. ListGrid is the outer class extending DataGrid
private HeaderBuilder() {
super(ListGrid.this, false);
}
@Override
protected boolean buildHeaderOrFooterImpl() {
TableRowBuilder tr = startRow();
tr.startTH().endTH(); //extra column
//Create top row of column headers - filter boxes for filterable columns, empty cells for non-filerable
for (ListGridColumn<?> column : this.columns) {
TableCellBuilder th = tr.startTH();
Header<String> header;
//If this column is filterable...
if (column.filter) {
//Create a new Cell containing an Input Box
AbstractCell<String> cell = new AbstractCell<String>("click","keydown","keyup") {
public void render(Context context, String value, SafeHtmlBuilder sb) {
sb.append(inputBox.input(""));
}
public void onBrowserEvent(Context context, Element parent, String value, NativeEvent event, ValueUpdater<String> valueUpdater) {
//These events never fire!
Window.alert("event");
}
};
header = new Header<String>(cell) {
public String getValue() {
return "value";
}
};
} else {
//Empty cell for non-filterable columns
header = new TextHeader("");
}
Context context = new Context(0, 0, header.getKey());
renderHeader(th, context, header);
th.endTH();
}
tr.endTR();
//Bottom row : header captions & sorting. This all works OK
tr = startRow();
tr.startTH().endTH(); //extra column
for (ListGridColumn<?> column : this.columns) {
TableCellBuilder th = tr.startTH();
enableColumnHandlers(th, column);
Header<String> header = new TextHeader(column.headerStr);
Context context = new Context(0, 0, header.getKey());
if (column.sortKey!=null) {
this.renderSortableHeader(th, context, header, true, true);
} else {
this.renderHeader(th, context, header);
}
th.endTH();
}
tr.endTR();
return true;
}
}
答案 0 :(得分:2)
如果查看insertColumn(int beforeIndex, Column col, Header header, Header footer)类中的AbstractCellTable方法的源代码(由DataGrid和CellTable扩展),则在插入(或添加)列的所有事件时(下沉单元格或页脚,以便将其从表格传播到相应的单元格:
if (header != null) {
Set<String> headerEvents = header.getCell().getConsumedEvents();
if (headerEvents != null) {
consumedEvents.addAll(headerEvents);
}
}
...
CellBasedWidgetImpl.get().sinkEvents(this, consumedEvents);
您在构建器中声明了Headers但没有“注册”它,因此事件不会传播到标题单元格。你应该找到一种方法来注册它。我没有看到任何干净的解决方案,因为DataGrid无法轻松扩展。
我可以告诉你两个脏的东西:
创建您的DataGrid版本(您需要复制并粘贴代码并在DataGrid的同一个包中声明它)并修改它以便为列注册两个标题。
创建一个新的标题,能够将事件传播到列中两个标题的正确实例。
我将选择2,创建一个内部有两个单元格的标题,您可以在构建器中使用这两个单元格。