Skip to content

Feature: Row Grouping #256

@szal1k

Description

@szal1k

Introduce a row grouping feature for data-table-bundle, inspired by the behavior of the DataTables RowGroup extension.

The feature allows grouping rows based on a selected data field, automatically inserting group header rows into the table and optionally rendering summary information for each group.

Grouping improves data readability by visually structuring rows into logical sections.

1. Grouping by data source (column)

Rows are grouped based on a selected field (column or data property).

All rows sharing the same value are displayed under a common group
The grouping field does not need to be visible in the table
Grouping can be dynamically changed at runtime

Example:

  • Group by office
  • All rows with office = "Tokyo" appear under one group

2. Automatic group row rendering

The table automatically inserts group header rows into the dataset:

A new row is inserted when group value changes
The row spans across the table (or aligns with columns if customized)
Displays the group label (e.g. Office: Tokyo)

This row is not part of the original dataset — it is generated dynamically.

3. Custom group rendering (start / end rows)

Developers can customize how grouping rows are rendered:

  • start row (group header)
  • end row (group footer)

Custom rendering allows:

  • injecting HTML rows
  • aligning with table columns
  • displaying additional metadata

4. Aggregations / summaries per group

Grouping rows can include computed values based on group data:

  • count of rows
  • sum of numeric columns
  • averages
  • custom metrics

Example:

  • Office: Tokyo | Employees: 12 | Total salary: $2,400,000

Custom aggregation rows can be rendered as full table rows aligned with columns.

5. Multi-level grouping

Support grouping by multiple fields:

  • first level: country
  • second level: city

This creates nested grouping structures.

6. Integration with sorting

Grouping is tightly coupled with ordering:

  • data is typically sorted by grouping column
  • grouping updates automatically after sorting
  • user can change sorting independently

7. Dynamic enable / disable

Grouping can be:

  • enabled or disabled at runtime
  • switched to another column dynamically

Example:

  • “Group by Office”
  • “Group by Position”
  • “Ungroup”

UX Behavior (based on example)

Group headers visually separate sections
Groups are displayed inline (not as nested tables)
Data remains a flat structure with inserted grouping rows
No pagination reset — grouping respects current view
Works with Ajax / server-side data
Mapping to data-table-bundle (conceptual)

This example implies:

  • grouping is data-driven (by field name)
  • grouping rows are virtual rows
  • summaries are computed on the fly
  • rendering is customizable
  • grouping is compatible with sorting & filtering
use Kreyu\Bundle\DataTableBundle\RowGroup\RowGroupingConfiguration;
use Kreyu\Bundle\DataTableBundle\RowGroup\AggregationDefinition;
use Kreyu\Bundle\DataTableBundle\RowGroup\AggregationType;

public function buildDataTable(DataTableBuilderInterface $builder, array $options): void
{
    $builder
        ->addColumn('name')
        ->addColumn('office')
        ->addColumn('salary')
    ;

    // Enable row grouping
    $builder->setRowGroupingEnabled(true);
    $builder->setRowGroupingConfiguration(
        (new RowGroupingConfiguration())
            ->setFields(['office'])                        // group by office
            ->addAggregation(new AggregationDefinition(
                'salary', AggregationType::Sum, 'Total Salary', '[salary]'
            ))
            ->setEndRenderer(fn ($value, $field, $level, $aggs, $count) => [
                'summary' => "$value: $count employees",
            ])
    );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions