2

Is it possible to add a summarizing row into a Vaadin Grid?

I currently have a grid that has a header row to join columns and give a good overview at the top. However, I would like to add similar headers throughout the grid in order to mark the end of a section. It appears to only be possible to add headers in the header section which will simply fill up the head of the grid. Footers do the same at the bottom.

But what if I want a special row within the grid without having to create a new grid component? One that would be a visible data separator.

LML
  • 53
  • 6

1 Answers1

2

Depending on what you need and how complicated your app is, you can fake something with some (possibly minor) effort. You can find below a simple example which should get you started.

1) Common class to use with BeanItemContainer to display both categories of rows

public abstract class Row {
    private String name;
    private int amount;

    public Row(String name, int amount) {
        this.name = name;
        this.amount = amount;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    // provide a custom style/type for the current row
    public abstract String getRowType();
}

2) Regular product row

public class ProductRow extends Row {
    public ProductRow(String name, int amount) {
        super(name, amount);
    }

    @Override
    public String getRowType() {
        return "product-row";
    }
}

3) Special row to display the total for the previous batch of products

public class TotalRow extends Row {
    public TotalRow(int sum) {
        super("Total", sum);
    }

    @Override
    public String getRowType() {
        return "total-row";
    }
}

4) The grid itself

public class GridWithIntermediateRowsComponent extends VerticalLayout {
    private static final String[] AVAILABLE_PRODUCTS = new String[]{"Banana", "Apple", "Coconut", "Pineapple", "Melon"};
    private Random random = new Random();

    public GridWithIntermediateRowsComponent() {
        BeanItemContainer<Row> container = new BeanItemContainer<>(Row.class);
        Grid grid = new Grid(container);

        // show only the relevant columns, the style one is used only to change the background
        grid.setColumns("name", "amount");

        // set a style generator so we can draw the "total" rows differently
        grid.setCellStyleGenerator(row -> ((Row) row.getItemId()).getRowType());

        // create some dummy data to display
        for (int i = 0; i < random.nextInt(10) + 1; i++) {
            container.addAll(createItemBatch(random.nextInt(5) + 1));
        }

        addComponent(grid);
    }

    private List<Row> createItemBatch(int total) {
        List<Row> rows = new ArrayList<>(total + 1);

        // add a batch of products
        String product = AVAILABLE_PRODUCTS[random.nextInt(AVAILABLE_PRODUCTS.length)];
        for (int i = 0; i < total; i++) {
            rows.add(new ProductRow(product, random.nextInt(100) + 1));
        }

        // calculate and add a "total row"
        rows.add(calculateTotal(rows));

        return rows;
    }

    private Row calculateTotal(List<Row> rows) {
        return new TotalRow(rows.stream().mapToInt(Row::getAmount).sum());
    }
}

5) Theme styles

@mixin mytheme {
  @include valo;
  // Insert your own theme rules here

  .v-grid-row > td.total-row {
    background-color: #c4e7b7;
    font-weight: bold;
  }
}

6) Result

Custom intermediate total rows

Morfic
  • 15,178
  • 3
  • 51
  • 61
  • Thanks for the detailed answer. So basically my only choice would be to add an extra row with the needed information + CSS-style that as a special row? I was really hoping to be able to also do a column join as you can do in headers. I would prefer that over doing multiple grids under one another – LML Jul 28 '16 at 13:08
  • From what I've read you also can't do colspan within a grid? While I loved the grid for its simple editing set up, the manipulation for displaying seems to be heavily limited. Is the table basically deprecated since the Grid or does it allow better options for this? – LML Jul 28 '16 at 13:14
  • @LML As far as I know, [spanning is only supporter in headers/footers](https://vaadin.com/docs/-/part/framework/components/components-grid.html#components.grid.headerfooter.joining) for the time being. You're correct, [table is being deprecated since the grid](http://stackoverflow.com/questions/30134479/vaadin-grid-vs-table), but I don't think it offers better options for this, it'd be pretty much the same. – Morfic Jul 28 '16 at 13:35
  • that's very unfortunate for my use case. I will have see how the styling works out for clarity purposes in showing grouped segments. Thanks for your feedback – LML Jul 28 '16 at 13:42
  • @LML If you're not already familiar with them, you can start by taking a look at the [Vaadin docs to understand how themes are built are built and how they work](https://vaadin.com/docs/-/part/framework/themes/themes-overview.html) . Good luck – Morfic Jul 28 '16 at 13:55