Skip to content

Instantly share code, notes, and snippets.

@austinn
Created April 4, 2024 18:04
Show Gist options
  • Save austinn/842e5debb272200408a0f4637f34095d to your computer and use it in GitHub Desktop.
Save austinn/842e5debb272200408a0f4637f34095d to your computer and use it in GitHub Desktop.
Basic Flutter List Form
// Copyright 2019 the Dart project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(body: const HomeScreen()),
);
}
}
class FormData {
String? name;
String? email;
bool? enable;
FormData({this.name, this.email, this.enable});
}
class HomeScreen extends StatefulHookConsumerWidget {
static const name = 'home';
static const path = '/home';
const HomeScreen({super.key});
@override
ConsumerState<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends ConsumerState<HomeScreen> {
// List to store form data
List<FormData> formsData = [];
List<GlobalKey<FormState>> formKeys = [];
@override
void initState() {
super.initState();
for (int i = 0; i < 3; i++) {
formsData.add(FormData());
formKeys.add(GlobalKey<FormState>());
}
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: formsData.length,
itemBuilder: (context, index) {
return CheckboxListTile(
onChanged: null,
title: Text('Name: ${formsData[index].name}'),
subtitle: Text('Email: ${formsData[index].email}'),
value: formsData[index].enable ?? false,
);
},
),
const SizedBox(height: 16),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: formsData.length,
separatorBuilder: (context, index) {
return const SizedBox(height: 16.0);
},
itemBuilder: (context, index) {
final data = formsData[index];
final key = formKeys[index];
return FormCard(
formKey: key,
formData: data,
);
},
),
const SizedBox(height: 16.0),
ElevatedButton(
onPressed: () {
for (int i = 0; i < formsData.length; i++) {
final formKey = formKeys[i];
final form = formKey.currentState;
if (form != null && form.validate()) {
setState(() {
form.save();
});
}
}
},
child: const Text('Submit'),
),
],
),
),
);
}
}
class FormCard extends StatefulHookWidget {
const FormCard({
super.key,
required this.formKey,
required this.formData,
});
final GlobalKey<FormState> formKey;
final FormData formData;
@override
State<FormCard> createState() => _FormCardState();
}
class _FormCardState extends State<FormCard> {
@override
Widget build(BuildContext context) {
final nameController = useTextEditingController();
final emailController = useTextEditingController();
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: widget.formKey,
child: Column(
children: [
TextFormField(
controller: nameController,
decoration: const InputDecoration(labelText: 'Name'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter name';
}
return null;
},
onSaved: (value) {
print('Saving name: $value');
widget.formData.name = value;
},
),
const SizedBox(height: 8.0),
TextFormField(
controller: emailController,
decoration: const InputDecoration(labelText: 'Email'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter email';
}
return null;
},
onSaved: (value) {
print('Saving email: $value');
widget.formData.email = value;
},
),
const SizedBox(height: 8.0),
CheckboxListTile(
title: const Text('Enable'),
value: widget.formData.enable ?? false,
onChanged: (value) {
setState(() {
widget.formData.enable = value;
});
},
),
],
),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment