我正在尝试创建一个包含一些文本和一个复选框的列的CellTable,它将用作全选复选框(参见下图,"cb"是复选框).目前我正在使用从Header派生的类并覆盖它的render方法来输出文本和一个复选框.我重写onBrowserEvent()但它只给我onChange事件,除了复选框无法正常工作外,它会正常工作.有没有人对此有任何想法?
+-------+------------+
| col 1 | Select All |
| | cb |
+-------+------------+
| row 1 | cb |
+-------+------------+
Run Code Online (Sandbox Code Playgroud)
我在复选框中遇到的问题是,如果没有选中,则必须单击两次以显示复选标记(至少在Chrome上),即使第一次"已检查"属性为真.单击一下即可正确取消选中它.
这是一些代码:
/** Setup the table's columns. */
private void setupTableColumns() {
// Add the first column:
TextColumn<MyObject> column1 = new TextColumn<MyObject>() {
@Override
public String getValue(final MyObject object) {
return object.getColumn1Text();
}
};
table.addColumn(macColumn, SafeHtmlUtils.fromSafeConstant("Column1"));
// the checkbox column for selecting the lease
Column<MyObject, Boolean> checkColumn = new Column<MyObject, Boolean>(
new CheckboxCell(true, false)) {
@Override
public Boolean getValue(final MyObject object) {
return selectionModel.isSelected(object);
}
};
SelectAllHeader selectAll = new SelectAllHeader();
selectAll.setSelectAllHandler(new SelectHandler());
table.addColumn(checkColumn, selectAll);
}
Run Code Online (Sandbox Code Playgroud)
public static class SelectAllHeader extends Header<Boolean> {
private final String checkboxID = "selectAllCheckbox";
private ISelectAllHandler handler = null;
@Override
public void render(final Context context, final SafeHtmlBuilder sb) {
String html = "<div>Select All<div><input type=\"checkbox\" id=\"" + checkboxID + "\"/>";
sb.appendHtmlConstant(html);
}
private final Boolean allSelected;
public SelectAllHeader() {
super(new CheckboxCell());
allSelected = false;
}
@Override
public Boolean getValue() {
Element checkboxElem = DOM.getElementById(checkboxID);
return checkboxElem.getPropertyBoolean("checked");
}
@Override
public void onBrowserEvent(final Context context, final Element element, final NativeEvent event) {
Event evt = Event.as(event);
int eventType = evt.getTypeInt();
super.onBrowserEvent(context, element, event);
switch (eventType) {
case Event.ONCHANGE:
handler.onSelectAllClicked(getValue());
event.preventDefault();
break;
default:
break;
}
}
public void setSelectAllHandler(final ISelectAllHandler handler) {
this.handler = handler;
}
}
Run Code Online (Sandbox Code Playgroud)
每当渲染标题时,您似乎都会渲染一个未选中的复选框,这可能会在每个单元格重新渲染时消除选择状态.
尝试存储已检查状态并使用状态呈现复选框.看起来你已经走了一半allSelected,你只是没有使用它.
编辑这是我刚刚为Zanata编写的一个工作实现(请参阅SearchResultsView.java).实现HasValue接口,以便可以以标准方式处理值更改事件.我没有覆盖渲染方法,如果你想这样做,请确保getValue()用于确定是否渲染已选中或未选中的复选框.选择/取消选择逻辑在相关的演示者类中处理(请参阅SearchResultsPresenter.java).
private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {
private boolean checked;
private HandlerManager handlerManager;
public CheckboxHeader()
{
//TODO consider custom cell with text
super(new CheckboxCell());
checked = false;
}
// This method is invoked to pass the value to the CheckboxCell's render method
@Override
public Boolean getValue()
{
return checked;
}
@Override
public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent)
{
int eventType = Event.as(nativeEvent).getTypeInt();
if (eventType == Event.ONCHANGE)
{
nativeEvent.preventDefault();
//use value setter to easily fire change event to handlers
setValue(!checked, true);
}
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler)
{
return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
}
@Override
public void fireEvent(GwtEvent<?> event)
{
ensureHandlerManager().fireEvent(event);
}
@Override
public void setValue(Boolean value)
{
checked = value;
}
@Override
public void setValue(Boolean value, boolean fireEvents)
{
checked = value;
if (fireEvents)
{
ValueChangeEvent.fire(this, value);
}
}
private HandlerManager ensureHandlerManager()
{
if (handlerManager == null)
{
handlerManager = new HandlerManager(this);
}
return handlerManager;
}
}
Run Code Online (Sandbox Code Playgroud)