How to show other GridColumn before checkboxColumn?

Hello~:)

In my case i want to show last selected hint(red color *) before checkbox.

May i show other GridColumn in front of checkboxColumn?

Or can i change checkboxColumn position?

the following is my demo photo(problem):


the following is my code:

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

void main() {
runApp(MyApp());
}

/// The application that contains datagrid on it.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Syncfusion DataGrid Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(),
);
}
}

DataGridController _dataGridController = DataGridController();

/// The home page of the application which hosts the datagrid.
class MyHomePage extends StatefulWidget {
/// Creates the home page.
MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
List<Employee> employees = <Employee>[];
late EmployeeDataSource employeeDataSource;

Map<String, double> columnWidths = {
'latestSelected': double.nan,
'id': double.nan,
'name': double.nan,
'designation': double.nan,
'salary': double.nan,
};

List<int> selectedRowsIndex = <int>[];

@override
void initState() {
super.initState();
employees = getEmployeeData();
employeeDataSource = EmployeeDataSource();
employeeDataSource.buildDataGridRows(employeeData: employees);
debugPrint('columnWidths text3: ${columnWidths['text3']}');
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter DataGrid'),
),
body: Center(
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
height: MediaQuery.of(context).size.height * 0.8,
child: SfDataGrid(
controller: _dataGridController,
source: employeeDataSource,
columnWidthMode: ColumnWidthMode.fitByCellValue,
selectionMode: SelectionMode.multiple,
showCheckboxColumn: true,
isScrollbarAlwaysShown: true,
allowColumnsResizing: true,
columnResizeMode: ColumnResizeMode.onResize,
onColumnResizeUpdate: (ColumnResizeUpdateDetails details) {
setState(() {
columnWidths[details.column.columnName] = details.width;
});
return true;
},
onSelectionChanged: (List<DataGridRow> addedRows, List<DataGridRow> removedRows) {
List<DataGridRow> newSelectedRows = [];

employees.forEach((employee) {
if (employee.isShowSelectedHint) {
employee.isShowSelectedHint = false;
}
});

if (addedRows.isNotEmpty) {
selectedRowsIndex.add(_dataGridController.selectedIndex);
employees[_dataGridController.selectedIndex].isShowSelectedHint = true;
}
if (removedRows.isNotEmpty) {
selectedRowsIndex.remove(employeeDataSource.rows.indexOf(removedRows[0]));
employees[employeeDataSource.rows.indexOf(removedRows[0])].isShowSelectedHint = true;
}

employeeDataSource.buildDataGridRows(employeeData: employees);
employeeDataSource.updateDataGridSource();

selectedRowsIndex.forEach((index) {
newSelectedRows.add(employeeDataSource.rows[index]);
});

_dataGridController.selectedRows = [...newSelectedRows];
},
columns: <GridColumn>[
GridColumn(
width: columnWidths['latestSelected']!,
minimumWidth: 30,
columnName: 'latestSelected',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'',
overflow: TextOverflow.visible,
softWrap: null,
maxLines: 1,
))),
GridColumn(
width: columnWidths['id']!,
minimumWidth: 30,
columnName: 'id',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Text(
'ID',
overflow: TextOverflow.visible,
softWrap: null,
maxLines: 1,
))),
GridColumn(
width: columnWidths['name']!,
minimumWidth: 30,
columnName: 'name',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Name',
overflow: TextOverflow.visible,
softWrap: null,
maxLines: 1,
))),
GridColumn(
width: columnWidths['designation']!,
minimumWidth: 30,
columnName: 'designation',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Designation',
overflow: TextOverflow.visible,
softWrap: null,
maxLines: 1,
))),
GridColumn(
width: columnWidths['salary']!,
minimumWidth: 30,
columnName: 'salary',
label: Container(
padding: EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text(
'Salary',
overflow: TextOverflow.visible,
softWrap: null,
maxLines: 1,
))),
],
),
),
),
);
}

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

/// Custom business object class which contains properties to hold the detailed
/// information about the employee which will be rendered in datagrid.
class Employee {
/// Creates the employee class with required details.
Employee(this.isShowSelectedHint, this.id, this.name, this.designation, this.salary);

bool isShowSelectedHint;

/// Id of an employee.
final int id;

/// Name of an employee.
final String name;

/// Designation of an employee.
final String designation;

/// Salary of an employee.
final int salary;
}

/// An object to set the employee collection data source to the datagrid. This
/// is used to map the employee data to the datagrid widget.
class EmployeeDataSource extends DataGridSource {
/// Creates the employee data source class with required details.
List<DataGridRow> buildDataGridRows({required List<Employee> employeeData}) {
return _employeeData = employeeData
.map<DataGridRow>((e) => DataGridRow(cells: [
DataGridCell<bool>(columnName: 'isShowSelectedHint', value: e.isShowSelectedHint),
DataGridCell<int>(columnName: 'id', value: e.id),
DataGridCell<String>(columnName: 'name', value: e.name),
DataGridCell<String>(columnName: 'designation', value: e.designation),
DataGridCell<int>(columnName: 'salary', value: e.salary),
]))
.toList();
}

List<DataGridRow> _employeeData = [];

@override
List<DataGridRow> get rows => _employeeData;

@override
DataGridRowAdapter buildRow(DataGridRow row) {
return DataGridRowAdapter(
cells: row.getCells().map<Widget>((e) {
if (e.columnName == 'isShowSelectedHint') {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(
e.value == true ? '*' : '',
style: TextStyle(color: Colors.red),
),
);
}
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: Text(
e.value.toString(),
),
);
}).toList());
}

