Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[syncfusion_flutter_datagrid]: onQueryRowHeight doesn't correctly adjust the height of the row depend on the content. #2248

Open
wartelski opened this issue Jan 7, 2025 · 2 comments
Labels
data grid Data grid component uncertain Uncertain feature waiting for customer response Cannot make further progress until the customer responds.

Comments

@wartelski
Copy link

Bug description

I need to change the height of the row in case if the content inside of the cell gets bigger.
Screenshot 2025-01-07 at 4 41 36 PM

I found that the best solution for this is to use onQueryRowHeight. But, for some reason, it doesn't work as expected.

Here is an example

  • when there is not enough space in the cell, the second button goes under the first button. That's expected behavior, and onQueryRowHeight does the correct job here.
 GridColumn(
            columnName: 'button',
            width: 100,
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Details'),
            ),
          ),
Screenshot 2025-01-07 at 4 34 02 PM
  • when there is enough space in the cell and two buttons in the row, then for some reason the height is still the same as if the two buttons were under each other. onQueryRowHeight does NOT work properly in this case. Why is there so much height applied?
 GridColumn(
            columnName: 'button',
            width: 300,
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Details'),
            ),
          ),
Screenshot 2025-01-07 at 4 36 49 PM

without using onQueryRowHeight:
Screenshot 2025-01-07 at 4 41 01 PM

My expectation is:

  • when there is enough space in the cell, it should look like this::
Screenshot 2025-01-07 at 4 41 01 PM
  • when there is not enough space in the cell, it should look like this:
Screenshot 2025-01-07 at 4 34 02 PM

Thank you.

Steps to reproduce

  1. apply onQueryRowHeight
  2. add two buttons in the cell
  3. make the width of the cell big enough, so the button will follow each other.

Code sample

Code sample
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';

void main() {
  runApp(MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SfDataGridDemo()));
}

class SfDataGridDemo extends StatefulWidget {
  const SfDataGridDemo({Key? key}) : super(key: key);

  @override
  _SfDataGridDemoState createState() => _SfDataGridDemoState();
}

class _SfDataGridDemoState extends State<SfDataGridDemo> {
  List<Employee> _employees = <Employee>[];
  late EmployeeDataSource _employeeDataSource;

  @override
  void initState() {
    super.initState();
    _employees = getEmployeeData();
    _employeeDataSource = EmployeeDataSource(_employees);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter SfDataGrid'),
      ),
      body: SfDataGrid(
        source: _employeeDataSource,
        onQueryRowHeight: (details) {
          return details.getIntrinsicRowHeight(details.rowIndex);
        },
        columnWidthMode: ColumnWidthMode.fill,
        columns: [
          GridColumn(
            columnName: 'id',
            width: 50,
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('ID'),
            ),
          ),
          GridColumn(
            columnName: 'name',
            width: 50,
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Name'),
            ),
          ),
          GridColumn(
            columnName: 'designation',
            width: 50,
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Designation'),
            ),
          ),
          GridColumn(
            columnName: 'button',
            width: 220,
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Details'),
            ),
          ),
        ],
      ),
    );
  }

  List<Employee> getEmployeeData() {
    return [
      Employee(10001, 'James', 'Project Lead '),
      Employee(10002, 'Kathryn', 'Manager'),
      Employee(10003, 'Lara', 'Developer'),
      Employee(10004, 'Michael', 'Designer'),
      Employee(10005, 'Martin', 'Developer'),
      Employee(10006, 'Newberry', 'Developer'),
      Employee(10007, 'Balnc', 'Developer'),
      Employee(10008, 'Perry', 'Developer'),
      Employee(10009, 'Gable', 'Developer'),
      Employee(10010, 'Grimes', 'Developer'),
    ];
  }
}

class EmployeeDataSource extends DataGridSource {
  EmployeeDataSource(List<Employee> employees) {
    buildDataGridRow(employees);
  }

  void buildDataGridRow(List<Employee> employeeData) {
    dataGridRow = employeeData.map<DataGridRow>((employee) {
      return DataGridRow(cells: [
        DataGridCell<int>(columnName: 'id', value: employee.id),
        DataGridCell<String>(columnName: 'name', value: employee.name),
        DataGridCell<String>(
            columnName: 'designation', value: employee.designation),
        const DataGridCell<Widget>(columnName: 'button', value: null),
      ]);
    }).toList();
  }

  List<DataGridRow> dataGridRow = <DataGridRow>[];

