[SYNC]
This commit is contained in:
@@ -2,5 +2,6 @@ export 'package:form_controller/form_controller.dart';
|
|||||||
export 'src/controller.dart';
|
export 'src/controller.dart';
|
||||||
export 'src/form_field.dart';
|
export 'src/form_field.dart';
|
||||||
export 'src/form_value_wrapper.dart';
|
export 'src/form_value_wrapper.dart';
|
||||||
|
export 'src/form_group_wrapper.dart';
|
||||||
export 'src/enums/enums.exports.dart';
|
export 'src/enums/enums.exports.dart';
|
||||||
export 'src/models/models.exports.dart';
|
export 'src/models/models.exports.dart';
|
||||||
|
|||||||
@@ -105,6 +105,35 @@ class AstromicFormController extends FormController {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool hasGroup(String formGroupID, {bool isSubGroup = false}) {
|
||||||
|
FormGroupStructure? groupStructure;
|
||||||
|
if (isSubGroup) {
|
||||||
|
FormGroupStructure? parentGroup = _formGroups.where((FormGroupStructure f) => (f.subGroups?.map((FormGroupStructure ss) => ss.id).contains(formGroupID) ?? false)).nonNulls.toList().firstOrNull;
|
||||||
|
if (parentGroup != null && parentGroup.subGroups != null && parentGroup.subGroups!.map((FormGroupStructure i) => i.id).contains(formGroupID)) {
|
||||||
|
groupStructure = parentGroup.subGroups!.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupStructure = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return groupStructure != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormGroupStructure? getGroupStructure(String formGroupID, {bool isSubGroup = false}) {
|
||||||
|
// Get the group structure with the same ID
|
||||||
|
FormGroupStructure? groupStructure;
|
||||||
|
if (isSubGroup) {
|
||||||
|
FormGroupStructure? parentGroup = _formGroups.where((FormGroupStructure f) => (f.subGroups?.map((FormGroupStructure ss) => ss.id).contains(formGroupID) ?? false)).nonNulls.toList().firstOrNull;
|
||||||
|
if (parentGroup != null && parentGroup.subGroups != null && parentGroup.subGroups!.map((FormGroupStructure i) => i.id).contains(formGroupID)) {
|
||||||
|
groupStructure = parentGroup.subGroups!.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupStructure = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return groupStructure;
|
||||||
|
}
|
||||||
|
|
||||||
FormGroupValue? getFormGroupValue(String formGroupID, {bool isSubGroup = false}) {
|
FormGroupValue? getFormGroupValue(String formGroupID, {bool isSubGroup = false}) {
|
||||||
// Get the group structure with the same ID
|
// Get the group structure with the same ID
|
||||||
FormGroupStructure? groupStructure;
|
FormGroupStructure? groupStructure;
|
||||||
@@ -148,8 +177,11 @@ class AstromicFormController extends FormController {
|
|||||||
for (int i = 0; i < firstSetOfFieldsWithID.length; i++) {
|
for (int i = 0; i < firstSetOfFieldsWithID.length; i++) {
|
||||||
instances.add(
|
instances.add(
|
||||||
FormGroupInstance(
|
FormGroupInstance(
|
||||||
|
composedID: '$formGroupID-#$i-',
|
||||||
fields: Map<String, String>.fromEntries(fieldsIDs.map((String id) => MapEntry<String, String>('$formGroupID-#$i-$id', value('$formGroupID-#$i-$id'))).toList()),
|
fields: Map<String, String>.fromEntries(fieldsIDs.map((String id) => MapEntry<String, String>('$formGroupID-#$i-$id', value('$formGroupID-#$i-$id'))).toList()),
|
||||||
values: valuesIDs.isNotEmpty? Map<String, dynamic>.fromEntries(valuesIDs.map((String a) => MapEntry<String, dynamic>('$formGroupID-#$i-$a', getValue<dynamic>('$formGroupID-#$i-$a'))).toList()) : <String, dynamic>{},
|
values: valuesIDs.isNotEmpty
|
||||||
|
? Map<String, dynamic>.fromEntries(valuesIDs.map((String a) => MapEntry<String, dynamic>('$formGroupID-#$i-$a', getValue<dynamic>('$formGroupID-#$i-$a'))).toList())
|
||||||
|
: <String, dynamic>{},
|
||||||
subGroups: subValues,
|
subGroups: subValues,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -159,28 +191,112 @@ class AstromicFormController extends FormController {
|
|||||||
return groupValue;
|
return groupValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// void addToFormGroup(String formGroupID) {
|
String addInstanceToFormGroup(String formGroupID, {bool isSubGroup = false}) {
|
||||||
// // Get the group structure with the same ID
|
// Get the group structure with the same ID
|
||||||
// FormGroupStructure? groupWithSameID = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
FormGroupStructure? groupStructure;
|
||||||
// if (groupWithSameID == null) {
|
if (isSubGroup) {
|
||||||
// throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?');
|
FormGroupStructure? parentGroup = _formGroups.where((FormGroupStructure f) => (f.subGroups?.map((FormGroupStructure ss) => ss.id).contains(formGroupID) ?? false)).nonNulls.toList().firstOrNull;
|
||||||
// }
|
if (parentGroup != null && parentGroup.subGroups != null && parentGroup.subGroups!.map((FormGroupStructure i) => i.id).contains(formGroupID)) {
|
||||||
|
groupStructure = parentGroup.subGroups!.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
} else {
|
||||||
|
throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupStructure = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
if (groupStructure == null) {
|
||||||
|
throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// // Get the current fields with this ID
|
// Get the current fields with this ID
|
||||||
// Map<String, String> firstSetOfFieldsWithID = Map<String, String>.fromEntries(
|
Map<String, String> firstSetOfFieldsWithID = Map<String, String>.fromEntries(
|
||||||
// controllers.entries.where((MapEntry<String, String> c) => RegExp(formGroupID + r'-#[\d+]-' + groupWithSameID.fields.entries.first.key).hasMatch(c.key)).nonNulls.toList(),
|
controllers.entries.where((MapEntry<String, String> c) => RegExp(formGroupID + r'-#[\d+]-' + groupStructure!.fields.first).hasMatch(c.key)).nonNulls.toList(),
|
||||||
// );
|
);
|
||||||
|
|
||||||
// for (MapEntry<String, bool> fieldEntry in groupWithSameID.fields.entries) {
|
// get the fields IDs
|
||||||
// String fieldID = '$formGroupID-${firstSetOfFieldsWithID.length}-${fieldEntry.key}';
|
List<String> fieldsIDs = groupStructure!.fields.nonNulls.toList();
|
||||||
// controller(fieldID);
|
print('fieldIDs: $fieldsIDs');
|
||||||
// if (fieldEntry.value) {
|
// get the values IDs
|
||||||
// // Is a value field
|
List<String> valuesIDs = groupStructure.values?.nonNulls.toList() ?? <String>[];
|
||||||
// } else {
|
print('valueIDs: $valuesIDs');
|
||||||
// // Is a text field
|
|
||||||
// }
|
// Add the controllers and values.
|
||||||
// }
|
|
||||||
// }
|
for (String fieldID in groupStructure.fields) {
|
||||||
|
String finalFieldID = '${groupStructure.id}-#${firstSetOfFieldsWithID.length}-$fieldID';
|
||||||
|
controller(finalFieldID);
|
||||||
|
}
|
||||||
|
if (groupStructure.values != null && groupStructure.values!.isNotEmpty) {
|
||||||
|
for (String valueID in groupStructure.values!) {
|
||||||
|
String finalFieldID = '${groupStructure.id}-#${firstSetOfFieldsWithID.length}-$valueID';
|
||||||
|
controller(finalFieldID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '${groupStructure.id}-#${firstSetOfFieldsWithID.length}-';
|
||||||
|
}
|
||||||
|
|
||||||
|
String removeInstanceFromFormGroup(String formGroupID, int indexToRemove, {bool isSubGroup = false}) {
|
||||||
|
// Get the group structure with the same ID
|
||||||
|
FormGroupStructure? groupStructure;
|
||||||
|
if (isSubGroup) {
|
||||||
|
FormGroupStructure? parentGroup = _formGroups.where((FormGroupStructure f) => (f.subGroups?.map((FormGroupStructure ss) => ss.id).contains(formGroupID) ?? false)).nonNulls.toList().firstOrNull;
|
||||||
|
if (parentGroup != null && parentGroup.subGroups != null && parentGroup.subGroups!.map((FormGroupStructure i) => i.id).contains(formGroupID)) {
|
||||||
|
groupStructure = parentGroup.subGroups!.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
} else {
|
||||||
|
throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupStructure = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull;
|
||||||
|
if (groupStructure == null) {
|
||||||
|
throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current fields with this ID
|
||||||
|
Map<String, String> firstSetOfFieldsWithID = Map<String, String>.fromEntries(
|
||||||
|
controllers.entries.where((MapEntry<String, String> c) => RegExp(formGroupID + r'-#[\d+]-' + groupStructure!.fields.first).hasMatch(c.key)).nonNulls.toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (i >= firstSetOfFieldsWithID.length) {
|
||||||
|
throw Exception('The index to remove is larger than the whole instances count.');
|
||||||
|
} else {
|
||||||
|
// get the fields IDs
|
||||||
|
List<String> fieldsIDs = groupStructure!.fields.nonNulls.toList();
|
||||||
|
print('fieldIDs: $fieldsIDs');
|
||||||
|
// get the values IDs
|
||||||
|
List<String> valuesIDs = groupStructure.values?.nonNulls.toList() ?? <String>[];
|
||||||
|
print('valueIDs: $valuesIDs');
|
||||||
|
|
||||||
|
if (i == (firstSetOfFieldsWithID.length - 1)) {
|
||||||
|
// Remove the last item
|
||||||
|
for (String fieldID in groupStructure.fields) {
|
||||||
|
removeController('${groupStructure.id}-#$i-$fieldID');
|
||||||
|
}
|
||||||
|
if (groupStructure.values != null && groupStructure.values!.isNotEmpty) {
|
||||||
|
for (String valueID in groupStructure.values!) {
|
||||||
|
removeController('${groupStructure.id}-#$i-$valueID');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Switch and remove
|
||||||
|
int nextIndex = i + 1;
|
||||||
|
for (String fieldID in groupStructure.fields) {
|
||||||
|
set('${groupStructure.id}-#$i-$fieldID', value('${groupStructure.id}-#$nextIndex-$fieldID'));
|
||||||
|
removeController('${groupStructure.id}-#$nextIndex-$fieldID');
|
||||||
|
}
|
||||||
|
if (groupStructure.values != null && groupStructure.values!.isNotEmpty) {
|
||||||
|
for (String valueID in groupStructure.values!) {
|
||||||
|
set('${groupStructure.id}-#$i-$valueID', value('${groupStructure.id}-#$nextIndex-$valueID'));
|
||||||
|
removeController('${groupStructure.id}-#$nextIndex-$valueID');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the controllers and values.
|
||||||
|
|
||||||
|
return '${groupStructure.id}-#${firstSetOfFieldsWithID.length}-';
|
||||||
|
}
|
||||||
|
|
||||||
// void removeFromFormGroup(String formGroupID, int index) {
|
// void removeFromFormGroup(String formGroupID, int index) {
|
||||||
// // Get all the groups with the same ID
|
// // Get all the groups with the same ID
|
||||||
|
|||||||
136
lib/src/form/src/form_group_wrapper.dart
Normal file
136
lib/src/form/src/form_group_wrapper.dart
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
//s1 Imports
|
||||||
|
//s2 Packages
|
||||||
|
//s3 Core Packages
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../astromic_helpers.dart';
|
||||||
|
//s3 Internal Packages
|
||||||
|
// import 'package:astromic_elements/astromic_elements.dart';
|
||||||
|
//s3 3rd-party Packages
|
||||||
|
//s2 Utility
|
||||||
|
//s3 Configs
|
||||||
|
// import '../../../../../core/configs/routing/routing.config.dart';
|
||||||
|
//s3 Misc
|
||||||
|
//s2 Domain
|
||||||
|
//s3 Entities
|
||||||
|
//s3 Usecases
|
||||||
|
//s2 Presentation
|
||||||
|
//s3 Design
|
||||||
|
// import '../../../../design-system/design_system.dart';
|
||||||
|
//s3 Presenters
|
||||||
|
//s3 Widgets
|
||||||
|
//s1 Exports
|
||||||
|
|
||||||
|
class FormGroupWrapper extends StatefulWidget {
|
||||||
|
//SECTION - Widget Arguments
|
||||||
|
final AstromicFormController formController;
|
||||||
|
final String groupID;
|
||||||
|
final Widget Function(List<Widget> children, String Function() addItem, void Function(int) removeItem) groupBuilder;
|
||||||
|
final Widget Function(int index, String composedID, VoidCallback removeItem) itemBuilder;
|
||||||
|
final int startLength;
|
||||||
|
//!SECTION
|
||||||
|
//
|
||||||
|
const FormGroupWrapper({
|
||||||
|
super.key,
|
||||||
|
required this.formController,
|
||||||
|
required this.groupID,
|
||||||
|
required this.groupBuilder,
|
||||||
|
required this.itemBuilder,
|
||||||
|
this.startLength = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FormGroupWrapper> createState() => _FormGroupWrapperState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FormGroupWrapperState extends State<FormGroupWrapper> {
|
||||||
|
//
|
||||||
|
//SECTION - State Variables
|
||||||
|
//s1 --State
|
||||||
|
late List<FormGroupInstance> instances;
|
||||||
|
//s1 --State
|
||||||
|
//
|
||||||
|
//s1 --Controllers
|
||||||
|
//s1 --Controllers
|
||||||
|
//
|
||||||
|
//s1 --Constants
|
||||||
|
//s1 --Constants
|
||||||
|
//!SECTION
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
//
|
||||||
|
//SECTION - State Variables initializations & Listeners
|
||||||
|
//s1 --State
|
||||||
|
//s1 --State
|
||||||
|
//
|
||||||
|
//s1 --Controllers & Listeners
|
||||||
|
instances = widget.formController.getFormGroupValue(widget.groupID)!.instances;
|
||||||
|
//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 widget.groupBuilder(
|
||||||
|
// Children
|
||||||
|
List<Widget>.generate(instances.length, (int i) => widget.itemBuilder(i, instances[i].composedID, () => _removeItem(i))),
|
||||||
|
// Add Callback
|
||||||
|
() {
|
||||||
|
return widget.formController.addInstanceToFormGroup(widget.groupID);
|
||||||
|
},
|
||||||
|
// Remove Callback
|
||||||
|
(int i) => _removeItem(i),
|
||||||
|
);
|
||||||
|
//!SECTION
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeItem(int i) {
|
||||||
|
widget.formController.removeInstanceFromFormGroup(widget.groupID, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
//SECTION - Disposable variables
|
||||||
|
//!SECTION
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,21 +5,25 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'form_group_value.model.dart';
|
import 'form_group_value.model.dart';
|
||||||
|
|
||||||
class FormGroupInstance {
|
class FormGroupInstance {
|
||||||
|
String composedID;
|
||||||
Map<String, String> fields;
|
Map<String, String> fields;
|
||||||
Map<String, dynamic> values;
|
Map<String, dynamic> values;
|
||||||
List<FormGroupValue>? subGroups;
|
List<FormGroupValue>? subGroups;
|
||||||
FormGroupInstance({
|
FormGroupInstance({
|
||||||
|
required this.composedID,
|
||||||
required this.fields,
|
required this.fields,
|
||||||
required this.values,
|
required this.values,
|
||||||
this.subGroups,
|
this.subGroups,
|
||||||
});
|
});
|
||||||
|
|
||||||
FormGroupInstance copyWith({
|
FormGroupInstance copyWith({
|
||||||
|
String? composedID,
|
||||||
Map<String, String>? fields,
|
Map<String, String>? fields,
|
||||||
Map<String, dynamic>? values,
|
Map<String, dynamic>? values,
|
||||||
List<FormGroupValue>? subGroups,
|
List<FormGroupValue>? subGroups,
|
||||||
}) {
|
}) {
|
||||||
return FormGroupInstance(
|
return FormGroupInstance(
|
||||||
|
composedID: composedID ?? this.composedID,
|
||||||
fields: fields ?? this.fields,
|
fields: fields ?? this.fields,
|
||||||
values: values ?? this.values,
|
values: values ?? this.values,
|
||||||
subGroups: subGroups ?? this.subGroups,
|
subGroups: subGroups ?? this.subGroups,
|
||||||
@@ -28,6 +32,7 @@ class FormGroupInstance {
|
|||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return <String, dynamic>{
|
return <String, dynamic>{
|
||||||
|
'composedID': composedID,
|
||||||
'fields': fields,
|
'fields': fields,
|
||||||
'values': values,
|
'values': values,
|
||||||
'subGroups': subGroups?.map((FormGroupValue x) => x.toMap()).toList(),
|
'subGroups': subGroups?.map((FormGroupValue x) => x.toMap()).toList(),
|
||||||
@@ -36,6 +41,7 @@ class FormGroupInstance {
|
|||||||
|
|
||||||
factory FormGroupInstance.fromMap(Map<String, dynamic> map) {
|
factory FormGroupInstance.fromMap(Map<String, dynamic> map) {
|
||||||
return FormGroupInstance(
|
return FormGroupInstance(
|
||||||
|
composedID: map['composedID'],
|
||||||
fields: Map<String, String>.from(map['fields'] as Map<String, String>),
|
fields: Map<String, String>.from(map['fields'] as Map<String, String>),
|
||||||
values: Map<String, dynamic>.from(map['values'] as Map<String, dynamic>),
|
values: Map<String, dynamic>.from(map['values'] as Map<String, dynamic>),
|
||||||
subGroups: map['subGroups'] != null
|
subGroups: map['subGroups'] != null
|
||||||
@@ -53,16 +59,15 @@ class FormGroupInstance {
|
|||||||
factory FormGroupInstance.fromJson(String source) => FormGroupInstance.fromMap(json.decode(source) as Map<String, dynamic>);
|
factory FormGroupInstance.fromJson(String source) => FormGroupInstance.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'FormGroupInstance(fields: $fields, values: $values, subGroups: $subGroups)';
|
String toString() => 'FormGroupInstance(composedID: $composedID, fields: $fields, values: $values, subGroups: $subGroups)';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(covariant FormGroupInstance other) {
|
bool operator ==(covariant FormGroupInstance other) {
|
||||||
if (identical(this, other)) return true;
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
return mapEquals(other.fields, fields) && mapEquals(other.values, values) && listEquals(other.subGroups, subGroups);
|
return mapEquals(other.fields, fields) && mapEquals(other.values, values) && listEquals(other.subGroups, subGroups) && composedID == other.composedID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => fields.hashCode ^ values.hashCode ^ subGroups.hashCode;
|
int get hashCode => composedID.hashCode ^ fields.hashCode ^ values.hashCode ^ subGroups.hashCode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user