void updateDataGridSource() {
notifyListeners();
}
}


7 Replies 1 reply marked as answer


JH Jimmy Huang April 15, 2022 01:40 PM UTC

Hi~ Tamilarasan : )

If I not set showCheckboxColumn to true and manual DIY datagrid column child widget for selection.

But just laborious.


Thanks for your reply.








TP Tamilarasan Paranthaman Syncfusion Team April 18, 2022 02:24 PM UTC

Hi Jimmy,


As we said in the previous update, we add the CheckBoxColumn as the first column in the DataGrid. Meanwhile, we are checking your requirement to achieve it at the sample level. We will update you with the details tomorrow i.e., April 19, 2022. We appreciate your patience until then.


Regards,

Tamilarasan



JH Jimmy Huang replied to Tamilarasan Paranthaman April 19, 2022 04:11 AM UTC

Hi Tamilarasan~

Thanks you for support.



TP Tamilarasan Paranthaman Syncfusion Team April 19, 2022 02:15 PM UTC

Hi Jimmy,


You can achieve your requirement at the sample level itself by the following the below steps,


Step 1: Add the Checkbox widget directly in the DataGrid cell instead of setting the showCheckboxColumn to true. You can add the checkbox column where you need it. Please check the following code snippet.


Code Snippet:

  @override

  DataGridRowAdapter buildRow(DataGridRow row) {

    return DataGridRowAdapter(

        cells: row.getCells().map<Widget>((e) {

      if (e.columnName == 'checkbox') {

        isSelected =

            dataGridController.selectedRows.contains(row) ? true : false;

        return Container(

            alignment: Alignment.center,

            padding: const EdgeInsets.all(8.0),

            child: Checkbox(

              value: isSelected,

              onChanged: (value) {

                if (value != null) {

                  if (!value) {

                    if (newSelectedRows.isNotEmpty) {

                      newSelectedRows.clear();

                    }

                    newSelectedRows =

                        List.from(dataGridController.selectedRows);

                    newSelectedRows.remove(row);

                    dataGridController.selectedRows =

                        List.from(newSelectedRows);

                  }

                  if (value) {

                    dataGridController.selectedRow = row;

                  }

                  notifyListeners();

                }

              },

            ));

      }

      return Container(

        alignment: Alignment.center,

        padding: const EdgeInsets.all(8.0),

        child: Text(

          e.value.toString(),

        ),

      );

    }).toList());

  }


Step 2: For the latest selected hint column, you can show the hint based on the row which is recently added in the dataGridController.selectedRows. Please check the following code snippet.


Code Snippet:

    getValue(DataGridRow row) {

    if (dataGridController.selectedRows.isNotEmpty) {

      return dataGridController.selectedRows.last == row ? '*' : '';

    } else {

      return '';

    }

  }

 

@override

  DataGridRowAdapter buildRow(DataGridRow row) {

    return DataGridRowAdapter(

        cells: row.getCells().map<Widget>((e) {

      if (e.columnName == 'isShowSelectedHint') {

        return Container(

          alignment: Alignment.center,

          padding: const EdgeInsets.all(8.0),

          child: Text(

            getValue(row),

            style: const TextStyle(color: Colors.red),

          ),

        );

      }

}



Step 3: Call the notifyListeners from the DataGridSource class in the DataGrid’s onSelectionChanged callback. It will update the recently selected row hint. Please check the following code snippet and sample.


Code Snippet:

  @override

  Widget build(BuildContext context) {

    return Scaffold(

        appBar: AppBar(

          title: const Text('Syncfusion Flutter DataGrid'),

        ),

        body: Center(

            child: SizedBox(

                width: MediaQuery.of(context).size.width * 0.8,

                height: MediaQuery.of(context).size.height * 0.8,

                child: SfDataGrid(

                    controller: _dataGridController,

                    source: employeeDataSource,

                    columnWidthMode: ColumnWidthMode.fitByCellValue,

                    selectionMode: SelectionMode.multiple,

                    onSelectionChanged: (List<DataGridRow> addedRows,

                        List<DataGridRow> removedRows) {

                      employeeDataSource.updateDataGridSource();

                    },

                    columns: getColumns))));

  }


Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sample1039089352


We hope this helps. Please let us know if need any further assistance.


Regards,

Tamilarasan


Marked as answer

JH Jimmy Huang April 19, 2022 03:42 PM UTC

Hi ~ Tamilarasan,


This sample very useful.

Thanks for your help : )





TP Tamilarasan Paranthaman Syncfusion Team April 20, 2022 05:15 AM UTC

Hi Jimmy,


We are glad that the provided response meets your requirement. Please let us know if you need further assistance. As always, we are happy to help you out.


Regards

Tamilarasan


Loader.
Up arrow icon