From 1eb18a89824f62ecf325e5ac8f7ae2bacd8310e0 Mon Sep 17 00:00:00 2001 From: "Michael W. Aziz" Date: Tue, 1 Apr 2025 14:39:38 +0200 Subject: [PATCH] [0.1.2] --- lib/src/form/src/controller.dart | 82 ++++++---------- lib/src/form/src/form_group_wrapper.dart | 117 +++++++++++++++++++++++ pubspec.lock | 9 +- pubspec.yaml | 5 +- 4 files changed, 156 insertions(+), 57 deletions(-) create mode 100644 lib/src/form/src/form_group_wrapper.dart diff --git a/lib/src/form/src/controller.dart b/lib/src/form/src/controller.dart index 925e847..a1442d6 100644 --- a/lib/src/form/src/controller.dart +++ b/lib/src/form/src/controller.dart @@ -21,8 +21,8 @@ class AstromicFormController extends FormController { final Map fieldStates = {}; final Map fieldMessages = {}; final Map _hostedValues = {}; - // final Map>? streamedErrorMaps; // fieldId: {errorCode: errorMessage} final Stream>? errorStream; + // State Stream Variables static final StreamController<(String, AstromicFieldState)> _stateStreamController = StreamController<(String id, AstromicFieldState)>.broadcast(); final Stream<(String id, AstromicFieldState)> stateStream = _stateStreamController.stream; @@ -32,35 +32,23 @@ class AstromicFormController extends FormController { final Stream<(String id, bool isValidationErrored)> hostedValueValidationStream = _hostedValueValidationStreamController.stream; AstromicFormController({ - Map? extraControllers, - // this.streamedErrorMaps, + Map? initialValues, this.errorStream, - }) : super(controllers: extraControllers) { + }) : super(initialValues) { // Add states and messages based on initial controller. - _addInitialControllers(); + _addInitialControllers(initialValues ?? {}); } - /// Get all the available controllers with their current values - Map get allControllers => Map.fromEntries({ - ...?controllers, - ...?super.controllers, - }.entries.map((MapEntry entry) => MapEntry(entry.key, value(entry.key))).toList()); - - bool hasKey(String id) => allControllers.containsKey(id); + /// Does the controller has a field with this ID. + bool hasKey(String id) => controllers.containsKey(id); /// Get the field state and message of a specific field using it's ID. - (AstromicFieldState, String? message)? getState(String fieldId) { - if (fieldStates.containsKey(fieldId)) { - return (fieldStates[fieldId]!, fieldMessages[fieldId]); - } else { - return null; - } - } + (AstromicFieldState, String? message)? getState(String fieldId) => (fieldStates.containsKey(fieldId)) ? (fieldStates[fieldId]!, fieldMessages[fieldId]) : null; /// Set the field state and message of a specific field using it's ID. void setState(String fieldId, AstromicFieldState state, {String? message}) { if (!fieldStates.containsKey(fieldId)) { - throw FlutterError('Field ID $fieldId does not exist.'); + throw Exception('Field ID $fieldId does not exist.'); } fieldStates[fieldId] = state; fieldMessages[fieldId] = message; @@ -68,10 +56,9 @@ class AstromicFormController extends FormController { } /// Reset the state of a specific field using it's ID. - resetState(String fieldId) { - setState(fieldId, AstromicFieldState.idle); - } + void resetState(String fieldId) => setState(fieldId, AstromicFieldState.idle); + /// Validate hosted values. bool validateValues(List valueIDs) { for (String hostedValueID in valueIDs) { if (_hostedValues.containsKey(hostedValueID) && _hostedValues[hostedValueID]!.$2 && _hostedValues[hostedValueID]!.$1 == null) { @@ -90,13 +77,6 @@ class AstromicFormController extends FormController { } } - /// Set the value of a hosted state variable using it's ID. - void setValue(String id, T data, {bool isRequired = false}) { - prepareValue(id, isRequired); - _hostedValues[id] = (data, isRequired); - _hostedValueValidationStreamController.add((id, false)); - } - /// Get the value of a hosted state variable using it's ID. T? getValue(String id) { prepareValue(id, false); @@ -104,48 +84,46 @@ class AstromicFormController extends FormController { if (_hostedValues[id]?.$1 is T?) { return _hostedValues[id]?.$1; } else { - throw FlutterError('Value found but is not of the type $T, it\'s of type ${_hostedValues[id]?.$1.runtimeType}'); + throw Exception('Value found but is not of the type $T, it\'s of type ${_hostedValues[id]?.$1.runtimeType}'); } } + /// Set the value of a hosted state variable using it's ID. + void setValue(String id, T data, {bool isRequired = false}) { + prepareValue(id, isRequired); + _hostedValues[id] = (data, isRequired); + _hostedValueValidationStreamController.add((id, false)); + } + @override TextEditingController controller(String id, {String? initialText, bool isObscure = false}) { - if (super.controllers == null || !super.controllers!.keys.toList().contains(id)) { + TextEditingController ret = super.controller(id, initialText: initialText, isObscure: isObscure); + // + if (!hasKey(id)) { fieldStates.addEntries(>[MapEntry(id, AstromicFieldState.idle)]); fieldMessages.addEntries(>[MapEntry(id, null)]); } - - TextEditingController ret = super.controller(id, initialText: initialText, isObscure: isObscure); SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) { if (ret.text.isEmpty) { ret.text = initialText ?? ''; } }); - super.controllers?.addEntries(>[MapEntry(id, (ret.text, isObscure))]); return ret; } - @override - Future dispose() async { - // _stateStreamController.close(); - super.dispose(); - } - //SECTION - Helper Methods - _addInitialControllers() { + _addInitialControllers(Map initialValues) { // Add in the initial field states... - fieldStates.addEntries(super.controllers?.entries.toList().map((MapEntry e) => MapEntry( - e.key, // controller ID - AstromicFieldState.idle, // Initial state of any new controller is Idle - )) ?? - >{}); + fieldStates.addEntries(initialValues.entries.toList().map((MapEntry e) => MapEntry( + e.key, // controller ID + AstromicFieldState.idle, // Initial state of any new controller is Idle + ))); // Add in the initial field messages... - fieldMessages.addEntries(super.controllers?.entries.toList().map((MapEntry e) => MapEntry( - e.key, // Controller ID - null, // The initial message it has which is Null - )) ?? - >{}); + fieldMessages.addEntries(initialValues.entries.toList().map((MapEntry e) => MapEntry( + e.key, // Controller ID + null, // The initial message it has which is Null + ))); } //!SECTION } diff --git a/lib/src/form/src/form_group_wrapper.dart b/lib/src/form/src/form_group_wrapper.dart new file mode 100644 index 0000000..f431f19 --- /dev/null +++ b/lib/src/form/src/form_group_wrapper.dart @@ -0,0 +1,117 @@ +// //s1 Imports +// //s2 Packages +// //s3 Core Packages +// import 'package:flutter/material.dart'; + +// import '../../sheet/sheet_helper.astromic.dart'; +// //s3 Internal Packages +// //s3 3rd-party Packages +// //s2 Utility +// //s3 Configs +// //s3 Misc +// //s2 Domain +// //s3 Entities +// //s3 Usecases +// //s2 Presentation +// //s3 Design +// //s3 Presenters +// //s3 Widgets +// //s1 Exports + +// class FormGroupWrapper extends StatefulWidget { +// //SECTION - Widget Arguments +// final AstromicFormController formController; +// final String identifier; +// //!SECTION +// // +// const FormGroupWrapper({ +// super.key, +// required this.formController, +// required this +// }); + +// @override +// State createState() => _FormGroupWrapperState(); +// } + +// class _FormGroupWrapperState extends State { +// // +// //SECTION - State Variables +// //s1 --State +// //s1 --State +// // +// //s1 --Controllers +// //late AstromicFormController _formController; +// //s1 --Controllers +// // +// //s1 --Constants +// //s1 --Constants +// //!SECTION + +// @override +// void initState() { +// super.initState(); +// // +// //SECTION - State Variables initializations & Listeners +// //s1 --State +// //s1 --State +// // +// //s1 --Controllers & Listeners +// // _formController = AstromicFormController(); +// //s1 --Controllers & Listeners +// // +// //s1 --Late & Async Initializers +// //s1 --Late & Async Initializers +// //!SECTION +// } + + +// @override +// void didChangeDependencies() { +// super.didChangeDependencies(); +// // +// //SECTION - State Variables initializations & Listeners +// //s1 --State +// //s1 --State +// // +// //s1 --Controllers & Listeners +// //s1 --Controllers & Listeners +// // +// //!SECTION +// } + +// //SECTION - Dumb Widgets +// //!SECTION + +// //SECTION - Stateless functions +// //!SECTION + +// //SECTION - Action Callbacks +// //!SECTION + +// @override +// Widget build(BuildContext context) { +// //SECTION - Build Setup +// //s1 --Values +// //double w = MediaQuery.of(context).size.width; +// //double h = MediaQuery.of(context).size.height; +// //s1 --Values +// // +// //s1 --Contexted Widgets +// //s1 --Contexted Widgets +// //!SECTION + +// //SECTION - Build Return +// return const Scaffold( +// body: Center(child:Text(FormGroupWrapper)), +// ); +// //!SECTION +// } + +// @override +// void dispose() { +// //SECTION - Disposable variables +// //!SECTION +// super.dispose(); +// } +// } diff --git a/pubspec.lock b/pubspec.lock index 08f1978..c807350 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -163,10 +163,11 @@ packages: form_controller: dependency: "direct main" description: - name: form_controller - sha256: "5e0f905cc8802ac787bd295900a122fa2a0b1a26070477666de0b9c3b4263e0c" - url: "https://pub.dev" - source: hosted + path: "." + ref: master + resolved-ref: "3938957cf30df607711b4bbdf8ee5a1dff89f802" + url: "https://git.micazi.dev/micazi/form_controller.git" + source: git version: "0.8.8+2" http: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index 1f70a00..5020ba4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,9 @@ dependencies: ## Needed for the sheet helper. provider: ^6.1.2 ## Needed for the form helper. - form_controller: ^0.8.8+2 + form_controller: + git: + url: https://git.micazi.dev/micazi/form_controller.git + ref: master ## Needed for the loading helper. loader_overlay: ^5.0.0