Save selected rows when rebuild datagrid

Hi everyone!


In my example I have a list of items in a listview that the user can select. According to his selection, the datagrid on the right should show his associated information, which the user can select with checkboxes. What I need and I can't manage to do is to save the rows that the user has selected from each of the listview options.


What I do and I don't understand why it doesn't work is:

1 - In the listview selection change event I rebuild with GetX my widget (stateless) where the datagrid is created.

2 - In the constructor of my widget I create a new DataGridSource.

3 - I update selectedRows of the controller to know which rows I have to select with a list of id that I keep with the rows that the user selects.


I paste my code

2024_01_12_08_08_34_Window.png

2024_01_12_08_10_10_datatable_syncfusion_view.dart_Hygehos_Web_Visual_Studio_Code_Administrad.png

2024_01_12_08_10_54_datatable_syncfusion_view.dart_Hygehos_Web_Visual_Studio_Code_Administrad.png


6 Replies 1 reply marked as answer

TP Tamilarasan Paranthaman Syncfusion Team January 18, 2024 02:27 PM UTC

Hi Fernando,

We are currently uncertain about the issue you are encountering, especially considering the implementation of DataGrid with GetX. From the provided information, it appears that you have been adding rows to the `DataGridController.selectedRows` property using the `add` method. Additionally, you mentioned the recreation of DataGridRows in specific scenarios. To address this, we recommend assigning the list of DataGridRow directly to the `DataGridController.selectedRows` property using the `=` operator instead of the `add` method.


For your convenience, we have attached a basic sample (without GetX implementation) illustrating this recommended approach. In this sample, rows are added to a local list and then assigned directly to `DataGridController.selectedRows` using the `=` operator. Please refer to the provided code snippet and sample for a clearer understanding.


  List<DataGridRow> selectedRows = [];

  DataGridController dataGridController = DataGridController();

 

  @override

  void initState() {

    super.initState();

    _employees = populateData();

    _employeeDataSource = EmployeeDataSource(_employees);

    selectedRows.add(_employeeDataSource.rows[0]);

    selectedRows.add(_employeeDataSource.rows[1]);

    selectedRows.add(_employeeDataSource.rows[2]);

  }

 

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(title: const Text('Syncfusion DataGrid Demo')),

      body: Column(

        children: [

          ElevatedButton(

            onPressed: () {

              dataGridController.selectedRows = selectedRows;

            },

            child: const Text('Select Rows Programmatically'),

          ),

          Expanded(

            child: SfDataGrid(

              source: _employeeDataSource,

              selectionMode: SelectionMode.multiple,

              columns: getColumns,

              controller: dataGridController,

              columnWidthMode: ColumnWidthMode.fill,

            ),

          ),

        ],

      ),

    );

  }


UG Document: https://help.syncfusion.com/flutter/datagrid/selection#programmatic-selection

If the issue persists despite implementing these changes, we kindly request you to share the specific sample that showcases the problem. Alternatively, you can modify the attached sample to replicate the issue you are experiencing. This will enable us to thoroughly investigate the problem on our end and provide a more effective solution. Your cooperation is greatly appreciated.


Regards,

Tamilarasan


Attachment: Sample_944487ae.zip


FD Fernando de Miguel replied to Tamilarasan Paranthaman January 18, 2024 05:03 PM UTC

Thank you very much for your answer but unfortunately it does not solve my problem.


I'll share an example (without GetX) with you so you can see the problem. Basically it is a silly example where a button is used to create a new data source, which switches between two different lists of employees. What I want is that, although the user has clicked on the button, the rows he has selected are saved so that, in case he sees the same data source again, the previously selected rows appear selected. That is, I don't want the selected rows to be lost when changing the data source.


The weirdest thing is that if you debug the getDatagridController method, you can see that it does change the rows to be selected; but it doesn't paint them. Very strange :S




Attachment: main_a67cf4f8.zip



TP Tamilarasan Paranthaman Syncfusion Team January 19, 2024 02:52 PM UTC

Fernando,

Thank you for providing the sample. In the provided example, you generated a new DataGrid source and built the DataGrid based on that when changing the source.


The issue you are encountering appears to be associated with applying the selection to rows before the DataGrid undergoes a rebuild. Normally, when programmatical selection is employed, the DataGrid promptly refreshes to reflect the changes. In your scenario, the selection process (specifically, applying programmatical selection through DataGridController) began before the DataGrid rebuilt with the updated source triggered by calling `setState`. Consequently, the selection didn't update as the DataGrid source had not been updated at that point.


To address this situation, we suggest implementing a solution. You can achieve the desired functionality by assigning selected rows to the DataGridController within the callback of `SchedulerBinding.instance.addPostFrameCallback`. This approach ensures that the rows are correctly assigned at the end of the frame. For a more comprehensive understanding, we have adjusted your sample. Please review the updated sample and code snippet for additional information.


  DataGridController getDatagridController() {

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

    for (DataGridRow row in _employeeDataSource.dataRows) {

      bool isSelectedRow =

          selEmployees.contains(row.getCells().elementAt(0).value);

      if (isSelectedRow) {

        newSelectedRows.add(row);

      }

    }

    SchedulerBinding.instance.addPostFrameCallback((timeStamp) {

      dataGridController.selectedRows = newSelectedRows;

    });

 

    return dataGridController;

  }




Attachment: Sample_1100e29d.zip

Marked as answer

FD Fernando de Miguel January 22, 2024 08:02 AM UTC

Perfect solution!


Thanks you very much.



MS Mahmoud Saleh April 3, 2024 06:45 AM UTC

This was helpful 



JS Jayashree Suresh Anand Syncfusion Team April 3, 2024 08:38 AM UTC

Hi Fernando & Mahmoud, 

We are glad that our solution meets your requirements, please let us know if you have any further queries, we will be happy to help. 

Regards,

Jayashree 


Loader.
Up arrow icon