Skip to content

Instantly share code, notes, and snippets.

@lukluk
Created May 28, 2024 16:49
Show Gist options
  • Save lukluk/2af405c3301db6f4fd500b4f2f76e721 to your computer and use it in GitHub Desktop.
Save lukluk/2af405c3301db6f4fd500b4f2f76e721 to your computer and use it in GitHub Desktop.
table
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
class TableWidget extends StatefulWidget {
final List<String> headers;
final String apiUrl;
const TableWidget({super.key, required this.headers, required this.apiUrl});
@override
_TableWidgetState createState() => _TableWidgetState();
}
class _TableWidgetState extends State<TableWidget> {
List<Map<String, dynamic>> items = [];
String searchText = '';
@override
void initState() {
super.initState();
_fetchData("");
}
Future<void> _fetchData(String search) async {
final response = await http.get(
Uri.parse(widget.apiUrl + (search.isNotEmpty ? '?q=$search' : '')));
final data = jsonDecode(response.body);
setState(() {
searchText = search;
items = data.cast<Map<String, dynamic>>();
});
}
@override
Widget build(BuildContext context) {
var search = TextEditingController(text: searchText);
return Scaffold(
body: ListView(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
),
child: Row(
children: [
Expanded(
child: TextField(
controller: search,
decoration: const InputDecoration(
labelText: 'Search',
border: OutlineInputBorder(),
),
onSubmitted: (value) {
_fetchData(value);
},
),
),
SizedBox(
width: 50,
child: IconButton(
onPressed: () {
_fetchData(search.text);
},
icon: const Icon(Icons.search),
))
],
),
),
_buildHeader(widget.headers),
for (var i = 0; i < items.length; i++)
_buildRow(i, items[i], widget.headers),
],
),
floatingActionButton: AddButton(widget: widget),
);
}
Widget _buildHeader(List<String> headers) {
return Container(
color: ColorPalette.header,
child: Row(
children: [
for (var header in headers)
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
header,
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
),
const Expanded(
child: Text(
"Actions",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
// Add more header columns here
],
),
);
}
Widget _buildRow(int index, Map<String, dynamic> item, List<String> headers) {
return Container(
color: _isEvenRow(index) ? ColorPalette.primary : ColorPalette.primaryVariant,
child: Row(
children: [
for (var header in headers)
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
item[header].toString(),
),
),
),
Expanded(
child: IconButton(
onPressed: () {
// Edit button logic here
List<TextEditingController> textFieldControllers = [];
for (var index = 0; index < headers.length; index++) {
textFieldControllers.add(TextEditingController(
text: item[headers[index]].toString()));
}
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Edit Item'),
content: Column(
children: [
for (var index = 0; index < headers.length; index++)
TextFormField(
enabled: headers[index] != 'id',
decoration:
InputDecoration(labelText: headers[index]),
controller: textFieldControllers[index],
),
],
),
actions: [
TextButton(
onPressed: () async {
// Edit button logic here
final requestBody = {};
for (var index = 0;
index < headers.length;
index++) {
final header = headers[index];
final textFieldValue =
textFieldControllers[index].text;
requestBody[header] = textFieldValue;
}
final response = await http.put(
Uri.parse('${widget.apiUrl}/${item['id']}'),
body: jsonEncode(requestBody),
headers: {'Content-Type': 'application/json'},
);
if (response.statusCode == 200) {
Fluttertoast.showToast(
msg: 'Item edited successfully',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 10,
backgroundColor: Colors.green,
textColor: Colors.white,
);
Navigator.of(context).pop();
} else {
// Error occurred while editing item, handle the error if needed
Fluttertoast.showToast(
msg:
'Failed to edit item: ${response.statusCode}',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 10,
backgroundColor: Colors.red,
textColor: Colors.white,
);
Navigator.of(context).pop();
}
},
child: const Text('Edit'),
),
],
);
},
);
},
icon: const Icon(Icons.edit),
),
),
],
),
);
}
bool _isEvenRow(int index) {
return index % 2 == 0;
}
}
class AddButton extends StatelessWidget {
const AddButton({
super.key,
required this.widget,
});
final TableWidget widget;
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: () {
List<TextEditingController> textFieldControllers = [];
final headers = List<String>.from(widget.headers);
headers.remove('id');
for (var _ in headers) {
textFieldControllers.add(TextEditingController());
}
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Add Item'),
content: Column(
children: [
for (var index = 0; index < headers.length; index++)
TextField(
decoration: InputDecoration(labelText: headers[index]),
controller: textFieldControllers[index],
),
],
),
actions: [
TextButton(
onPressed: () async {
// Add button logic here
final requestBody = {};
for (var index = 0; index < headers.length; index++) {
final header = headers[index];
final textFieldValue = textFieldControllers[index].text;
requestBody[header] = textFieldValue;
}
final response = await http.post(
Uri.parse(widget.apiUrl),
body: jsonEncode(requestBody),
headers: {'Content-Type': 'application/json'},
);
if (response.statusCode == 200) {
Fluttertoast.showToast(
msg: 'Item added successfully',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 10,
backgroundColor: Colors.green,
textColor: Colors.white,
);
Navigator.of(context).pop();
} else {
// Error occurred while adding item, handle the error if needed
Fluttertoast.showToast(
msg: 'Failed to add item: ${response.statusCode}',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 10,
backgroundColor: Colors.red,
textColor: Colors.white,
);
Navigator.of(context).pop();
}
},
child: const Text('Add'),
),
],
);
},
);
},
child: const Icon(Icons.add),
);
}
}
class ColorPalette {
static const Color primary = Color.fromARGB(255, 255, 255, 255);
static const Color primaryVariant = Color.fromARGB(255, 180, 235, 223);
static const Color header = Color(0xFF03DAC6);
static const Color secondaryVariant = Color(0xFF018786);
// Add your code here
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment