diff --git a/lib/src/form/src/controller.dart b/lib/src/form/src/controller.dart index b66dda8..b628616 100644 --- a/lib/src/form/src/controller.dart +++ b/lib/src/form/src/controller.dart @@ -205,23 +205,31 @@ class AstromicFormController extends FormController { return null; } - int getInstanceCount(String targetGroupID) { + /// Get the count of instances of this group. + int getInstanceCount(String targetGroupID, {Map? parents}) { + // Get the group structure FormGroupStructure? structure = getGroupStructure(targetGroupID); + if (structure != null) { - String firstField = structure.fields.first; - String? p = getFullPathOfGroup(targetGroupID); - late RegExp pattern; - if (p != null && p.split('->').length > 1 && p.split('->').indexOf(targetGroupID) != 0) { - // This is a subgroup - pattern = RegExp(r'^' + - p.split('->').sublist(0, p.split('->').indexOf(targetGroupID)).map((String a) => standeredGroupFormat(a, '0', '')).toList().join() + - standeredGroupFormat(targetGroupID, r'[\d+]', firstField) + - r'$'); - } else { - pattern = RegExp(r'^' + standeredGroupFormat(targetGroupID, r'[\d+]', firstField) + r'$'); + // Get the prefix of the parents + String? prefix; + if (isASubGroup(targetGroupID) && parents != null) { + prefix = parents.entries.map((MapEntry parentEntry) => standeredGroupFormat(parentEntry.key, parentEntry.value.toString(), null)).join('-'); } + + // Get and process the regex pattern. + late RegExp pattern; + if (prefix != null) { + // This is a subgroup + pattern = RegExp(r'^' + ('$prefix-') + standeredGroupFormat(targetGroupID, r'[\d+]', structure.fields.first) + r'$'); + } else { + pattern = RegExp(r'^' + standeredGroupFormat(targetGroupID, r'[\d+]', structure.fields.first) + r'$'); + } + + // Return keys that match the pattern. return controllers.keys.where((String c) => pattern.hasMatch(c)).nonNulls.toList().length; } + return 0; } @@ -287,14 +295,19 @@ class AstromicFormController extends FormController { } /// Get the target formGroup Value. - FormGroupValue? getFormGroupValue(String formGroupID, {String? prefix}) { - assert(prefix != null || _formGroups.map((FormGroupStructure f) => f.id).contains(formGroupID), 'This method is not valid for sub-groups.'); - + FormGroupValue? getFormGroupValue(String formGroupID, {Map? parents}) { // Get the group structure with the ID FormGroupStructure? groupStructure = getGroupStructure(formGroupID); + assert(groupStructure != null, 'The Group $formGroupID doesn\'t seem to be found, are you sure you initialized it?'); + + // Get the prefix for subgroups if exists + String? prefix; + if (isASubGroup(formGroupID) && parents != null) { + prefix = parents.entries.map((MapEntry parentEntry) => standeredGroupFormat(parentEntry.key, parentEntry.value.toString(), null)).join('-'); + } // Get the current fields with this ID - int instancesCount = getInstanceCount(formGroupID); + int instancesCount = getInstanceCount(formGroupID, parents: parents); // get the fields IDs List fieldsIDs = groupStructure!.fields.nonNulls.toList(); @@ -308,7 +321,15 @@ class AstromicFormController extends FormController { List subValues = []; if (groupStructure.subGroups != null && groupStructure.subGroups!.isNotEmpty) { subValues = groupStructure.subGroups! - .map(((int, FormGroupStructure) s) => getFormGroupValue(s.$2.id, prefix: (prefix != null ? '$prefix-' : '') + standeredGroupFormat(formGroupID, i.toString(), null))) + .map( + ((int, FormGroupStructure) s) => getFormGroupValue( + s.$2.id, + parents: { + if (parents != null) ...parents, + formGroupID: i, + }, + ), + ) .nonNulls .toList(); } @@ -328,17 +349,18 @@ class AstromicFormController extends FormController { ), ); } - FormGroupValue groupValue = FormGroupValue(groupID: formGroupID, instancesCount: instancesCount, instances: instances); return groupValue; } + /// Is this group a SubGroup? bool isASubGroup(String formGroupID) { List? fullPath = getFullPathOfGroup(formGroupID)?.split('->'); return fullPath != null && fullPath.length > 1 && fullPath.indexOf(formGroupID) != 0; } - String addInstanceToFormGroup(String formGroupID, {Map? parents}) { + /// Add an instance to the group. + String addInstanceToFormGroupT(String formGroupID, {Map? parents}) { // Get the group structure with the same ID FormGroupStructure? structure = getGroupStructure(formGroupID); assert(structure != null, 'The Group $formGroupID doesn\'t seem to be found, are you sure you initialized it?'); @@ -350,87 +372,122 @@ class AstromicFormController extends FormController { } // Get current instances of this group and the new index. - int currentGroupInstances = getInstanceCount(formGroupID); + int currentGroupInstances = getInstanceCount(formGroupID, parents: parents); int newGroupIndex = currentGroupInstances; // Add the controllers and values. for (String fieldID in structure!.fields.nonNulls) { String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(formGroupID, newGroupIndex.toString(), fieldID); - controller(p); + controller(p.trim(), initialText: ''); } if (structure.values != null && structure.values!.isNotEmpty) { for (String valueID in structure.values!.nonNulls) { String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(formGroupID, newGroupIndex.toString(), valueID); - controller(p); + controller(p.trim()); } } String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(formGroupID, newGroupIndex.toString(), ''); - return p; + return p.trim(); } - // void 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?'); - // } - // } + /// Remove an instance from the group + void removeInstanceFromGroupT(String formGroupID, int indexToRemove, {Map? parents, bool removeAll = false}) { + // Get the group structure with the same ID + FormGroupStructure? structure = getGroupStructure(formGroupID); + assert(structure != null, 'The Group $formGroupID doesn\'t seem to be found, are you sure you initialized it?'); - // // Get the current fields with this ID - // Map firstSetOfFieldsWithID = Map.fromEntries( - // controllers.entries.where((MapEntry c) => RegExp(formGroupID + r'-#[\d+]-' + groupStructure!.fields.first).hasMatch(c.key)).nonNulls.toList(), - // ); + // Get the prefix for subgroups if exists + String? prefix; + if (isASubGroup(formGroupID) && parents != null) { + prefix = parents.entries.map((MapEntry parentEntry) => standeredGroupFormat(parentEntry.key, parentEntry.value.toString(), null)).join('-'); + } - // if (indexToRemove >= firstSetOfFieldsWithID.length) { - // throw Exception('The index to remove is larger than the whole instances count.'); - // } else { - // // get the fields IDs - // List fieldsIDs = groupStructure!.fields.nonNulls.toList(); - // print('fieldIDs: $fieldsIDs'); - // // get the values IDs - // List valuesIDs = groupStructure.values?.nonNulls.toList() ?? []; - // print('valueIDs: $valuesIDs'); + // handle subgroups + if (structure!.subGroups != null && structure.subGroups!.isNotEmpty) { + for (final (int, FormGroupStructure) subGroup in structure.subGroups!) { + // Recursively remove any nested subgroups inside this subgroup + final nestedParents = { + if (parents != null) ...parents, + structure.id: indexToRemove, + }; - // if (indexToRemove == (firstSetOfFieldsWithID.length - 1)) { - // // Remove the last item - // for (String fieldID in groupStructure.fields) { - // removeController('${groupStructure.id}-#$indexToRemove-$fieldID'); - // } - // if (groupStructure.values != null && groupStructure.values!.isNotEmpty) { - // for (String valueID in groupStructure.values!) { - // removeController('${groupStructure.id}-#$indexToRemove-$valueID'); - // _hostedValues.remove('${groupStructure.id}-#$indexToRemove-$valueID'); - // } - // } - // } else { - // // Switch and remove - // int nextIndex = indexToRemove + 1; - // for (String fieldID in groupStructure.fields) { - // set('${groupStructure.id}-#$indexToRemove-$fieldID', value('${groupStructure.id}-#$nextIndex-$fieldID')); - // removeController('${groupStructure.id}-#$nextIndex-$fieldID'); - // } - // if (groupStructure.values != null && groupStructure.values!.isNotEmpty) { - // for (String valueID in groupStructure.values!) { - // _hostedValues.remove('${groupStructure.id}-#$indexToRemove-$valueID'); - // set('${groupStructure.id}-#$indexToRemove-$valueID', value('${groupStructure.id}-#$nextIndex-$valueID')); - // setValue('${groupStructure.id}-#$indexToRemove-$valueID', getValue('${groupStructure.id}-#$nextIndex-$valueID')); - // removeController('${groupStructure.id}-#$nextIndex-$valueID'); - // _hostedValues.remove('${groupStructure.id}-#$nextIndex-$valueID'); - // } - // } - // } - // // Remove last instance - // } - // } + int subGroupInstancesCount = getInstanceCount( + subGroup.$2.id, + parents: nestedParents, + ); + + for (int ii = 0; ii < subGroupInstancesCount; ii++) { + removeInstanceFromGroupT( + subGroup.$2.id, + ii, + parents: nestedParents, + removeAll: true, + ); + } + //-- + // } + } + } + // Get current instances of this group. + int currentGroupInstances = getInstanceCount(formGroupID, parents: parents); + if (removeAll) { + for (var ina = 0; ina < currentGroupInstances; ina++) { + // Remove the last item + for (String fieldID in structure.fields) { + String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, ina.toString(), fieldID); + removeController(p); + } + if (structure.values != null && structure.values!.isNotEmpty) { + for (String valueID in structure.values!) { + String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, ina.toString(), valueID); + removeValue(p); + removeController(p); + } + } + } + } else { + // The actual controllers removal + if (indexToRemove >= currentGroupInstances) { + // return; + throw Exception('The index to remove is larger than the whole instances count. ($indexToRemove , $currentGroupInstances)'); + } else { + if (indexToRemove == (currentGroupInstances - 1)) { + // Remove the last item + for (String fieldID in structure.fields) { + String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, indexToRemove.toString(), fieldID); + removeController(p); + } + if (structure.values != null && structure.values!.isNotEmpty) { + for (String valueID in structure.values!) { + String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, indexToRemove.toString(), valueID); + removeValue(p); + removeController(p); + } + } + } else { + // Switch and remove + int nextIndex = indexToRemove + 1; + for (String fieldID in structure!.fields) { + String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, indexToRemove.toString(), fieldID); + String p2 = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, nextIndex.toString(), fieldID); + set(p, value(p2)); + removeController(p2); + } + if (structure.values != null && structure.values!.isNotEmpty) { + for (String valueID in structure.values!) { + String p = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, indexToRemove.toString(), valueID); + String p2 = (prefix != null ? '$prefix-' : '') + standeredGroupFormat(structure.id, nextIndex.toString(), valueID); + removeValue(p); + set(p, value(p2)); + setValue(p, getValue(p2)); + removeController(p2); + removeValue(p2); + } + } + } + } + } + } //!SECTION //SECTION - Helper Methods diff --git a/lib/src/form/src/form_group_wrapper.dart b/lib/src/form/src/form_group_wrapper.dart index 54f74ee..756cefb 100644 --- a/lib/src/form/src/form_group_wrapper.dart +++ b/lib/src/form/src/form_group_wrapper.dart @@ -103,8 +103,8 @@ class _FormGroupWrapperState extends State { () { String id = ''; setState(() { - id = widget.formController.addInstanceToFormGroup(widget.groupID); - instances = widget.formController.getFormGroupValue(widget.groupID)!.instances; + // id = widget.formController.addInstanceToFormGroup(widget.groupID); + // instances = widget.formController.getFormGroupValue(widget.groupID)!.instances; }); return id; },