diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..fa0b357 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/lib/src/form/src/controller.dart b/lib/src/form/src/controller.dart index a6c34f5..a40f82d 100644 --- a/lib/src/form/src/controller.dart +++ b/lib/src/form/src/controller.dart @@ -1,6 +1,5 @@ //s1 Imports //s2 Core Package Imports -// ignore_for_file: close_sinks import 'dart:async'; import 'package:flutter/widgets.dart'; @@ -13,7 +12,9 @@ import 'package:form_controller/form_controller.dart'; //s3 Services //s3 Models & Widgets import 'enums/enums.exports.dart'; +import 'models/form_group_instance.model.dart'; import 'models/form_group_structure.model.dart'; +import 'models/form_group_value.model.dart'; //s1 Exports /// A specialized form controller to handle form states, @@ -61,21 +62,22 @@ class AstromicFormController extends FormController { */ // At the start of a screen? - void initializeFormGroup(FormGroupStructure group, {int initialCount = 1}) { - if (group.fields.isEmpty) { + void initializeFormGroup(FormGroupStructure groupStructure, {int initialCount = 1}) { + if (groupStructure.fields.isEmpty) { throw Exception('Group Fields should NOT be empty.'); } - _formGroups.add(group); + _formGroups.add(groupStructure); + // Add the controllers and values. for (int i = 0; i < initialCount; i++) { - for (MapEntry fieldEntry in group.fields.entries) { - String fieldID = '${group.id}-$i-${fieldEntry.key}'; + for (MapEntry fieldEntry in groupStructure.fields.entries) { + String fieldID = '${groupStructure.id}-$i-${fieldEntry.key}'; controller(fieldID); - if (fieldEntry.value) { - // Is a value field - } else { - // Is a text field - } + // if (fieldEntry.value) { + // // Is a value field + // } else { + // // Is a text field + // } } } } @@ -102,69 +104,93 @@ class AstromicFormController extends FormController { } */ - Map> getFormGroup(String formGroupID) { + FormGroupValue? getFormGroupValue(String formGroupID, {bool isSubGroup = false}) { // Get the group structure with the same ID - FormGroupStructure? groupWithSameID = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull; - if (groupWithSameID == null) { - throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?'); + 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 firstSetOfFieldsWithID = Map.fromEntries( - controllers.entries.where((MapEntry c) => RegExp(formGroupID + r'-#[\d+]-' + groupWithSameID.fields.entries.first.key).hasMatch(c.key)).nonNulls.toList(), + controllers.entries.where((MapEntry c) => RegExp(formGroupID + r'-#[\d+]-' + groupStructure!.fields.entries.first.key).hasMatch(c.key)).nonNulls.toList(), ); + // get the fields IDs + List fieldsIDs = groupStructure!.fields.entries.where((MapEntry e) => !e.value).nonNulls.map((MapEntry ee) => ee.key).toList(); + // get the values IDs + List valuesIDs = groupStructure.fields.entries.where((MapEntry e) => e.value).nonNulls.map((MapEntry ee) => ee.key).toList(); - for (MapEntry fieldEntry in groupWithSameID.fields.entries) { - String fieldID = '$formGroupID-${firstSetOfFieldsWithID.length}-${fieldEntry.key}'; - controller(fieldID); - if (fieldEntry.value) { - // Is a value field - } else { - // Is a text field - } + // get the subGroups + List subValues = []; + if (groupStructure.subGroups != null && groupStructure.subGroups!.isNotEmpty) { + subValues = groupStructure.subGroups!.map((FormGroupStructure s) => getFormGroupValue(s.id, isSubGroup: true)).nonNulls.toList(); } + + List instances = []; + for (int i = 0; i < firstSetOfFieldsWithID.length; i++) { + instances.add( + FormGroupInstance( + fields: Map.fromEntries(fieldsIDs.map((String id) => MapEntry('$formGroupID-#$i-$id', value('$formGroupID-#$i-$id'))).toList()), + values: Map.fromEntries(valuesIDs.map((String id) => MapEntry('$formGroupID-#$i-$id', getValue('$formGroupID-#$i-$id'))).toList()), + subGroups: subValues, + ), + ); + } + + FormGroupValue groupValue = FormGroupValue(groupID: formGroupID, instancesCount: firstSetOfFieldsWithID.length, instances: instances); + return groupValue; } - void addToFormGroup(String formGroupID) { - // Get the group structure with the same ID - FormGroupStructure? groupWithSameID = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull; - if (groupWithSameID == null) { - throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?'); - } + // void addToFormGroup(String formGroupID) { + // // Get the group structure with the same ID + // FormGroupStructure? groupWithSameID = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList().firstOrNull; + // if (groupWithSameID == 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 firstSetOfFieldsWithID = Map.fromEntries( - controllers.entries.where((MapEntry c) => RegExp(formGroupID + r'-#[\d+]-' + groupWithSameID.fields.entries.first.key).hasMatch(c.key)).nonNulls.toList(), - ); + // // Get the current fields with this ID + // Map firstSetOfFieldsWithID = Map.fromEntries( + // controllers.entries.where((MapEntry c) => RegExp(formGroupID + r'-#[\d+]-' + groupWithSameID.fields.entries.first.key).hasMatch(c.key)).nonNulls.toList(), + // ); - for (MapEntry fieldEntry in groupWithSameID.fields.entries) { - String fieldID = '$formGroupID-${firstSetOfFieldsWithID.length}-${fieldEntry.key}'; - controller(fieldID); - if (fieldEntry.value) { - // Is a value field - } else { - // Is a text field - } - } - } + // for (MapEntry fieldEntry in groupWithSameID.fields.entries) { + // String fieldID = '$formGroupID-${firstSetOfFieldsWithID.length}-${fieldEntry.key}'; + // controller(fieldID); + // if (fieldEntry.value) { + // // Is a value field + // } else { + // // Is a text field + // } + // } + // } - void removeFromFormGroup(String formGroupID, int index) { - // Get all the groups with the same ID - List groupsWithSameID = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList(); - if (groupsWithSameID.isEmpty) { - throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?'); - } - _formGroups.removeAt(groupsWithSameID.first); - for (MapEntry fieldEntry in groupsWithSameID.first.fields.entries) { - String fieldID = '$formGroupID-${groupsWithSameID.length}-${fieldEntry.key}'; - controller(fieldID); - if (fieldEntry.value) { - // Is a value field - } else { - // Is a text field - } - } - } + // void removeFromFormGroup(String formGroupID, int index) { + // // Get all the groups with the same ID + // List groupsWithSameID = _formGroups.where((FormGroupStructure f) => f.id == formGroupID).nonNulls.toList(); + // if (groupsWithSameID.isEmpty) { + // throw Exception('The group ID $formGroupID doesn\'t have any elements. Did you initialize the group?'); + // } + // _formGroups.removeAt(groupsWithSameID.first); + // for (MapEntry fieldEntry in groupsWithSameID.first.fields.entries) { + // String fieldID = '$formGroupID-${groupsWithSameID.length}-${fieldEntry.key}'; + // controller(fieldID); + // if (fieldEntry.value) { + // // Is a value field + // } else { + // // Is a text field + // } + // } + // } void getFormGroupValues(FormGroupStructure group) {} diff --git a/lib/src/form/src/models/form_group_instance.model.dart b/lib/src/form/src/models/form_group_instance.model.dart new file mode 100644 index 0000000..8ddc554 --- /dev/null +++ b/lib/src/form/src/models/form_group_instance.model.dart @@ -0,0 +1,68 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; + +import 'form_group_value.model.dart'; + +class FormGroupInstance { + Map fields; + Map values; + List? subGroups; + FormGroupInstance({ + required this.fields, + required this.values, + this.subGroups, + }); + + FormGroupInstance copyWith({ + Map? fields, + Map? values, + List? subGroups, + }) { + return FormGroupInstance( + fields: fields ?? this.fields, + values: values ?? this.values, + subGroups: subGroups ?? this.subGroups, + ); + } + + Map toMap() { + return { + 'fields': fields, + 'values': values, + 'subGroups': subGroups?.map((FormGroupValue x) => x.toMap()).toList(), + }; + } + + factory FormGroupInstance.fromMap(Map map) { + return FormGroupInstance( + fields: Map.from(map['fields'] as Map), + values: Map.from(map['values'] as Map), + subGroups: map['subGroups'] != null + ? List.from( + (map['subGroups'] as List).map( + (int x) => FormGroupValue.fromMap(x as Map), + ), + ) + : null, + ); + } + + String toJson() => json.encode(toMap()); + + factory FormGroupInstance.fromJson(String source) => FormGroupInstance.fromMap(json.decode(source) as Map); + + @override + String toString() => 'FormGroupInstance(fields: $fields, values: $values, subGroups: $subGroups)'; + + @override + bool operator ==(covariant FormGroupInstance other) { + if (identical(this, other)) return true; + + return mapEquals(other.fields, fields) && mapEquals(other.values, values) && listEquals(other.subGroups, subGroups); + } + + @override + int get hashCode => fields.hashCode ^ values.hashCode ^ subGroups.hashCode; + +} diff --git a/lib/src/form/src/models/form_group_value.model.dart b/lib/src/form/src/models/form_group_value.model.dart index b038173..82b9e78 100644 --- a/lib/src/form/src/models/form_group_value.model.dart +++ b/lib/src/form/src/models/form_group_value.model.dart @@ -1,3 +1,65 @@ -class FromGroupValue{ - final -} \ No newline at end of file +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; + +import 'form_group_instance.model.dart'; + +class FormGroupValue { + final String groupID; + final int instancesCount; + final List instances; + FormGroupValue({ + required this.groupID, + required this.instancesCount, + required this.instances, + }); + + FormGroupValue copyWith({ + String? groupID, + int? instancesCount, + List? instances, + }) { + return FormGroupValue( + groupID: groupID ?? this.groupID, + instancesCount: instancesCount ?? this.instancesCount, + instances: instances ?? this.instances, + ); + } + + Map toMap() { + return { + 'groupID': groupID, + 'instancesCount': instancesCount, + 'instances': instances.map((FormGroupInstance x) => x.toMap()).toList(), + }; + } + + factory FormGroupValue.fromMap(Map map) { + return FormGroupValue( + groupID: map['groupID'] as String, + instancesCount: map['instancesCount'] as int, + instances: List.from((map['instances'] as List).map((int x) => FormGroupInstance.fromMap(x as Map),),), + ); + } + + String toJson() => json.encode(toMap()); + + factory FormGroupValue.fromJson(String source) => FormGroupValue.fromMap(json.decode(source) as Map); + + @override + String toString() => 'FromGroupValue(groupID: $groupID, instancesCount: $instancesCount, instances: $instances)'; + + @override + bool operator ==(covariant FormGroupValue other) { + if (identical(this, other)) return true; + + return + other.groupID == groupID && + other.instancesCount == instancesCount && + listEquals(other.instances, instances); + } + + @override + int get hashCode => groupID.hashCode ^ instancesCount.hashCode ^ instances.hashCode; +}