  @override
  List<DataGridRow> get rows => dataGridRow.isEmpty ? [] : dataGridRow;

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
      cells: row.getCells().map<Widget>((dataGridCell) {
        return Container(
          alignment: Alignment.center,
          child: dataGridCell.columnName == 'button'
              ? LayoutBuilder(
                  builder: (BuildContext context, BoxConstraints constraints) {
                    return Wrap(
                      spacing: 4.0,
                      runSpacing: 4.0,
                      children: [
                        ElevatedButton(
                          onPressed: () {
                            showDialog(
                              context: context,
                              builder: (context) => AlertDialog(
                                content: SizedBox(
                                  height: 100,
                                  child: Column(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceBetween,
                                    children: [
                                      Text(
                                          'Employee ID: ${row.getCells()[0].value.toString()}'),
                                      Text(
                                          'Employee Name: ${row.getCells()[1].value.toString()}'),
                                      Text(
                                          'Employee Designation: ${row.getCells()[2].value.toString()}'),
                                    ],
                                  ),
                                ),
                              ),
                            );
                          },
                          child: const Text('Details'),
                        ),
                        ElevatedButton(
                          onPressed: () {
                            showDialog(
                              context: context,
                              builder: (context) => AlertDialog(
                                content: SizedBox(
                                  height: 100,
                                  child: Column(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceBetween,
                                    children: [
                                      Text(
                                          'Employee ID: ${row.getCells()[0].value.toString()}'),
                                      Text(
                                          'Employee Name: ${row.getCells()[1].value.toString()}'),
                                      Text(
                                          'Employee Designation: ${row.getCells()[2].value.toString()}'),
                                    ],
                                  ),
                                ),
                              ),
                            );
                          },
                          child: const Text('Details'),
                        ),
                      ],
                    );
                  },
                )
              : Text(
                  dataGridCell.value.toString(),
                  overflow: TextOverflow.ellipsis,
                ),
        );
      }).toList(),
    );
  }
}

class Employee {
  Employee(this.id, this.name, this.designation);
  final int id;
  final String name;
  final String designation;
}

Screenshots or Video

Screenshots / Video demonstration Screenshot 2025-01-07 at 4 52 37 PM

Stack Traces

Stack Traces
[Add the Stack Traces here]

On which target platforms have you observed this bug?

Web

Flutter Doctor output

Doctor output
   [✓] Flutter (Channel stable, 3.27.1, on macOS 15.0 ... darwin-arm64, locale en-US)
    • Flutter version 3.27.1 on channel stable at /...
    • Upstream repository ...
    • Framework revision ...
    • Engine revision ...
    • Dart version 3.6.0
    • DevTools version 2.40.2
    
    [✓] Xcode - develop for iOS and macOS (Xcode 16.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build ...
    • CocoaPods version 1.13.0
    
    [✓] IntelliJ IDEA Ultimate Edition (version 2024.1.4)
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • Flutter plugin version 81.0.2
    • Dart plugin version 241.18808


   [✓] Network resources
    • All expected network resources are available.
@abineshPalanisamy
Copy link

Hi @wartelski ,

After thoroughly analyzing the sample code and the details you provided, it appears that you have set the width for all columns. Additionally, you are using SfDataGrid.onQueryRowHeight to determine the height of rows based on the cell values.

By constraining the column widths, the values in the ID, Name, and Designation columns are being clipped. When using onQueryRowHeight, the height calculation is performed based on all cell values within the rows. Consequently, other column cell values contribute to a certain height, which results in the rowHeight being maintained even when a larger width is set for the button columns.

To avoid this issue and achieve the desired UI, you need to increase the width of the other columns, similar to what you have done for the button column. We have included a sample for your reference.

Sample: row_height.zip

As of now, the DataGrid does not have support to autofit the columns and rows based on size of the widget loaded in cells. We have already considered your request as a feature. We will implement this feature in any of our upcoming releases. At the planning stage for every release cycle, we review all open features and identify features for implementation based on specific parameters including product vision, technological feasibility, and customer interest. We appreciate your patience and understanding until then. You can follow up with the below feedback for further details,

Feedback link: 30155

Regards,
Abinesh P

@ashok-kuvaraja ashok-kuvaraja added data grid Data grid component waiting for customer response Cannot make further progress until the customer responds. uncertain Uncertain feature labels Jan 8, 2025
@wartelski
Copy link
Author

Hello @ashok-kuvaraja

Thank you for your response.
I have a couple of questions.

You saying "other column cell values contribute to a certain height, which results in the rowHeight being maintained even when a larger width is set for the button columns."

I found in the docs a property excludeColumns.
"excludeColumns – By default, the getIntrinsicRowHeight method calculates the row height based on all columns. To skip the specific columns from the row height calculation, add that column’s GridColumn.columnName to the excludeColumns collection." So, this I suppose could help, but it didn't.

And even if GridColumn has width: double.nan, I still have an issue making the hight of the row bigger when the content gets bigger.
With code like this:

 onQueryRowHeight: (details) {
          return details.getIntrinsicRowHeight(details.rowIndex, excludedColumns: ['id', 'name', 'designation']);
        },
        columnWidthMode: ColumnWidthMode.fill,
       columns: [
          GridColumn(
            columnName: 'id',
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('ID'),
            ),
          ),
          GridColumn(
            columnName: 'name',
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Name'),
            ),
          ),
          GridColumn(
            columnName: 'designation',
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Designation'),
            ),
          ),
          GridColumn(
            columnName: 'button',
            label: Container(
              padding: const EdgeInsets.all(8.0),
              alignment: Alignment.center,
              child: const Text('Details'),
            ),
          ),
        ],

I have this problem:
Screenshot 2025-01-08 at 11 19 29 AM

And I'm not even talking about constraining the column widths, it is just simply responsive issue, on smaller screen it doesn't look right.

Defining a bigger width also will not help, because what if I will have 10 buttons in one cell, and in another one just 2 buttons.

Here is the project I'm working on, and the data is dynamic. As you can see the 2nd and 5th row is too big for no reason, but the 7th row makes sense.
image

But I guess there is no solution in syncfusion currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data grid Data grid component uncertain Uncertain feature waiting for customer response Cannot make further progress until the customer responds.
Projects
None yet
Development

No branches or pull requests

3 participants