Flutter DataTable - Tap on row
Asked Answered
B

7

25

I am using Flutter DataTables to display list of items in cart. Now I want to edit the quantity of any selected row. Is there a way to get the information of the row user has tapped?

Following is complete code of my DataTable:

class _DataTableSampleState extends State<DataTableSample> {

  void _getSelectedRowInfo() {
    print('Selected Item Row Name Here...')
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('DataTable Sample'),
      ),
      body: Container(
        child: DataTable(
          onSelectAll: (b) {},
          sortAscending: true,
          columns: <DataColumn>[
            DataColumn(
              label: Text('Item'),
            ),
            DataColumn(
              label: Text('Price'),
            ),
          ],
          rows: items
              .map(
                (itemRow) => DataRow(
                      cells: [
                        DataCell(
                          Text(itemRow.itemName),
                          showEditIcon: false,
                          placeholder: false,
                        ),
                        DataCell(
                          Text(itemRow.itemPrice),
                          showEditIcon: true,
                          placeholder: false,
                          onTap: _getSelectedRowInfo,
                        ),
                      ],
                    ),
              )
              .toList(),
        ),
      ),
    );
  }
}

class ItemInfo {
  String itemName;
  String itemPrice;

  ItemInfo({
    this.itemName,
    this.itemPrice,
  });
}

var items = <ItemInfo>[
  ItemInfo(
    itemName: 'Item A',
    itemPrice: '250',
  ),
  ItemInfo(
    itemName: 'Item B',
    itemPrice: '100',
  ),
  ItemInfo(
    itemName: 'Item C',
    itemPrice: '150',
  ),
];

When edit icon is clicked "_getSelectedRowInfo" method is called. I want to get complete detail of selected/tapped row in this function.

Bergquist answered 7/11, 2018 at 13:42 Comment(0)
D
37

you can use onSelectChanged property from DataRow.

rows: items
    .map(
        (itemRow) => DataRow(
            onSelectChanged: (bool selected) {
                if (selected) {
                    log.add('row-selected: ${itemRow.index}');
                }
            },
            cells: [
                // ..
            ],
        ),
Discommode answered 7/11, 2018 at 15:30 Comment(2)
Thanks it worked. But is there any way to hide the checkbox?Bergquist
To hide the checkboxes you just have to add the property showCheckboxColumn: false in your Datatable definition.Rath
B
19

Try this :

DataTable(
    showCheckboxColumn: false, // <-- this is important
    columns: [
        DataColumn(label: Text('FirstName')),
         DataColumn(label: Text('LastName')),
    ],
     rows:[
        DataRow(
            cells: [
                DataCell(Text(obj['user1'])),
                DataCell(Text(obj['name-a'])),
            ],
            onSelectChanged: (newValue) {
                print('row 1 pressed');
            },
        ),
        DataRow(
            cells: [
                DataCell(Text(obj['user2'])),
                DataCell(Text(obj['name-b'])),
            ],
            onSelectChanged: (newValue) {
                print('row 2 pressed');
            },
        ),
    ]
),

Hope this helps. Thanks

Bystreet answered 23/2, 2020 at 12:10 Comment(0)
B
10

Each DataCell has an onTap callback. You could use this without the unhideable checkbox appearing on your table rows. For example

DataCell(Text(itemrow.itemname),
      onTap: () {
// Your code here
})

This works for me. If you want the onTap to work for the entire DataRow instead of only a DataCell, you could just add the logic to the onTap of each DataCell and get the desired result.

Bottomry answered 22/3, 2019 at 10:2 Comment(0)
I
3

You can get it done by using a closure , a function object that has access to variables in its lexical scope and basically 'remembers' them.

Change the 'onTap' property of your DataCell to :

onTap: (){_getSelectedRowInfo(itemRow.itemName,itemRow.itemPrice);},

and modify the _getSelectedRowInfo function to accommodate the following changes:

void _getSelectedRowInfo(dynamic name,dynamic price) {
    print('Name:$name  price: $price');
  }

Here's how the entire thing should look like:

class _DataTableSampleState extends State<DataTableSample> {

  void _getSelectedRowInfo(dynamic name,dynamic price) {
    print('Name:$name  price: $price');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('DataTable Sample'),
      ),
      body: Container(
        child: DataTable(
          onSelectAll: (b) {},
          sortAscending: true,
          columns: <DataColumn>[
            DataColumn(
              label: Text('Item'),
            ),
            DataColumn(
              label: Text('Price'),
            ),
          ],
          rows: items
              .map(
                (itemRow) => DataRow(
              cells: [
                DataCell(
                  Text(itemRow.itemName),
                  showEditIcon: false,
                  placeholder: false,
                ),
                DataCell(
                  Text(itemRow.itemPrice),
                  showEditIcon: true,
                  placeholder: false,
                  onTap: (){_getSelectedRowInfo(itemRow.itemName,itemRow.itemPrice);},
                ),
              ],
            ),
          )
              .toList(),
        ),
      ),
    );
  }
}

class ItemInfo {
  String itemName;
  String itemPrice;

  ItemInfo({
    this.itemName,
    this.itemPrice,
  });
}

var items = <ItemInfo>[
  ItemInfo(
    itemName: 'Item A',
    itemPrice: '250',
  ),
  ItemInfo(
    itemName: 'Item B',
    itemPrice: '100',
  ),
  ItemInfo(
    itemName: 'Item C',
    itemPrice: '150',
  ),
];
Impossible answered 17/11, 2019 at 13:11 Comment(0)
A
0

Small correction to anyone wondering how to do it on the latest versions of flutter. It takes in a bool? selected rather than a bool selected. This is due to the new null safety values syntax. Ensuring that even if the row is not rendered for whatever reason the data table can still function.

Atelectasis answered 28/12, 2021 at 20:25 Comment(0)
P
0

set showCheckboxColumn: false to hide checkbox

Parallelize answered 5/5, 2022 at 13:54 Comment(1)
Yes! When adding onSelectChanged in the DataRow, you need to put the showCheckboxColumn: false parameter in the DataTable to not show the checkbox in the row. DataTable(showCheckboxColumn: falseDrabeck
B
0

Solution 1:

class TimesheetDetails extends StatelessWidget {
  const TimesheetDetails({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: const CustomApBar(title: "Timesheet Details"),
      body: SingleChildScrollView(
        child: DataTable(

          showCheckboxColumn: false,   // =======> for hide checkbox
          
          columns: const [
            DataColumn(label: Text("ID")),
            DataColumn(label: Text("Name")),
            DataColumn(label: Text("Added?")),
          ],
          rows: List<DataRow>.generate(
            20,
            (int index) => DataRow(
              // onLongPress: () { },        // =======> also you can use long press function 
              onSelectChanged: (value) {     // =======> Use onSelectChanged for tab 
                log("message $index");
              },
              color: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
                if (index.isEven) {
                  return Colors.grey.withOpacity(0.1);
                }
                return null;
              }),
              cells: [
                DataCell(Text("ABC000${index + 1}")),
                const DataCell(Text("DONALD OCONNELL")),
                const DataCell(Icon(Icons.check)),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Solution 2: NOTE: you have to use onTap every cell

 cells: [
                DataCell(
                  Text("ABC000${index + 1}"),
                  onTap: () => log("message $index"),
                ),
                DataCell(
                  const Text("DONALD OCONNELL"),
                  onTap: () => log("message $index"),
                ),
                DataCell(
                  const Icon(Icons.check),
                  onTap: () => log("message $index"),
                ),
              ],


     
          
Bivalent answered 9/5, 2024 at 14:5 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.