2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 05:26:47 +00:00

Better handling of date inputs within forms

- use datetime_picker_formfield
- Allow null / empty dates
This commit is contained in:
Oliver 2021-10-05 21:19:35 +11:00
parent 4a238d0530
commit 21271d71c1
4 changed files with 39 additions and 25 deletions

View File

@ -1,9 +1,10 @@
import "dart:ui"; import "dart:ui";
import "dart:io"; import "dart:io";
import "package:intl/intl.dart";
import "package:font_awesome_flutter/font_awesome_flutter.dart"; import "package:font_awesome_flutter/font_awesome_flutter.dart";
import "package:dropdown_search/dropdown_search.dart"; import "package:dropdown_search/dropdown_search.dart";
import "package:date_field/date_field.dart"; import "package:datetime_picker_formfield/datetime_picker_formfield.dart";
import "package:inventree/api.dart"; import "package:inventree/api.dart";
import "package:inventree/app_colors.dart"; import "package:inventree/app_colors.dart";
@ -21,7 +22,6 @@ import "package:flutter/material.dart";
import "package:inventree/widget/snacks.dart"; import "package:inventree/widget/snacks.dart";
/* /*
* Class that represents a single "form field", * Class that represents a single "form field",
* defined by the InvenTree API * defined by the InvenTree API
@ -114,11 +114,11 @@ class APIFormField {
dynamic get value => data["value"] ?? data["instance_value"] ?? defaultValue; dynamic get value => data["value"] ?? data["instance_value"] ?? defaultValue;
// Render value to string (for form submission) // Render value to string (for form submission)
String renderToString() { String renderValueToString() {
if (value == null) { if (data["value"] == null) {
return ""; return "";
} else { } else {
return value.toString(); return data["value"].toString();
} }
} }
@ -359,22 +359,37 @@ class APIFormField {
// Field for displaying and selecting dates // Field for displaying and selecting dates
Widget _constructDateField() { Widget _constructDateField() {
return DateTimeFormField( DateTime? currentDate = DateTime.tryParse((value ?? "")as String);
mode: DateTimeFieldPickerMode.date,
return InputDecorator(
decoration: InputDecoration( decoration: InputDecoration(
helperText: helpText,
helperStyle: _helperStyle(),
labelText: label, labelText: label,
labelStyle: _labelStyle(), labelStyle: _labelStyle(),
helperStyle: _helperStyle(),
helperText: helpText,
), ),
initialValue: DateTime.tryParse((value ?? "") as String), child: DateTimeField(
autovalidateMode: AutovalidateMode.disabled, format: DateFormat("yyyy-MM-dd"),
validator: (e) { initialValue: currentDate,
// TODO onChanged: (DateTime? time) {
}, // Save the time string
onDateSelected: (DateTime dt) { if (time == null) {
data["value"] = dt.toString().split(" ").first; data["value"] = null;
}, } else {
data["value"] = time.toString().split(" ").first;
}
},
onShowPicker: (context, value) async {
final time = await showDatePicker(
context: context,
initialDate: currentDate ?? DateTime.now(),
firstDate: DateTime(1900),
lastDate: DateTime(2100),
);
return time;
},
)
); );
} }
@ -403,7 +418,6 @@ class APIFormField {
FilePickerDialog.pickFile( FilePickerDialog.pickFile(
message: L10().attachmentSelect, message: L10().attachmentSelect,
onPicked: (file) { onPicked: (file) {
// print("${file.path}");
// Display the filename // Display the filename
controller.text = file.path.split("/").last; controller.text = file.path.split("/").last;
@ -1122,7 +1136,7 @@ class _APIFormWidgetState extends State<APIFormWidget> {
if (field.isSimple) { if (field.isSimple) {
// Simple top-level field data // Simple top-level field data
data[field.name] = field.renderToString(); data[field.name] = field.data["value"];
} else { } else {
// Not so simple... (WHY DID I MAKE THE API SO COMPLEX?) // Not so simple... (WHY DID I MAKE THE API SO COMPLEX?)
if (field.parent.isNotEmpty) { if (field.parent.isNotEmpty) {
@ -1136,7 +1150,7 @@ class _APIFormWidgetState extends State<APIFormWidget> {
parent = parent.first; parent = parent.first;
} }
parent[field.name] = field.renderToString(); parent[field.name] = field.data["value"];
// Nested fields must be handled as an array! // Nested fields must be handled as an array!
// For now, we only allow single length nested fields // For now, we only allow single length nested fields

View File

@ -94,7 +94,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => PurchaseOrderListWidget() builder: (context) => PurchaseOrderListWidget(filters: {})
) )
); );
} }

View File

@ -127,13 +127,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.3" version: "1.0.3"
date_field: datetime_picker_formfield:
dependency: "direct main" dependency: "direct main"
description: description:
name: date_field name: datetime_picker_formfield
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.2" version: "2.0.0"
device_info_plus: device_info_plus:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -18,7 +18,7 @@ dependencies:
cached_network_image: ^3.1.0 # Download and cache remote images cached_network_image: ^3.1.0 # Download and cache remote images
camera: # Camera camera: # Camera
cupertino_icons: ^1.0.3 cupertino_icons: ^1.0.3
date_field: ^2.1.2 # Date / time picker datetime_picker_formfield: ^2.0.0 # Date / time picker
device_info_plus: ^2.1.0 # Information about the device device_info_plus: ^2.1.0 # Information about the device
dropdown_search: 0.6.3 # Dropdown autocomplete form fields dropdown_search: 0.6.3 # Dropdown autocomplete form fields
file_picker: ^4.0.0 # Select files from the device file_picker: ^4.0.0 # Select files from the device