Search code examples
flutterlistviewdart

Flutter: How to update a given index data and delete a list using Flutter form?


On clicking the pencil icon, The form is populated with respective field data. However, when i make changes, the changes are not made on the list data. Also, When i click on the delete button (Currently don't know) how to delete respective data from list.

enter image description here

I want this output after clicking on Edit button. Is there any way I can do this?

Here is my Code.

import 'package:flutter/material.dart';
import 'package:table/model.dart';

class Episode5 extends StatefulWidget {
  @override
  _Episode5State createState() => _Episode5State();
}

class _Episode5State extends State<Episode5> {
  TextEditingController nameController = TextEditingController();
  TextEditingController emailController = TextEditingController();

  final form = GlobalKey<FormState>();
  static var _focusNode = new FocusNode();
  bool update = false;
  User user = User();
  List<User> userList = [
    User(name: "a", email: "a"),
    User(name: "d", email: "b"),
    User(name: "c", email: "c"),
  ];

  @override
  Widget build(BuildContext context) {
    Widget bodyData() => DataTable(
          onSelectAll: (b) {},
          sortColumnIndex: 0,
          sortAscending: true,
          columns: <DataColumn>[
            DataColumn(label: Text("Name"), tooltip: "To Display name"),
            DataColumn(label: Text("Email"), tooltip: "To Display Email"),
            DataColumn(label: Text("Update"), tooltip: "Update data"),
            DataColumn(label: Text("Delete"), tooltip: "Delete data"),
          ],
          rows: userList
              .map(
                (name) => DataRow(
                  cells: [
                    DataCell(
                      Text(name.name),
                    ),
                    DataCell(
                      Text(name.email),
                    ),
                    DataCell(
                      IconButton(
                        onPressed: () {
                          _updateTextControllers(name); // new function here
                        },
                        icon: Icon(
                          Icons.edit,
                          color: Colors.black,
                        ),
                      ),
                    ),
                    DataCell(
                      IconButton(
                        onPressed: () =>
                            _deleteTextControllers(name), // new function here
                        icon: Icon(
                          Icons.delete,
                          color: Colors.black,
                        ),
                      ),
                    ),
                  ],
                ),
              )
              .toList(),
        );

    return Scaffold(
      appBar: AppBar(
        title: Text("Data add to List Table using Form"),
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            bodyData(),
            Padding(
              padding: EdgeInsets.all(10.0),
              child: Form(
                key: form,
                child: Container(
                  child: Column(
                    children: <Widget>[
                      TextFormField(
                        controller: nameController,
                        focusNode: _focusNode,
                        keyboardType: TextInputType.text,
                        autocorrect: false,
                        onSaved: (String value) {
                          user.name = value;
                        },
                        maxLines: 1,
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'This field is required';
                          }
                          return null;
                        },
                        decoration: new InputDecoration(
                          labelText: 'Name',
                          hintText: 'Name',
                          labelStyle: new TextStyle(
                              decorationStyle: TextDecorationStyle.solid),
                        ),
                      ),
                      SizedBox(
                        height: 10,
                      ),
                      TextFormField(
                        controller: emailController,
                        keyboardType: TextInputType.text,
                        autocorrect: false,
                        maxLines: 1,
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'This field is required';
                          }
                          return null;
                        },
                        onSaved: (String value) {
                          user.email = value;
                        },
                        decoration: new InputDecoration(
                            labelText: 'Email',
                            hintText: 'Email',
                            labelStyle: new TextStyle(
                                decorationStyle: TextDecorationStyle.solid)),
                      ),
                      SizedBox(
                        height: 10,
                      ),
                      Column(
                        // crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Center(
                            child: Row(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: <Widget>[
                                TextButton(
                                  child: Text("Add"),
                                  onPressed: () {
                                    if (validate() == true) {
                                      form.currentState.save();
                                      addUserToList(
                                        user.name,
                                        user.email,
                                      );
                                      clearForm();
                                    }
                                  },
                                ),
                                TextButton(
                                  child: Text("Update"),
                                  onPressed: () {
                                    if (validate() == true) {
                                      form.currentState.save();
                                      updateForm(user);
                                      clearForm();
                                    }
                                  },
                                ),
                              ],
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void updateForm(User user) {
    setState(() {
      //Code to update the list after editing
    });
  }

  void _updateTextControllers(User user) {
    setState(() {
      nameController.text = user.name;
      emailController.text = user.email;
    });
  }

  void _deleteTextControllers(User user) {
    setState(() {
      //How to delete the list data on clicking Delete button?
    });
  }

  void addUserToList(name, email) {
    setState(() {
      userList.add(User(name: name, email: email));
    });
  }

  clearForm() {
    nameController.clear();
    emailController.clear();
  }

  bool validate() {
    var valid = form.currentState.validate();
    if (valid) form.currentState.save();
    return valid;
  }
}

Solution

  • Personally, i don't reccomend to mutate data to avoid rendering problems, however, this is my solution:

    1. Mutating User data: (don't recommend)
    // I write this because you don't show me the User Model
    class User {
      String name;
      String email;
    
      User({this.name, this.email});
    }
    
    class Episode5 extends StatefulWidget {
      @override
      _Episode5State createState() => _Episode5State();
    }
    
    class _Episode5State extends State<Episode5> {
      TextEditingController nameController = TextEditingController();
      TextEditingController emailController = TextEditingController();
    
      final form = GlobalKey<FormState>();
      static var _focusNode = new FocusNode();
      bool update = false;
    
      User user = User();
    
      List<User> userList = [
        User(name: "a", email: "a"),
        User(name: "d", email: "b"),
        User(name: "c", email: "c"),
      ];
    
      @override
      Widget build(BuildContext context) {
        Widget bodyData() => DataTable(
              onSelectAll: (b) {},
              sortColumnIndex: 0,
              sortAscending: true,
              columns: <DataColumn>[
                DataColumn(label: Text("Name"), tooltip: "To Display name"),
                DataColumn(label: Text("Email"), tooltip: "To Display Email"),
                DataColumn(label: Text("Update"), tooltip: "Update data"),
                DataColumn(label: Text("Delete"), tooltip: "Delete data"),
              ],
              rows: userList
                  .map(
                    (user) => DataRow(
                      cells: [
                        DataCell(
                          Text(user.name),
                        ),
                        DataCell(
                          Text(user.email),
                        ),
                        DataCell(
                          IconButton(
                            onPressed: () {
                              this.user = user;
                              _updateTextControllers(); // new function here
                            },
                            icon: Icon(
                              Icons.edit,
                              color: Colors.black,
                            ),
                          ),
                        ),
                        DataCell(
                          IconButton(
                            onPressed: () {
                              this.user = user;
                              _deleteTextControllers(); // new function here
                            },
                            icon: Icon(
                              Icons.delete,
                              color: Colors.black,
                            ),
                          ),
                        ),
                      ],
                    ),
                  )
                  .toList(),
            );
    
        return Scaffold(
          appBar: AppBar(
            title: Text("Data add to List Table using Form"),
          ),
          body: Container(
            child: Column(
              children: <Widget>[
                bodyData(),
                Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Form(
                    key: form,
                    child: Container(
                      child: Column(
                        children: <Widget>[
                          TextFormField(
                            controller: nameController,
                            focusNode: _focusNode,
                            keyboardType: TextInputType.text,
                            autocorrect: false,
                            maxLines: 1,
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'This field is required';
                              }
                              return null;
                            },
                            decoration: new InputDecoration(
                              labelText: 'Name',
                              hintText: 'Name',
                              labelStyle: new TextStyle(
                                  decorationStyle: TextDecorationStyle.solid),
                            ),
                          ),
                          SizedBox(
                            height: 10,
                          ),
                          TextFormField(
                            controller: emailController,
                            keyboardType: TextInputType.text,
                            autocorrect: false,
                            maxLines: 1,
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'This field is required';
                              }
                              return null;
                            },
                            decoration: new InputDecoration(
                                labelText: 'Email',
                                hintText: 'Email',
                                labelStyle: new TextStyle(
                                    decorationStyle: TextDecorationStyle.solid)),
                          ),
                          SizedBox(
                            height: 10,
                          ),
                          Column(
                            // crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Center(
                                child: Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    TextButton(
                                      child: Text("Add"),
                                      onPressed: () {
                                        if (validate() == true) {
                                          form.currentState.save();
                                          addUserToList(
                                            nameController.text,
                                            emailController.text,
                                          );
                                          clearForm();
                                        }
                                      },
                                    ),
                                    TextButton(
                                      child: Text("Update"),
                                      onPressed: () {
                                        if (validate() == true) {
                                          form.currentState.save();
                                          updateForm();
                                          clearForm();
                                        }
                                      },
                                    ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    
      void updateForm() {
        setState(() {
          //Code to update the list after editing
          user.name = nameController.text;
          user.email = emailController.text;
        });
      }
    
      void _updateTextControllers() {
        setState(() {
          nameController.text = user.name;
          emailController.text = user.email;
        });
      }
    
      void _deleteTextControllers() {
        setState(() {
          //How to delete the list data on clicking Delete button?
          int currentIndex = userList.indexOf(user);
          userList.removeAt(currentIndex);
        });
      }
    
      void addUserToList(name, email) {
        setState(() {
          userList.add(User(name: name, email: email));
        });
      }
    
      clearForm() {
        nameController.clear();
        emailController.clear();
      }
    
      bool validate() {
        var valid = form.currentState.validate();
        if (valid) form.currentState.save();
        return valid;
      }
    }
    
    1. Can't mutate user data because have final values (Recommended)
    class User {
      final String name;
      final String email;
    
      User({this.name, this.email});
    }
    
    class Episode5 extends StatefulWidget {
      @override
      _Episode5State createState() => _Episode5State();
    }
    
    class _Episode5State extends State<Episode5> {
      TextEditingController nameController = TextEditingController();
      TextEditingController emailController = TextEditingController();
    
      final form = GlobalKey<FormState>();
      static var _focusNode = new FocusNode();
      bool update = false;
      int currentIndex = 0;
    
      List<User> userList = [
        User(name: "a", email: "a"),
        User(name: "d", email: "b"),
        User(name: "c", email: "c"),
      ];
    
      @override
      Widget build(BuildContext context) {
        Widget bodyData() => DataTable(
              onSelectAll: (b) {},
              sortColumnIndex: 0,
              sortAscending: true,
              columns: <DataColumn>[
                DataColumn(label: Text("Name"), tooltip: "To Display name"),
                DataColumn(label: Text("Email"), tooltip: "To Display Email"),
                DataColumn(label: Text("Update"), tooltip: "Update data"),
                DataColumn(label: Text("Delete"), tooltip: "Delete data"),
              ],
              rows: userList
                  .map(
                    (user) => DataRow(
                      cells: [
                        DataCell(
                          Text(user.name),
                        ),
                        DataCell(
                          Text(user.email),
                        ),
                        DataCell(
                          IconButton(
                            onPressed: () {
                              currentIndex = userList.indexOf(user);
                              _updateTextControllers(user); // new function here
                            },
                            icon: Icon(
                              Icons.edit,
                              color: Colors.black,
                            ),
                          ),
                        ),
                        DataCell(
                          IconButton(
                            onPressed: () {
                              currentIndex = userList.indexOf(user);
                              _deleteTextControllers(); // new function here
                            },
                            icon: Icon(
                              Icons.delete,
                              color: Colors.black,
                            ),
                          ),
                        ),
                      ],
                    ),
                  )
                  .toList(),
            );
    
        return Scaffold(
          appBar: AppBar(
            title: Text("Data add to List Table using Form"),
          ),
          body: Container(
            child: Column(
              children: <Widget>[
                bodyData(),
                Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Form(
                    key: form,
                    child: Container(
                      child: Column(
                        children: <Widget>[
                          TextFormField(
                            controller: nameController,
                            focusNode: _focusNode,
                            keyboardType: TextInputType.text,
                            autocorrect: false,
                            maxLines: 1,
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'This field is required';
                              }
                              return null;
                            },
                            decoration: new InputDecoration(
                              labelText: 'Name',
                              hintText: 'Name',
                              labelStyle: new TextStyle(
                                  decorationStyle: TextDecorationStyle.solid),
                            ),
                          ),
                          SizedBox(
                            height: 10,
                          ),
                          TextFormField(
                            controller: emailController,
                            keyboardType: TextInputType.text,
                            autocorrect: false,
                            maxLines: 1,
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'This field is required';
                              }
                              return null;
                            },
                            decoration: new InputDecoration(
                                labelText: 'Email',
                                hintText: 'Email',
                                labelStyle: new TextStyle(
                                    decorationStyle: TextDecorationStyle.solid)),
                          ),
                          SizedBox(
                            height: 10,
                          ),
                          Column(
                            // crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Center(
                                child: Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    TextButton(
                                      child: Text("Add"),
                                      onPressed: () {
                                        if (validate() == true) {
                                          form.currentState.save();
                                          addUserToList(
                                            nameController.text,
                                            emailController.text,
                                          );
                                          clearForm();
                                        }
                                      },
                                    ),
                                    TextButton(
                                      child: Text("Update"),
                                      onPressed: () {
                                        if (validate() == true) {
                                          form.currentState.save();
                                          updateForm();
                                          clearForm();
                                        }
                                      },
                                    ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    
      void updateForm() {
        setState(() {
          //Code to update the list after editing
          User user = User(name: nameController.text, email: emailController.text);
          userList[currentIndex] = user;
        });
      }
    
      void _updateTextControllers(User user) {
        setState(() {
          nameController.text = user.name;
          emailController.text = user.email;
        });
      }
    
      void _deleteTextControllers() {
        setState(() {
          //How to delete the list data on clicking Delete button?
          userList.removeAt(currentIndex);
        });
      }
    
      void addUserToList(name, email) {
        setState(() {
          userList.add(User(name: name, email: email));
        });
      }
    
      clearForm() {
        nameController.clear();
        emailController.clear();
      }
    
      bool validate() {
        var valid = form.currentState.validate();
        if (valid) form.currentState.save();
        return valid;
      }
    }