3

自分のプロジェクト用に GWT の DataGrid 機能を拡張しようとしていますが、その機能をファイラー列に追加したいと考えています。ヘッダーにフィルター ボックスを表示しましたが、イベントに応答しません。

以下は、ここで与えられたコードから適応された私のコードの関連部分です:検索ボックスとフォーカスの問題を含むカスタム ヘッダーを持つ CellTable

上記の質問は、列がソート可能である場合は機能しないため、私のニーズには完全には適合しません。

代わりに、2 つのテーブル行 (TR) で構成されるヘッダーを開発しました。一番上の行にはフィルター ボックスが含まれ、2 番目の行には列のタイトルが含まれ、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;
    }

}
4

1 に答える 1

2

AbstractCellTableクラス (DataGrid および CellTable によって拡張される) のinsertColumn(int beforeIndex, Column col, Header header, Header footer)メソッドのソース コードを見ると、列が挿入 (または追加) されると、ヘッダー (セルまたはフッター) は、テーブルから対応するセルに伝播するためにシンクされます。

if (header != null) {
  Set<String> headerEvents = header.getCell().getConsumedEvents();
  if (headerEvents != null) {
    consumedEvents.addAll(headerEvents);
  }
}
...
CellBasedWidgetImpl.get().sinkEvents(this, consumedEvents);

ビルダーでヘッダーを宣言していますが、それを「登録」していないため、イベントはヘッダー セルに伝達されません。登録する方法を見つける必要があります。DataGrid は簡単に拡張できないため、クリーンなソリューションはありません。

私はあなたに2つの汚いものを与えることができます:

  1. DataGrid のバージョンを作成し (コードをコピーして貼り付け、DataGrid の同じパッケージで宣言する必要があります)、列の 2 つのヘッダーを登録するために変更します。

  2. 列内の 2 つのヘッダーの正しいインスタンスにイベントを伝達できる新しいヘッダーを作成します。

私は 2 に行き、内部に 2 つのセルを持つヘッダーを作成します。これらの 2 つのセルをビルダーで使用できます。

于 2013-11-18T11:09:18.670 に答える