How to insert 'sub-rows' into a Wicket DataTable
Asked Answered
R

2

8

I have an AjaxFallbackDefaultDataTable which contains one row per test result. A test result may have a note attached to it, which needs to be displayed prominently below the test result, hopefully giving a table similar to the following:

| Test | Result | Appraisal |
|------|--------|-----------|
|  1   |  20.0  |   PASS    |
|  2   |  1.50  |   FAIL    |
| Note: This is an epic fail|
|  3   |  19.4  |   PASS    |
|  4   |  14.9  |   PASS    |

Is there any way to achieve this row insertion (preferably with column spanning) using the Wicket DataTable constructs. As I dig down into the source I can find Item renderers but nothing that deals with a row.

Currently I have the following:

// Create the sortable data provider.
SortableDataProvider<TestResult> provider = new SortableDataProvider<TestResult>() {
    //... hibernate pagination code ...
};

List<IColumn> columns = new ArrayList<IColumn>();
columns.add(new TextFilteredPropertyColumn(new Model<String>("Test"), "test", "test"));
columns.add(new TextFilteredPropertyColumn(new Model<String>("Result"), "result", "result"));
columns.add(new TextFilteredPropertyColumn(new Model<String>("Appraisal"), "appraisal", "appraisal"));

// Create a new AJAX table using the sortable, filtered data provider.
final AjaxFallbackDefaultDataTable dataTable = new AjaxFallbackDefaultDataTable("testResultTable", columns.toArray(new IColumn[0]), provider, 20);// 20 = number of rows per page
Reflection answered 29/9, 2010 at 13:59 Comment(0)
I
11

I don't think there is a clean way to do that, you will have to hack the resulting HTML.

I'd attach a custom behavior to the rows that generates the required HTML automatically, something like this:

new AjaxFallbackDefaultDataTable<MyCustomObject>(
    id, columns, dataProvider, rowsPerPage){

    @Override
    protected Item<MyCustomObject> newRowItem(String id,
        int index,
        final IModel<MyCustomObject> model){
        Item<MyCustomObject> item = super.newRowItem(id, index, model);
        item.add(new AbstractBehavior(){

            private static final long serialVersionUID = 1L;

            /**
             * {@inheritDoc}
             */
            @Override
            public void onRendered(Component component){
                if(model.getObject().isEpicFail()){
                    component.getResponse().write(
                    "<tr><td colspan=\"3\">This is an epic fail</td></tr>");
                }
            }

        });
        return item;
    }

    private static final long serialVersionUID = 1L;

}
Insinuate answered 29/9, 2010 at 16:37 Comment(3)
That is both absolutely spot on and a very quick reply. Many thanks for that, I've been scratching my head about this problem for the past week. Cheers!Reflection
No prob. Wicket is actually easy once you wrap your head around it, but that takes some time.Insinuate
It is kinda ugly to render your own HTML :o. But overriding the newRowItem is a good start, you should create a Panel and add that to the item.Internationalist
T
0

If look at class NavigationToolbar (extension, DataTable) when looking from point of view HTML there is one row of html table, object construction is quite different but result is good, other data are presented in HTML row not being a row in sense Java table (from code that navigator isn't part of object table, is external from such point of view.

Nice fragment code to analyse

When my enriched Datatable for data will be platform to visually present reports with subtotal, I know this will be possible

Twickenham answered 4/9, 2015 at 20:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.