Merge pull request #4 from Iconica-Development/feature/input_date

add input date picker
This commit is contained in:
Jacques Doeleman 2022-10-13 12:24:38 +02:00 committed by GitHub
commit 10763d6de9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 311 additions and 8 deletions

View file

@ -1,9 +1,13 @@
## 0.0.1 - September 29th 2022 ## 0.0.2 - October 10th 2022
- Initial release - Initial release
## 0.0.2 - October 12th 2022 ## 0.1.0 - October 12th 2022
- Added a multi line plain text input widget - Added a multi line plain text input widget
- Ability to set the scrolldirection of the pageview - Ability to set the scrolldirection of the pageview
- Ability to set the scrollphysics of the pages' scrollview. - Ability to set the scrollphysics of the pages' scrollview.
## 0.2.0 - October 13th 2022
- Added date input widget

View file

@ -25,7 +25,7 @@ class _AgePageState extends State<AgePage> {
fontSize: fontSize, fontSize: fontSize,
title: "What is your age?", title: "What is your age?",
pageNumber: 1, pageNumber: 1,
amountOfPages: 3, amountOfPages: 4,
flutterFormWidgets: [ flutterFormWidgets: [
FlutterFormInputNumberPicker( FlutterFormInputNumberPicker(
minValue: 12, minValue: 12,

View file

@ -27,7 +27,7 @@ class _CarouselPageState extends State<CarouselPage> {
fontSize: fontSize, fontSize: fontSize,
title: "What's your favorite car?", title: "What's your favorite car?",
pageNumber: 3, pageNumber: 3,
amountOfPages: 3, amountOfPages: 4,
flutterFormWidgets: [ flutterFormWidgets: [
FlutterFormInputCarousel( FlutterFormInputCarousel(
controller: widget.inputController, items: getCars()) controller: widget.inputController, items: getCars())

View 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,
),
),
],
);
}
}

View file

@ -28,7 +28,7 @@ class _NamePageState extends State<NamePage> {
size: size, size: size,
fontSize: fontSize, fontSize: fontSize,
pageNumber: 2, pageNumber: 2,
amountOfPages: 3, amountOfPages: 4,
title: "Please enter your name", title: "Please enter your name",
flutterFormWidgets: [ flutterFormWidgets: [
Padding( Padding(

View file

@ -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/check_page.dart';
import 'package:form_example/example_pages/name_page.dart'; import 'package:form_example/example_pages/name_page.dart';
import 'example_pages/date_page.dart';
class FormExample extends ConsumerStatefulWidget { class FormExample extends ConsumerStatefulWidget {
const FormExample({Key? key}) : super(key: key); 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 @override
void initState() { void initState() {
super.initState(); super.initState();
@ -189,6 +200,11 @@ class _FormExampleState extends ConsumerState<FormExample> {
cars: cars, cars: cars,
), ),
), ),
FlutterFormPage(
child: DatePage(
dateController: dateController,
),
),
], ],
checkPage: CheckPageExample() checkPage: CheckPageExample()
.showCheckpage(context, size, fontSize, checkPageText), .showCheckpage(context, size, fontSize, checkPageText),

View file

@ -94,7 +94,7 @@ packages:
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
intl: intl:
dependency: transitive dependency: "direct main"
description: description:
name: intl name: intl
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"

View file

@ -16,6 +16,7 @@ dependencies:
flutter_riverpod: ^1.0.4 flutter_riverpod: ^1.0.4
flutter_form: flutter_form:
path: ../ path: ../
intl: ^0.17.0
dev_dependencies: dev_dependencies:

View file

@ -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"),
),
);
}
}

View file

@ -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;
}
}

View file

@ -4,3 +4,4 @@ export 'input_number_picker/input_number_picker.dart';
export 'input_password/input_password.dart'; export 'input_password/input_password.dart';
export 'input_plain_text.dart'; export 'input_plain_text.dart';
export 'input_slider/input_slider.dart'; export 'input_slider/input_slider.dart';
export 'input_date_picker/input_date_picker.dart';

View file

@ -6,7 +6,7 @@ homepage:
publish_to: none publish_to: none
environment: environment:
sdk: '>=2.18.0 <3.0.0' sdk: ">=2.18.0 <3.0.0"
flutter: ">=1.17.0" flutter: ">=1.17.0"
dependencies: dependencies:
@ -15,8 +15,8 @@ dependencies:
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
flutter_riverpod: ^1.0.4 flutter_riverpod: ^1.0.4
intl: ^0.17.0
localization: ^2.1.0 localization: ^2.1.0
sliding_up_panel: ^2.0.0+1 sliding_up_panel: ^2.0.0+1
uuid: ^3.0.6 uuid: ^3.0.6