4

I'm quite new to flutter and I'm building a shopping app, which list the order items in a table. The user will fill out the row field such as Price and Amount. I want to know how do I create an object of order items from each row of table. Please help me! I'm stuck with this problem a few days already.

here is a link to example table

Here is the code of each row

    rows: orderedProducts
      .map((product) => DataRow(cells: [
           DataCell(Text(product.productName)),
           DataCell(
             TextFormField(
               onSaved: (String value) {
                 takeNumber(value, product.id);
                },
             keyboardType: TextInputType.number,
              ),),
           DataCell(
             TextFormField(
                onSaved: (String value) {
                   takeNumber(value, product.id);
                },
             keyboardType: TextInputType.number,
            ),),])).toList()),
Coldie Man
  • 45
  • 1
  • 1
  • 6

1 Answers1

15

The following example is Datatable with TextField
In the example below, data came from List and First name is editable

full demo code with edit and add/print all button

import 'package:flutter/material.dart';

void main() => runApp(MyMaterialApp());

class MyMaterialApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter_typeahead demo',
      home: DataTableDemo(),
    );
  }
}

class User {
  String firstName;
  String lastName;

  User({this.firstName, this.lastName});

  static List<User> getUsers() {
    return users;
    /*return <User>[
      User(firstName: "Aaryan", lastName: "Shah"),
      User(firstName: "Ben", lastName: "John"),
      User(firstName: "Carrie", lastName: "Brown"),
      User(firstName: "Deep", lastName: "Sen"),
      User(firstName: "Emily", lastName: "Jane"),
    ];*/
  }

  static addUsers(firstName, lastName) {
    var user = new User();
    user.firstName = firstName;
    user.lastName = lastName;
    users.add(user);
  }
}

List<User> users = [];

class DataTableDemo extends StatefulWidget {
  DataTableDemo() : super();

  final String title = "Data Table Flutter Demo";

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

class DataTableDemoState extends State<DataTableDemo> {
  List<User> users;
  List<User> selectedUsers;
  bool sort;

  @override
  void initState() {
    sort = false;
    selectedUsers = [];
    users = User.getUsers();
    super.initState();
  }

  onSortColum(int columnIndex, bool ascending) {
    if (columnIndex == 0) {
      if (ascending) {
        users.sort((a, b) => a.firstName.compareTo(b.firstName));
      } else {
        users.sort((a, b) => b.firstName.compareTo(a.firstName));
      }
    }
  }

  onSelectedRow(bool selected, User user) async {
    setState(() {
      if (selected) {
        selectedUsers.add(user);
      } else {
        selectedUsers.remove(user);
      }
    });
  }

  deleteSelected() async {
    setState(() {
      if (selectedUsers.isNotEmpty) {
        List<User> temp = [];
        temp.addAll(selectedUsers);
        for (User user in temp) {
          users.remove(user);
          selectedUsers.remove(user);
        }
      }
    });
  }

  SingleChildScrollView dataBody() {
    return SingleChildScrollView(
      scrollDirection: Axis.vertical,
      child: Column(
        children: <Widget>[
          MaterialButton(
            child: Text('add button'),
            onPressed: () {
              var user = new User();
              user.firstName = "default firstName";
              user.lastName = "default lastName";
              users.add(user);
              setState(() {});
            },
          ),
          MaterialButton(
            child: Text('print all button'),
            onPressed: () {
              users.forEach((u) => print("${u.firstName} ${u.lastName}"));
            },
          ),
          DataTable(
            sortAscending: sort,
            sortColumnIndex: 0,
            columns: [
              DataColumn(
                  label: Text("FIRST NAME"),
                  numeric: false,
                  tooltip: "This is First Name",
                  onSort: (columnIndex, ascending) {
                    setState(() {
                      sort = !sort;
                    });
                    onSortColum(columnIndex, ascending);
                  }),
              DataColumn(
                label: Text("LAST NAME"),
                numeric: false,
                tooltip: "This is Last Name",
              ),
            ],
            rows: users
                .map(
                  (user) => DataRow(
                          selected: selectedUsers.contains(user),
                          onSelectChanged: (b) {
                            print("Onselect");
                            onSelectedRow(b, user);
                          },
                          cells: [
                            DataCell(
                              //Text(user.firstName),
                              TextField(
                                onChanged: (text) {
                                  print("First text field: $text");
                                  user.firstName = text;
                                },
                              ),
                            ),
                            DataCell(
                              Text(user.lastName),
                            ),
                          ]),
                )
                .toList(),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        verticalDirection: VerticalDirection.down,
        children: <Widget>[
          Expanded(
            child: dataBody(),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.all(20.0),
                child: OutlineButton(
                  child: Text('SELECTED ${selectedUsers.length}'),
                  onPressed: () {},
                ),
              ),
              Padding(
                padding: EdgeInsets.all(20.0),
                child: OutlineButton(
                  child: Text('DELETE SELECTED'),
                  onPressed: selectedUsers.isEmpty
                      ? null
                      : () {
                          deleteSelected();
                        },
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

result when click print all button

I/flutter (13851): abc default lastName
I/flutter (13851): def default lastName

enter image description here

chunhunghan
  • 51,087
  • 5
  • 102
  • 120
  • is there any other way to do this without using add button? – Coldie Man Aug 20 '19 at 08:34
  • The key is users.add(user); and setState(() {}); you put this logical anywhere you need. – chunhunghan Aug 20 '19 at 08:46
  • Your code is adding new user to users list so u can edit the field while i want to fill out the field first then add a new user to user list. i'm sorry please explain me one last time i really don't know what to do. – Coldie Man Aug 21 '19 at 05:54
  • If you need your order item display in DataTable, you need to add list first. because the UI's work is only display list data and there is always the last empty item can be removed after user click submit. you can validate this list with for loop. – chunhunghan Aug 21 '19 at 06:03
  • or you can put these editable field on other UI and when user click add button. you just add to list and setState, it will show in DataTable. – chunhunghan Aug 21 '19 at 06:05
  • so i will tell you the flow of the app i want. This app is for salesperson use for order products for his customers. First, he will select the name of product from the product list. Then he will input the amount and the price. Thus, i want him to input the amount and price inside the datatable. So what do u think i should use? – Coldie Man Aug 21 '19 at 06:47
  • You have to insert empty or default data to list and setState, and then DataTable will show this default order item with default or empty value. and then you can validate user's input and finally when user click submit button, for loop this list do some validate, and remove empty item (should be last one) – chunhunghan Aug 21 '19 at 06:55
  • that means i can't add to list and setstate in submit button, right? – Coldie Man Aug 21 '19 at 06:59
  • you can do add to list and setState in submit button. it's just a logical. – chunhunghan Aug 21 '19 at 07:02
  • i'm doing it here in submit button, but it only give me the last row – Coldie Man Aug 21 '19 at 07:10
  • ah i forgot that i have 2 different lists, orderItemList and orderedProductList. I use orderedProductList on datatable and i want to create new orderedItem and add to orderItemList – Coldie Man Aug 21 '19 at 07:28
  • most of the example use ListView not DataTable, Actually I did not find github example use DataTable. You can check this https://github.com/Widle-Studio/Grocery-App or https://github.com/invoiceninja/flutter-mobile – chunhunghan Aug 21 '19 at 07:35