2021-10-22 23:08:09 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
class FormWrapper extends StatefulWidget {
|
2021-10-22 23:08:09 +00:00
|
|
|
final List<Widget>? fields;
|
|
|
|
final List<Widget>? buttons;
|
|
|
|
final GlobalKey<FormState>? formState;
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
const FormWrapper({Key? key, this.formState, this.fields, this.buttons})
|
2021-10-22 23:08:09 +00:00
|
|
|
: super(key: key);
|
|
|
|
|
|
|
|
@override
|
2021-11-09 00:17:35 +00:00
|
|
|
_FormWrapperState createState() => _FormWrapperState();
|
2021-10-22 23:08:09 +00:00
|
|
|
}
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
class _FormWrapperState extends State<FormWrapper> {
|
2021-10-22 23:08:09 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Padding(
|
|
|
|
padding: const EdgeInsets.all(10.0),
|
|
|
|
child: Form(
|
|
|
|
key: widget.formState,
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Column(
|
|
|
|
children: widget.fields
|
2021-12-09 05:14:55 +00:00
|
|
|
?.map((e) => Padding(
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 5.0),
|
|
|
|
child: e))
|
|
|
|
.toList() ??
|
|
|
|
[],
|
2021-10-22 23:08:09 +00:00
|
|
|
),
|
|
|
|
Container(
|
|
|
|
padding: const EdgeInsets.only(top: 10.0),
|
|
|
|
child: Row(
|
|
|
|
mainAxisSize: MainAxisSize.max,
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
children: widget.buttons ?? [],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
class BooleanFormField extends StatefulWidget {
|
2021-10-22 23:08:09 +00:00
|
|
|
final bool value;
|
|
|
|
final String label;
|
|
|
|
final void Function(bool) onChanged;
|
|
|
|
final bool? enabled;
|
2021-12-04 23:44:46 +00:00
|
|
|
final EdgeInsets? contentPadding;
|
2021-10-22 23:08:09 +00:00
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
const BooleanFormField(
|
2021-10-22 23:08:09 +00:00
|
|
|
{Key? key,
|
|
|
|
required this.value,
|
|
|
|
required this.label,
|
|
|
|
required this.onChanged,
|
2021-12-04 23:44:46 +00:00
|
|
|
this.enabled,
|
|
|
|
this.contentPadding})
|
2021-10-22 23:08:09 +00:00
|
|
|
: super(key: key);
|
|
|
|
|
|
|
|
@override
|
2021-11-09 00:17:35 +00:00
|
|
|
_BooleanFormFieldState createState() => _BooleanFormFieldState();
|
2021-10-22 23:08:09 +00:00
|
|
|
}
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
class _BooleanFormFieldState extends State<BooleanFormField> {
|
2021-10-22 23:08:09 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2021-11-24 23:19:27 +00:00
|
|
|
return FormField<bool>(builder: (state) {
|
2021-10-22 23:08:09 +00:00
|
|
|
return ListTile(
|
2021-12-04 23:44:46 +00:00
|
|
|
contentPadding: widget.contentPadding,
|
2021-10-22 23:08:09 +00:00
|
|
|
onTap: () => widget.onChanged(!widget.value),
|
|
|
|
trailing: Switch(
|
|
|
|
value: widget.value,
|
|
|
|
onChanged: widget.onChanged,
|
|
|
|
),
|
|
|
|
title: Text(widget.label),
|
|
|
|
enabled: widget.enabled ?? true,
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
class DateTimeFormField extends StatefulWidget {
|
|
|
|
final DateTime date;
|
|
|
|
final DateTime? minDate;
|
|
|
|
final DateTime? maxDate;
|
|
|
|
final TextEditingController controller;
|
|
|
|
final String label;
|
|
|
|
final void Function(DateTime?) onChanged;
|
|
|
|
|
|
|
|
const DateTimeFormField(
|
|
|
|
{Key? key,
|
|
|
|
required this.date,
|
|
|
|
this.minDate,
|
|
|
|
this.maxDate,
|
|
|
|
required this.controller,
|
|
|
|
required this.label,
|
|
|
|
required this.onChanged})
|
|
|
|
: super(key: key);
|
|
|
|
|
|
|
|
@override
|
2021-11-24 23:19:27 +00:00
|
|
|
_DateTimeFormFieldState createState() => _DateTimeFormFieldState();
|
2021-11-09 00:17:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class _DateTimeFormFieldState extends State<DateTimeFormField> {
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return TextFormField(
|
|
|
|
readOnly: true,
|
|
|
|
controller: widget.controller,
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: widget.label,
|
|
|
|
),
|
|
|
|
onTap: () async {
|
|
|
|
final newTime = await showDatePicker(
|
|
|
|
context: context,
|
|
|
|
initialDate: widget.date,
|
2021-11-24 23:19:27 +00:00
|
|
|
firstDate: widget.minDate ?? DateTime(2000, 1, 1),
|
2021-12-04 23:44:46 +00:00
|
|
|
lastDate:
|
|
|
|
widget.maxDate ?? DateTime.now().add(const Duration(days: 365)),
|
2021-11-09 00:17:35 +00:00
|
|
|
);
|
|
|
|
widget.onChanged(newTime);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class TimeOfDayFormField extends StatefulWidget {
|
2021-10-22 23:08:09 +00:00
|
|
|
final TimeOfDay time;
|
|
|
|
final TextEditingController controller;
|
|
|
|
final String label;
|
|
|
|
final void Function(TimeOfDay?) onChanged;
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
const TimeOfDayFormField(
|
2021-10-22 23:08:09 +00:00
|
|
|
{Key? key,
|
|
|
|
required this.time,
|
|
|
|
required this.controller,
|
|
|
|
required this.label,
|
|
|
|
required this.onChanged})
|
|
|
|
: super(key: key);
|
|
|
|
|
|
|
|
@override
|
2021-11-24 23:19:27 +00:00
|
|
|
_TimeOfDayFormFieldState createState() => _TimeOfDayFormFieldState();
|
2021-10-22 23:08:09 +00:00
|
|
|
}
|
|
|
|
|
2021-11-09 00:17:35 +00:00
|
|
|
class _TimeOfDayFormFieldState extends State<TimeOfDayFormField> {
|
2021-10-22 23:08:09 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return TextFormField(
|
|
|
|
readOnly: true,
|
|
|
|
controller: widget.controller,
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: widget.label,
|
|
|
|
),
|
|
|
|
onTap: () async {
|
|
|
|
final newTime = await showTimePicker(
|
|
|
|
context: context,
|
|
|
|
initialTime: widget.time,
|
|
|
|
);
|
|
|
|
widget.onChanged(newTime);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|