Search code examples
flutterdatatablepaginateddatatable

How to Make the First Column Occupy More Space in PaginatedDataTable2 in Flutter?


I am working on a Flutter desktop application and using PaginatedDataTable2 to display a paginated table. I want the first column (e.g., "Product Name") to occupy more space than the other columns, but I’m having difficulty achieving this.

using: data_table_2 package

custom widget for Paginated Datatable

import 'package:data_table_2/data_table_2.dart';

class TpaginatedDatatable extends StatelessWidget {
  const TpaginatedDatatable(
      {super.key,
      this.rowPerPerPage = 25,
      required this.source,
      required this.columns,
      this.onPageChanged,
      this.dataRowHeight = 35,
      this.tableHeight = 786,
      this.minWidth,
      this.showCheckboxColumn = true});

  final int rowPerPerPage;
  final DataTableSource source;
  final List<DataColumn> columns;
  final Function(int)? onPageChanged;
  final double dataRowHeight;
  final double tableHeight;
  final double? minWidth;
  final bool showCheckboxColumn;

  @override
  Widget build(BuildContext context) {
    return PaginatedDataTable2(
      source: source,
      columns: columns,
      columnSpacing: 12,
      minWidth: minWidth,
      dividerThickness: 2.5,
      horizontalMargin: 12,
      rowsPerPage: rowPerPerPage,
      availableRowsPerPage: const [10, 20, 25],
      showFirstLastButtons: true,

      // Checkbox Column
      showCheckboxColumn: showCheckboxColumn,
      onPageChanged: onPageChanged,

      // pagination
      onRowsPerPageChanged: (noOfRows) {},
      renderEmptyRowsInTheEnd: false,
      dataRowHeight: dataRowHeight,
      headingTextStyle: Theme.of(context).textTheme.titleMedium,
      headingRowColor:
          WidgetStateProperty.resolveWith((states) => Colors.white),
      empty: Text("no data"),
      headingRowDecoration: BoxDecoration(),
    );
  }
}

using it

TpaginatedDatatable(
                columns: const [
                  DataColumn(label: Text("Product Name")),
                  DataColumn(label: Text("Ctn RP")),
                  DataColumn(label: Text("Psc RP")),
                  DataColumn(label: Text("Ctn TP")),
                  DataColumn(label: Text("Psc TP")),
                  DataColumn(label: Text("Ctn Qty")),
                  DataColumn(label: Text("Pcs Qty")),
                  DataColumn(label: Text("Bon (Rs)")),
                  DataColumn(label: Text("Dis (Rs)")),
                  DataColumn(label: Text("Dis (%)")),
                  DataColumn(label: Text("Total")),
                ],
                source: ProductDataSource(productController),
                showCheckboxColumn: true,
              )

Data Source

class ProductDataSource extends DataTableSource {
  final ProductController productController;

  ProductDataSource(this.productController);

  @override
  DataRow getRow(int index) {
    if (index >= productController.filteredData.length) {
      return const DataRow(cells: []);
    }

    final product = productController.filteredData[index];
    return DataRow(
      selected: productController.isSelected(product.id),
      onSelectChanged: (selected) {
        if (selected != null) {
          productController.toggleSelection(product.id);
          notifyListeners();
        }
      },
      cells: [
        DataCell(SizedBox(width: 200, child: Text(product.name))),
        DataCell(Text('Rs ${product.retailCtnPrice.toStringAsFixed(2)}')),
        DataCell(Text('Rs ${product.retailPcsPrice.toStringAsFixed(2)}')),
        DataCell(Text('Rs ${product.tradeCtnPrice.toStringAsFixed(2)}')),
        DataCell(Text('Rs ${product.tradePcsPrice.toStringAsFixed(2)}')),
        // DataCell(Text('PKR ${product.retail.toStringAsFixed(2)}')),
        DataCell(buildQuantityInput(
          controller: product.ctnQuantityController,
          onChanged: (newQty) {
            productController.updateCtnQuantity(index, newQty);
            notifyListeners();
          },
          enabled: productController.isSelected(product.id),
        )),
        DataCell(buildQuantityInput(
          controller: product.pcsQuantityController,
          onChanged: (newQty) {
            productController.updatePcsQuantity(index, newQty);
            notifyListeners();
          },
          enabled: productController.isSelected(product.id),
        )),
        DataCell(buildQuantityInput(
          controller: product.bonController,
          onChanged: (newBon) {
            productController.updateBon(index, newBon);
            notifyListeners();
          },
          enabled: productController.isSelected(product.id),
        )),
        DataCell(buildQuantityInput(
          controller: product.discountInRsController,
          onChanged: (newDiscount) {
            productController.updateDiscountInRs(index, newDiscount);
            notifyListeners();
          },
          enabled: productController.isSelected(product.id),
        )),
        DataCell(buildQuantityInput(
          controller: product.discountInPercentController,
          onChanged: (newDiscount) {
            productController.updateDiscountInPercent(index, newDiscount);
            notifyListeners();
          },
          enabled: productController.isSelected(product.id),
        )),
        DataCell(Text(
          'Rs ${productController.calculateProductTotal(product).toStringAsFixed(2)}',
          style: const TextStyle(
              fontSize: 14, fontWeight: FontWeight.bold, color: Colors.green),
        )),
      ],
    );
  }

  @override
  bool get isRowCountApproximate => false;
  @override
  int get rowCount => productController.filteredData.length;
  @override
  int get selectedRowCount => 0;
}

Solution try

I’ve tried the following approaches:

1) Using SizedBox:

I wrapped the label of the first column in a SizedBox with a specific width:

DataColumn(
  label: SizedBox(width: 200, child: Text("Product Name")),
)

It didn’t work as expected, as the width still seemed constrained.

2) Using Expanded with flex:

I tried using Row and Expanded in both the column header (DataColumn) and the data cells (DataCell):

DataCell(
  Row(
    children: [
      Expanded(
        flex: 2,
        child: Text("Product Name"),
      ),
    ],
  ),
);

The column didn’t expand as expected.

3) Adjusting minWidth and columnSpacing: I increased minWidth and reduced columnSpacing, but this didn’t resolve the issue.


Solution

  •  DataColumn2(
        label: Text('Column A'),
        size: ColumnSize.L,
    ),
    

    Do you have this option in your package? Maybe can help you...