6

テキストとチェックボックスを含む列を持つCellTableを作成しようとしています。このチェックボックスは、[すべて選択]チェックボックスとして使用されます(下の図を参照してください。「cb」はチェックボックスです)。現在、Headerから派生したクラスを使用しており、そのrenderメソッドをオーバーライドして、テキストとチェックボックスを出力しています。onBrowserEvent()をオーバーライドしていますが、onChangeイベントのみが表示されます。これは、チェックボックスが正しく機能しないことを除いて正常に機能します。誰かがこれについて何か考えを持っていますか?

+-------+------------+
| col 1 | Select All |
|       |     cb     | 
+-------+------------+
| row 1 |     cb     |
+-------+------------+

チェックボックスで私が抱えている問題は、チェックされていない場合、最初に「チェックされた」プロパティがtrueであっても、チェックマークが表示されるようにするには2回クリックする必要があることです(少なくともChromeでは)。ワンクリックで正しくチェックを外します。

ここにいくつかのコードがあります:

CellTable列を設定します。

/** 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);
}

私のすべてのヘッダーを選択:

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;
    }

}
4

1 に答える 1

7

ヘッダーをレンダリングするたびにチェックされていないチェックボックスをレンダリングしているように見えます。これにより、セルテーブルが再レンダリングされるたびに選択状態が消去される可能性があります。

チェックされた状態を保存し、チェックボックスを状態とともにレンダリングしてみてください。中途半端なようですが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;
   }
}
于 2012-04-18T03:16:19.290 に答える