How To Edit & Delete Data From Flutter List View?
By Webotapp Academy•
<!-- wp:paragraph -->\n<p>In this article, we shall discuss how to edit & delete data from Flutter List View using PHP and MySQL.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">First we will add the edit and delete icons </h3>\n<!-- /wp:heading -->\n\n<!-- wp:image {\"id\":4847,\"sizeSlug\":\"large\",\"linkDestination\":\"none\"} -->\n<figure class=\"wp-block-image size-large\"><img src=\"https://academy.webotapp.com/wp-content/uploads/2024/03/image-1024x635.png\" alt=\"\" class=\"wp-image-4847\"/></figure>\n<!-- /wp:image -->\n\n<!-- wp:paragraph -->\n<p>We will go to ListView Builder and change the trailing. While we will edit the status and bring it to the title. </p>\n<!-- /wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>title: Text('Order ID: ${orders[index]['id']} | Status: ${orders[index]['status']}'),</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>And then we will add the two icons.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>trailing: Row(\n mainAxisSize: MainAxisSize.min,\n children: [\n IconButton(\n icon: Icon(Icons.edit),\n onPressed: () => editOrder(orders[index]['id']),\n ),\n IconButton(\n icon: Icon(Icons.delete),\n onPressed: () => deleteOrder(orders[index]['id']),\n ),\n ],\n ),</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Next, We have to create the functions for edit and delete.</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> Future<void> editOrder(int orderId) async {\n // Implement edit order functionality\n }\n\n Future<void> deleteOrder(int orderId) async {\n // Implement delete order functionality\n }</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Next, we will go to our control panel and create the delete order API page</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code><?php\ninclude('cors.php');\ninclude('../database.php');\n\n// Assuming you're receiving the order ID to delete\n$order_id = $_GET['order_id'];\n\n// Query to delete the order\n$query = \"DELETE FROM checkout WHERE id = :order_id\";\n$stmt = $conn->prepare($query);\n$stmt->bindParam(':order_id', $order_id);\n$stmt->execute();\n\nif ($stmt->rowCount() > 0) {\n $response = [\n 'success' => true,\n 'message' => 'Order deleted successfully',\n ];\n} else {\n $response = [\n 'success' => false,\n 'message' => 'Failed to delete order',\n ];\n}\n\n// Send the response as JSON\nheader('Content-Type: application/json');\necho json_encode($response);\n?></code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Next, we will build the logout function in our app</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>Future<void> deleteOrder(int orderId) async {\n try {\n // Replace 'your_api_endpoint' with the actual endpoint URL for deleting orders\n final url = Uri.parse('https://aboutassam.in/flutter_app/api/delete-order.php?order_id=$orderId');\n\n final response = await http.delete(url);\n\n if (response.statusCode == 200) {\n final responseData = json.decode(response.body);\n if (responseData['success'] == true) {\n // Order deleted successfully, navigate back to MyOrderScreen\n Navigator.push(\n context,\n MaterialPageRoute(builder: (context) => MyOrderScreen()),\n );\n } else {\n throw Exception(responseData['message']);\n }\n } else {\n throw Exception('Failed to delete order');\n }\n } catch (error) {\n print('Error deleting order: $error');\n // Handle error accordingly\n }\n }</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Create a blank flutter screen called Edit order and we will shift the edit code to this screen </h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>import 'package:flutter/cupertino.dart';\n\nclass EditOrder extends StatefulWidget {\n const EditOrder({super.key});\n\n @override\n State<EditOrder> createState() => _EditOrderState();\n}\n\n\nFuture<void> editOrder(int orderId) async {\n // Implement edit order functionality\n}\nclass _EditOrderState extends State<EditOrder> {\n @override\n Widget build(BuildContext context) {\n return const Placeholder();\n }\n}\n</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">We will then copy the codes from the checkout screen and paste them into the edit order screen</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>import 'package:ecommerce_app/orders/myOrders.dart';\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' as http;\nimport 'package:shared_preferences/shared_preferences.dart';\nimport '../MyAccount/login.dart';\nimport '../MyAccount/thankyou.dart';\n\nclass EditOrder extends StatefulWidget {\n final int orderId;\n\n const EditOrder({Key? key, required this.orderId}) : super(key: key);\n\n @override\n State<EditOrder> createState() => _EditOrderState();\n}\n\n\nFuture<void> editOrder(int orderId) async {\n // Implement edit order functionality\n}\n\n\nclass _EditOrderState extends State<EditOrder> {\n\n//define all the variables\n\n final _formKey = GlobalKey<FormState>();\n String selectedState = 'Select State';\n String userMobile = '';\n\n\n\n\n List<String> indianStates = [\n 'Select State',\n 'Andhra Pradesh',\n 'Arunachal Pradesh',\n 'Assam',\n 'Bihar',\n 'Chhattisgarh',\n 'Goa',\n 'Gujarat',\n 'Haryana',\n 'Himachal Pradesh',\n 'Jharkhand',\n 'Karnataka',\n 'Kerala',\n 'Madhya Pradesh',\n 'Maharashtra',\n 'Manipur',\n 'Meghalaya',\n 'Mizoram',\n 'Nagaland',\n 'Odisha',\n 'Punjab',\n 'Rajasthan',\n 'Sikkim',\n 'Tamil Nadu',\n 'Telangana',\n 'Tripura',\n 'Uttar Pradesh',\n 'Uttarakhand',\n 'West Bengal',\n // Rest of the states\n ];\n\n\n\n Widget _buildStateDropdown() {\n\n return DropdownButtonFormField<String>(\n decoration: InputDecoration(\n labelText: 'Your State',\n border: OutlineInputBorder(\n borderRadius: BorderRadius.circular(50),\n borderSide: BorderSide(color: Colors.pink),\n ),\n ),\n value: selectedState,\n items: indianStates.map((state) {\n return DropdownMenuItem<String>(\n value: state,\n child: Text(state),\n );\n }).toList(),\n onChanged: (value) {\n setState(() {\n selectedState = value!;\n });\n },\n );\n }\n\n @override\n void initState() {\n super.initState();\n\n _getUserInfo();\n }\n Future<void> _getUserInfo() async {\n try {\n SharedPreferences prefs = await SharedPreferences.getInstance();\n String usermobile = prefs.getString('userMobile') ?? ''; // Get user email\n\n if (usermobile.isEmpty) {\n Navigator.push(\n context,\n MaterialPageRoute(\n builder: (context) => LoginScreen(),\n ),\n );\n } else {\n setState(() {\n userMobile = usermobile;\n });\n }\n ;\n } catch (error) {\n print('Error retrieving user info: $error');\n }\n }\n\n\n //Define Controllers Here\n\n TextEditingController yourName = TextEditingController();\n TextEditingController yourMobile = TextEditingController();\n TextEditingController yourAddress = TextEditingController();\n\n\n @override\n void dispose(){\n yourName.dispose();\n yourMobile.dispose();\n yourAddress.dispose();\n super.dispose();\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(\n title: Text('Edit Order'),\n backgroundColor: Colors.pink,\n ),\n body: SingleChildScrollView(\n child: Column(\n children: [\n Container(\n margin: EdgeInsets.all(30),\n child: Image.network('https://aboutassam.in/flutter_app/assets/img/cart.png'),\n ),\n Container(\n child: Text('Edit Screen', style: TextStyle(fontSize: 30),),\n ),\n\n Form(\n\n key: _formKey,\n child: Column(\n children: <Widget>[\n\n _buildTextInputField('Your Name', yourName),\n SizedBox(height: 10,),\n _buildTextInputField('Your Mobile', yourMobile, userMobile : userMobile, readOnly: true),\n SizedBox(height: 10,),\n _buildStateDropdown(),\n SizedBox(height: 10,),\n _buildTextInputField('Your Address', yourAddress),\n SizedBox(height: 10,),\n ElevatedButton(\n onPressed: (){\n if(_formKey.currentState!.validate()){\n sendDataToServer();\n }\n\n },\n child: Text('Submit')\n )\n\n ],\n )\n ,\n )\n ],\n ),\n ),\n );\n }\n\n void sendDataToServer () async {\n\n int orderId = widget.orderId;\n // Create a map of the form data.\n Map<String, String> formData = {\n 'name': yourName.text,\n 'mobile': yourMobile.text,\n 'state': selectedState,\n 'address': yourAddress.text,\n };\n\n // Make an HTTP POST request to send the form data.\n final response = await http.post(\n Uri.parse('https://aboutassam.in/flutter_app/api/update-order.php?id=$orderId'),\n body: formData,\n );\n\n\n if (response.statusCode == 200) {\n print('Response===== ${response.body}');\n Navigator.push(context,\n MaterialPageRoute(\n builder: (context) => MyOrderScreen())\n );\n } else {\n print('Response===== ${response.body}');\n }\n }\n}\n\n\n\nWidget _buildTextInputField(\n\n\n\n\n String labelText, TextEditingController controller, {\n TextInputType inputType = TextInputType.text,\n String? Function(String?)? validator,\n String userMobile = '',\n bool readOnly = false,\n\n }) {\n\n\n\n if(labelText == 'Your Mobile'){\n\n controller.text = userMobile;\n }\n\n\n return TextFormField(\n controller: controller,\n enabled: !readOnly,\n decoration: InputDecoration(\n labelText: labelText,\n border: OutlineInputBorder(\n borderRadius: BorderRadius.circular(50),\n borderSide: BorderSide(color: Colors.pink),\n ),\n ),\n keyboardType: inputType,\n validator: validator,\n );\n}\n</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>We will have to modify the edit button in my orders page</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>IconButton(\n icon: Icon(Icons.edit),\n onPressed: () {\n int orderId = orders[index]['id'];\n Navigator.push(\n context,\n MaterialPageRoute(\n builder: (context) => EditOrder(orderId: orderId),\n ),\n );\n },\n ),</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Create The Update / Edit API</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code><?php\ninclude('cors.php');\ninclude('../database.php');\n\n// Assuming you have already established a PDO database connection in database.php\n// Replace database credentials with your own.\n\nheader('Content-Type: application/json');\n\n// Initialize an empty response.\n$response = array();\n\n// Check if the request is a POST request.\nif ($_SERVER['REQUEST_METHOD'] === 'POST') {\n // Get data from the POST request.\n $order_id = $_GET['id']; // Assuming you have a field named 'order_id' to identify the order to update\n $c_name = $_POST['name'];\n $c_mobile = $_POST['mobile'];\n $c_state = $_POST['state'];\n $c_address = $_POST['address'];\n\n // Update the data in the database using prepared statements.\n $sql = \"UPDATE checkout SET c_name = :name, c_mobile = :mobile, c_state = :state, c_address = :address WHERE id = :order_id\";\n $stmt = $conn->prepare($sql);\n \n // Bind the parameters.\n $stmt->bindParam(':name', $c_name);\n $stmt->bindParam(':mobile', $c_mobile);\n $stmt->bindParam(':state', $c_state);\n $stmt->bindParam(':address', $c_address);\n $stmt->bindParam(':order_id', $order_id);\n\n if ($stmt->execute()) {\n $response['success'] = true;\n $response['message'] = \"Data updated successfully.\";\n } else {\n $response['success'] = false;\n $response['message'] = \"Error: \" . $stmt->errorInfo();\n }\n} else {\n $response['success'] = false;\n $response['message'] = \"Invalid request method.\";\n}\n\n// Output the response as JSON.\necho json_encode($response);\n?>\n</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Complete Code of My Orders Screen </h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>import 'dart:convert';\n\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' as http;\nimport 'package:shared_preferences/shared_preferences.dart';\n\nimport '../MyAccount/login.dart';\nimport 'edit-order.dart';\n\n\nclass MyOrderScreen extends StatefulWidget {\n const MyOrderScreen({super.key});\n\n @override\n State<MyOrderScreen> createState() => _MyOrderScreenState();\n\n\n\n\n\n}\n\n\n\nclass _MyOrderScreenState extends State<MyOrderScreen> {\n\n List<Map<String, dynamic>> orders = [];\n\n String userMobile = '';\n\n @override\n void initState(){\n super.initState();\n _getUserInfo();\n fetchOrders();\n\n }\n\n Future<void> _getUserInfo() async {\n try {\n SharedPreferences prefs = await SharedPreferences.getInstance();\n String usermobile = prefs.getString('userMobile') ?? ''; // Get user email\n\n if (usermobile.isEmpty) {\n Navigator.push(\n context,\n MaterialPageRoute(\n builder: (context) => LoginScreen(),\n ),\n );\n } else {\n setState(() {\n userMobile= usermobile;\n });\n }\n ;\n } catch (error) {\n print('Error retrieving user info: $error');\n }\n }\n\n\n Future<void> fetchOrders() async {\n\n SharedPreferences prefs = await SharedPreferences.getInstance();\n String usermobile = prefs.getString('userMobile') ?? '';\n print(userMobile);\n print(\"==================\");\n setState(() {\n userMobile= usermobile;\n });\n\n\n\n\n final response = await http.get(Uri.parse('https://aboutassam.in/flutter_app/api/fetch_orders.php?mobile=$userMobile'));\n if (response.statusCode == 200) {\n final responseData = json.decode(response.body);\n if (responseData['success'] == true) {\n setState(() {\n orders = List<Map<String, dynamic>>.from(responseData['orders']);\n });\n } else {\n throw Exception(responseData['message']);\n }\n } else {\n throw Exception('Failed to load orders');\n }\n }\n\n\n\n\n Future<void> deleteOrder(int orderId) async {\n try {\n // Replace 'your_api_endpoint' with the actual endpoint URL for deleting orders\n final url = Uri.parse('https://aboutassam.in/flutter_app/api/delete-order.php?order_id=$orderId');\n\n final response = await http.delete(url);\n\n if (response.statusCode == 200) {\n final responseData = json.decode(response.body);\n if (responseData['success'] == true) {\n // Order deleted successfully, navigate back to MyOrderScreen\n Navigator.push(\n context,\n MaterialPageRoute(builder: (context) => MyOrderScreen()),\n );\n } else {\n throw Exception(responseData['message']);\n }\n } else {\n throw Exception('Failed to delete order');\n }\n } catch (error) {\n print('Error deleting order: $error');\n // Handle error accordingly\n }\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(\n title: Text('My Orders'),\n backgroundColor: Colors.pink,\n ),\n body: SingleChildScrollView(\n child: Column(\n children: [\n SizedBox(height: 50,),\n Container(\n margin: EdgeInsets.all(10),\n alignment: Alignment.center,\n child: Text('Your Orders! ', style: TextStyle(fontSize: 25),),\n ),\n ListView.builder(\n shrinkWrap: true,\n itemCount: orders.length,\n itemBuilder: (context, index) {\n return ListTile(\n title: Text('Order ID: ${orders[index]['id']} | Status: ${orders[index]['status']}'),\n subtitle: Text('Name: ${orders[index]['c_name']}'),\n trailing: Row(\n mainAxisSize: MainAxisSize.min,\n children: [\n IconButton(\n icon: Icon(Icons.edit),\n onPressed: () {\n int orderId = orders[index]['id'];\n Navigator.push(\n context,\n MaterialPageRoute(\n builder: (context) => EditOrder(orderId: orderId),\n ),\n );\n },\n ),\n IconButton(\n icon: Icon(Icons.delete),\n onPressed: () => deleteOrder(orders[index]['id']),\n ),\n ],\n ),\n );\n },\n ),\n\n ],\n ),\n ),\n );\n }\n}\n</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Complete Code of Edit Orders Screen</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>import 'package:ecommerce_app/orders/myOrders.dart';\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' as http;\nimport 'package:shared_preferences/shared_preferences.dart';\nimport '../MyAccount/login.dart';\nimport '../MyAccount/thankyou.dart';\n\nclass EditOrder extends StatefulWidget {\n final int orderId;\n\n const EditOrder({Key? key, required this.orderId}) : super(key: key);\n\n @override\n State<EditOrder> createState() => _EditOrderState();\n}\n\n\nFuture<void> editOrder(int orderId) async {\n // Implement edit order functionality\n}\n\n\nclass _EditOrderState extends State<EditOrder> {\n\n//define all the variables\n\n final _formKey = GlobalKey<FormState>();\n String selectedState = 'Select State';\n String userMobile = '';\n\n\n\n\n List<String> indianStates = [\n 'Select State',\n 'Andhra Pradesh',\n 'Arunachal Pradesh',\n 'Assam',\n 'Bihar',\n 'Chhattisgarh',\n 'Goa',\n 'Gujarat',\n 'Haryana',\n 'Himachal Pradesh',\n 'Jharkhand',\n 'Karnataka',\n 'Kerala',\n 'Madhya Pradesh',\n 'Maharashtra',\n 'Manipur',\n 'Meghalaya',\n 'Mizoram',\n 'Nagaland',\n 'Odisha',\n 'Punjab',\n 'Rajasthan',\n 'Sikkim',\n 'Tamil Nadu',\n 'Telangana',\n 'Tripura',\n 'Uttar Pradesh',\n 'Uttarakhand',\n 'West Bengal',\n // Rest of the states\n ];\n\n\n\n Widget _buildStateDropdown() {\n\n return DropdownButtonFormField<String>(\n decoration: InputDecoration(\n labelText: 'Your State',\n border: OutlineInputBorder(\n borderRadius: BorderRadius.circular(50),\n borderSide: BorderSide(color: Colors.pink),\n ),\n ),\n value: selectedState,\n items: indianStates.map((state) {\n return DropdownMenuItem<String>(\n value: state,\n child: Text(state),\n );\n }).toList(),\n onChanged: (value) {\n setState(() {\n selectedState = value!;\n });\n },\n );\n }\n\n @override\n void initState() {\n super.initState();\n\n _getUserInfo();\n }\n Future<void> _getUserInfo() async {\n try {\n SharedPreferences prefs = await SharedPreferences.getInstance();\n String usermobile = prefs.getString('userMobile') ?? ''; // Get user email\n\n if (usermobile.isEmpty) {\n Navigator.push(\n context,\n MaterialPageRoute(\n builder: (context) => LoginScreen(),\n ),\n );\n } else {\n setState(() {\n userMobile = usermobile;\n });\n }\n ;\n } catch (error) {\n print('Error retrieving user info: $error');\n }\n }\n\n\n //Define Controllers Here\n\n TextEditingController yourName = TextEditingController();\n TextEditingController yourMobile = TextEditingController();\n TextEditingController yourAddress = TextEditingController();\n\n\n @override\n void dispose(){\n yourName.dispose();\n yourMobile.dispose();\n yourAddress.dispose();\n super.dispose();\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(\n title: Text('Edit Order'),\n backgroundColor: Colors.pink,\n ),\n body: SingleChildScrollView(\n child: Column(\n children: [\n Container(\n margin: EdgeInsets.all(30),\n child: Image.network('https://aboutassam.in/flutter_app/assets/img/cart.png'),\n ),\n Container(\n child: Text('Edit Screen', style: TextStyle(fontSize: 30),),\n ),\n\n Form(\n\n key: _formKey,\n child: Column(\n children: <Widget>[\n\n _buildTextInputField('Your Name', yourName),\n SizedBox(height: 10,),\n _buildTextInputField('Your Mobile', yourMobile, userMobile : userMobile, readOnly: true),\n SizedBox(height: 10,),\n _buildStateDropdown(),\n SizedBox(height: 10,),\n _buildTextInputField('Your Address', yourAddress),\n SizedBox(height: 10,),\n ElevatedButton(\n onPressed: (){\n if(_formKey.currentState!.validate()){\n sendDataToServer();\n }\n\n },\n child: Text('Submit')\n )\n\n ],\n )\n ,\n )\n ],\n ),\n ),\n );\n }\n\n void sendDataToServer () async {\n\n int orderId = widget.orderId;\n // Create a map of the form data.\n Map<String, String> formData = {\n 'name': yourName.text,\n 'mobile': yourMobile.text,\n 'state': selectedState,\n 'address': yourAddress.text,\n };\n\n // Make an HTTP POST request to send the form data.\n final response = await http.post(\n Uri.parse('https://aboutassam.in/flutter_app/api/update-order.php?id=$orderId'),\n body: formData,\n );\n\n\n if (response.statusCode == 200) {\n print('Response===== ${response.body}');\n Navigator.push(context,\n MaterialPageRoute(\n builder: (context) => MyOrderScreen())\n );\n } else {\n print('Response===== ${response.body}');\n }\n }\n}\n\n\n\nWidget _buildTextInputField(\n\n\n\n\n String labelText, TextEditingController controller, {\n TextInputType inputType = TextInputType.text,\n String? Function(String?)? validator,\n String userMobile = '',\n bool readOnly = false,\n\n }) {\n\n\n\n if(labelText == 'Your Mobile'){\n\n controller.text = userMobile;\n }\n\n\n return TextFormField(\n controller: controller,\n enabled: !readOnly,\n decoration: InputDecoration(\n labelText: labelText,\n border: OutlineInputBorder(\n borderRadius: BorderRadius.circular(50),\n borderSide: BorderSide(color: Colors.pink),\n ),\n ),\n keyboardType: inputType,\n validator: validator,\n );\n}\n</code></pre>\n<!-- /wp:code -->