mirror of
https://github.com/Iconica-Development/flutter_form_wizard.git
synced 2025-05-19 19:03:47 +02:00
Merge pull request #4 from Iconica-Development/feature/input_date
add input date picker
This commit is contained in:
commit
10763d6de9
12 changed files with 311 additions and 8 deletions
|
@ -1,9 +1,13 @@
|
|||
## 0.0.1 - September 29th 2022
|
||||
## 0.0.2 - October 10th 2022
|
||||
|
||||
- Initial release
|
||||
|
||||
## 0.0.2 - October 12th 2022
|
||||
## 0.1.0 - October 12th 2022
|
||||
|
||||
- Added a multi line plain text input widget
|
||||
- Ability to set the scrolldirection of the pageview
|
||||
- Ability to set the scrollphysics of the pages' scrollview.
|
||||
|
||||
## 0.2.0 - October 13th 2022
|
||||
|
||||
- Added date input widget
|
||||
|
|
|
@ -25,7 +25,7 @@ class _AgePageState extends State<AgePage> {
|
|||
fontSize: fontSize,
|
||||
title: "What is your age?",
|
||||
pageNumber: 1,
|
||||
amountOfPages: 3,
|
||||
amountOfPages: 4,
|
||||
flutterFormWidgets: [
|
||||
FlutterFormInputNumberPicker(
|
||||
minValue: 12,
|
||||
|
|
|
@ -27,7 +27,7 @@ class _CarouselPageState extends State<CarouselPage> {
|
|||
fontSize: fontSize,
|
||||
title: "What's your favorite car?",
|
||||
pageNumber: 3,
|
||||
amountOfPages: 3,
|
||||
amountOfPages: 4,
|
||||
flutterFormWidgets: [
|
||||
FlutterFormInputCarousel(
|
||||
controller: widget.inputController, items: getCars())
|
||||
|
|
44
example/lib/example_pages/date_page.dart
Normal file
44
example/lib/example_pages/date_page.dart
Normal file
|
@ -0,0 +1,44 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form/flutter_form.dart';
|
||||
import 'package:form_example/template_page.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class DatePage extends StatefulWidget {
|
||||
const DatePage({
|
||||
required this.dateController,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final FlutterFormInputPlainTextController dateController;
|
||||
|
||||
@override
|
||||
State<DatePage> createState() => _DatePageState();
|
||||
}
|
||||
|
||||
class _DatePageState extends State<DatePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var size = MediaQuery.of(context).size;
|
||||
var fontSize = size.height / 40;
|
||||
|
||||
return TemplatePage(
|
||||
size: size,
|
||||
fontSize: fontSize,
|
||||
pageNumber: 4,
|
||||
amountOfPages: 4,
|
||||
title: "Please enter a date",
|
||||
flutterFormWidgets: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(40, 0, 40, 40),
|
||||
child: FlutterFormInputDateTime(
|
||||
inputType: FlutterFormDateTimeType.dateTime,
|
||||
dateFormat: DateFormat.yMd(),
|
||||
firstDate: DateTime.now(),
|
||||
label: const Text("Date"),
|
||||
controller: widget.dateController,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ class _NamePageState extends State<NamePage> {
|
|||
size: size,
|
||||
fontSize: fontSize,
|
||||
pageNumber: 2,
|
||||
amountOfPages: 3,
|
||||
amountOfPages: 4,
|
||||
title: "Please enter your name",
|
||||
flutterFormWidgets: [
|
||||
Padding(
|
||||
|
|
|
@ -6,6 +6,8 @@ import 'package:form_example/example_pages/carousel_page.dart';
|
|||
import 'package:form_example/example_pages/check_page.dart';
|
||||
import 'package:form_example/example_pages/name_page.dart';
|
||||
|
||||
import 'example_pages/date_page.dart';
|
||||
|
||||
class FormExample extends ConsumerStatefulWidget {
|
||||
const FormExample({Key? key}) : super(key: key);
|
||||
|
||||
|
@ -60,6 +62,15 @@ class _FormExampleState extends ConsumerState<FormExample> {
|
|||
},
|
||||
);
|
||||
|
||||
FlutterFormInputPlainTextController dateController =
|
||||
FlutterFormInputPlainTextController(
|
||||
mandatory: true,
|
||||
id: "date",
|
||||
checkPageTitle: (dynamic date) {
|
||||
return "Date: $date";
|
||||
},
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
@ -189,6 +200,11 @@ class _FormExampleState extends ConsumerState<FormExample> {
|
|||
cars: cars,
|
||||
),
|
||||
),
|
||||
FlutterFormPage(
|
||||
child: DatePage(
|
||||
dateController: dateController,
|
||||
),
|
||||
),
|
||||
],
|
||||
checkPage: CheckPageExample()
|
||||
.showCheckpage(context, size, fontSize, checkPageText),
|
||||
|
|
|
@ -94,7 +94,7 @@ packages:
|
|||
source: sdk
|
||||
version: "0.0.0"
|
||||
intl:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.dartlang.org"
|
||||
|
|
|
@ -16,6 +16,7 @@ dependencies:
|
|||
flutter_riverpod: ^1.0.4
|
||||
flutter_form:
|
||||
path: ../
|
||||
intl: ^0.17.0
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form/utils/translation_service.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import '../../../../../flutter_form.dart';
|
||||
|
||||
/// Generates a [DateTimeInputField] for DateTimes/Dates/Times/DateRanges.
|
||||
/// It requires a [FlutterFormInputController], [inputType], [dateFormat], [firstDate], and [lastDate]
|
||||
class DateTimeInputField extends ConsumerStatefulWidget {
|
||||
const DateTimeInputField({
|
||||
Key? key,
|
||||
required this.inputType,
|
||||
required this.controller,
|
||||
this.label,
|
||||
this.showIcon = true,
|
||||
this.icon = Icons.calendar_today,
|
||||
required this.dateFormat,
|
||||
required this.firstDate,
|
||||
required this.lastDate,
|
||||
}) : super(
|
||||
key: key,
|
||||
);
|
||||
final FlutterFormDateTimeType inputType;
|
||||
final FlutterFormInputController controller;
|
||||
final DateFormat dateFormat;
|
||||
final bool showIcon;
|
||||
final DateTime? firstDate;
|
||||
final DateTime? lastDate;
|
||||
final IconData icon;
|
||||
final Widget? label;
|
||||
@override
|
||||
ConsumerState<DateTimeInputField> createState() => _DateInputFieldState();
|
||||
}
|
||||
|
||||
class _DateInputFieldState extends ConsumerState<DateTimeInputField> {
|
||||
late final DateTime firstDate;
|
||||
late final DateTime lastDate;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
firstDate = widget.firstDate ??
|
||||
DateTime.now().subtract(
|
||||
const Duration(days: 1000),
|
||||
);
|
||||
lastDate = widget.lastDate ??
|
||||
DateTime.now().add(
|
||||
const Duration(days: 1000),
|
||||
);
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String Function(String, {List<String>? params}) _ =
|
||||
getTranslator(context, ref);
|
||||
|
||||
Future<String> getInputFromUser(FlutterFormDateTimeType inputType) async {
|
||||
String userInput = '';
|
||||
switch (inputType) {
|
||||
case FlutterFormDateTimeType.date:
|
||||
DateTime? unformatted = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: firstDate,
|
||||
lastDate: lastDate,
|
||||
);
|
||||
userInput = unformatted != null
|
||||
? widget.dateFormat.format(unformatted)
|
||||
: userInput;
|
||||
break;
|
||||
case FlutterFormDateTimeType.dateTime:
|
||||
await getInputFromUser(FlutterFormDateTimeType.date)
|
||||
.then((value) async {
|
||||
if (value != '') {
|
||||
String secondInput =
|
||||
await getInputFromUser(FlutterFormDateTimeType.time);
|
||||
if (secondInput != '') {
|
||||
userInput = '$value $secondInput';
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case FlutterFormDateTimeType.range:
|
||||
userInput = (await showDateRangePicker(
|
||||
context: context,
|
||||
firstDate: firstDate,
|
||||
lastDate: lastDate,
|
||||
).then((value) {
|
||||
return value != null
|
||||
? '${widget.dateFormat.format(value.start)} - ${widget.dateFormat.format(value.end)}'
|
||||
: '';
|
||||
}))
|
||||
.toString();
|
||||
break;
|
||||
case FlutterFormDateTimeType.time:
|
||||
userInput = await showTimePicker(
|
||||
context: context, initialTime: TimeOfDay.now())
|
||||
.then((value) => value == null ? '' : value.format(context));
|
||||
}
|
||||
return userInput;
|
||||
}
|
||||
|
||||
return TextFormField(
|
||||
keyboardType: TextInputType.none,
|
||||
readOnly: true,
|
||||
key: Key(widget.controller.value.toString()),
|
||||
initialValue: widget.controller.value,
|
||||
onSaved: (value) {
|
||||
widget.controller.onSaved(value);
|
||||
},
|
||||
onTap: () async {
|
||||
String userInput = await getInputFromUser(widget.inputType);
|
||||
setState(() {
|
||||
widget.controller.value =
|
||||
userInput != '' ? userInput : widget.controller.value;
|
||||
});
|
||||
},
|
||||
validator: (value) => widget.controller.onValidate(value, _),
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: widget.showIcon ? Icon(widget.icon) : null,
|
||||
focusColor: Theme.of(context).primaryColor,
|
||||
label: widget.label ?? const Text("Date"),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form/src/widgets/input/input_types/input_date_picker/date_picker.dart';
|
||||
import 'package:flutter_form/utils/translation_service.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../../../../flutter_form.dart';
|
||||
|
||||
/// Select Input Types in a [FlutterFormInputDateTime]
|
||||
enum FlutterFormDateTimeType {
|
||||
date,
|
||||
time,
|
||||
dateTime,
|
||||
range,
|
||||
}
|
||||
|
||||
/// Input for a dateTime used in a [FlutterForm].
|
||||
///
|
||||
/// Standard controller is [FlutterFormInputDateController].
|
||||
class FlutterFormInputDateTime extends FlutterFormInputWidget {
|
||||
const FlutterFormInputDateTime({
|
||||
Key? key,
|
||||
required FlutterFormInputController controller,
|
||||
Widget? label,
|
||||
this.showIcon = true,
|
||||
required this.inputType,
|
||||
required this.dateFormat,
|
||||
this.firstDate,
|
||||
this.lastDate,
|
||||
this.icon = Icons.calendar_today,
|
||||
}) : super(
|
||||
key: key,
|
||||
controller: controller,
|
||||
label: label,
|
||||
);
|
||||
final bool showIcon;
|
||||
final FlutterFormDateTimeType inputType;
|
||||
final DateFormat dateFormat;
|
||||
final DateTime? firstDate;
|
||||
final DateTime? lastDate;
|
||||
final IconData icon;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
String Function(String, {List<String>? params}) _ =
|
||||
getTranslator(context, ref);
|
||||
super.registerController(context);
|
||||
|
||||
return DateTimeInputField(
|
||||
firstDate: firstDate,
|
||||
lastDate: lastDate,
|
||||
inputType: inputType,
|
||||
controller: controller,
|
||||
dateFormat: dateFormat,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Controller for dates used by a [FlutterFormInputWidget] used in a [FlutterForm].
|
||||
///
|
||||
/// Mainly used by [FlutterFormInputDateTime].
|
||||
class FlutterFormInputDateTimeController
|
||||
implements FlutterFormInputController<String> {
|
||||
FlutterFormInputDateTimeController({
|
||||
required this.id,
|
||||
this.mandatory = true,
|
||||
this.value,
|
||||
this.checkPageTitle,
|
||||
this.checkPageDescription,
|
||||
required this.dateTimeType,
|
||||
required this.dateFormat,
|
||||
});
|
||||
|
||||
final DateFormat dateFormat;
|
||||
final FlutterFormDateTimeType dateTimeType;
|
||||
|
||||
@override
|
||||
String? id;
|
||||
|
||||
@override
|
||||
String? value;
|
||||
|
||||
@override
|
||||
bool mandatory;
|
||||
|
||||
@override
|
||||
String Function(String value)? checkPageTitle;
|
||||
|
||||
@override
|
||||
String Function(String value)? checkPageDescription;
|
||||
|
||||
@override
|
||||
void onSaved(dynamic value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@override
|
||||
String? onValidate(String? value,
|
||||
String Function(String, {List<String>? params}) translator) {
|
||||
if (mandatory) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return translator('shell.form.error.empty');
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -4,3 +4,4 @@ export 'input_number_picker/input_number_picker.dart';
|
|||
export 'input_password/input_password.dart';
|
||||
export 'input_plain_text.dart';
|
||||
export 'input_slider/input_slider.dart';
|
||||
export 'input_date_picker/input_date_picker.dart';
|
||||
|
|
|
@ -6,7 +6,7 @@ homepage:
|
|||
publish_to: none
|
||||
|
||||
environment:
|
||||
sdk: '>=2.18.0 <3.0.0'
|
||||
sdk: ">=2.18.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
|
||||
dependencies:
|
||||
|
@ -15,8 +15,8 @@ dependencies:
|
|||
flutter_localizations:
|
||||
sdk: flutter
|
||||
flutter_riverpod: ^1.0.4
|
||||
intl: ^0.17.0
|
||||
localization: ^2.1.0
|
||||
|
||||
sliding_up_panel: ^2.0.0+1
|
||||
uuid: ^3.0.6
|
||||
|
||||
|
|
Loading…
Reference in a new issue