[SYNC] Doing the initial Values thing.
This commit is contained in:
@@ -15,20 +15,43 @@ 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';
|
||||
import 'models/initial_form_group_values.model.dart';
|
||||
import 'models/initial_values.model.dart';
|
||||
//s1 Exports
|
||||
|
||||
part './helpers/controller_states.helper.dart';
|
||||
|
||||
/// A specialized form controller to handle form states,
|
||||
class AstromicFormController extends FormController {
|
||||
AstromicFormController({
|
||||
Map<String, (String initialText, bool initialObscurity)>? initialValues,
|
||||
Map<String, (dynamic, bool)>? initialHostedValues,
|
||||
AstromicFormInitialValues? initialValues,
|
||||
this.errorStream,
|
||||
}) : super(initialValues) {
|
||||
// Add states and messages based on initial controllers.
|
||||
_addInitialControllers(initialValues);
|
||||
_addInitialHostedValues(initialHostedValues);
|
||||
}) : super(null) {
|
||||
if (initialValues != null) {
|
||||
// Take in the initials and proceed to fill:
|
||||
//1. Field Values
|
||||
if (initialValues.fieldValues != null && initialValues.fieldValues!.isNotEmpty) {
|
||||
for (MapEntry<String, String?> fieldValueEntry in initialValues.fieldValues!.entries) {
|
||||
String k = fieldValueEntry.key;
|
||||
String v = fieldValueEntry.value ?? '';
|
||||
bool isObs = initialValues.fieldObscurityValues != null && initialValues.fieldObscurityValues!.containsKey(k) && initialValues.fieldObscurityValues![k]!;
|
||||
//
|
||||
controller(k, initialText: v, isObscure: isObs);
|
||||
}
|
||||
}
|
||||
//2. Hosted Values
|
||||
if (initialValues.hostedValues != null && initialValues.hostedValues!.isNotEmpty) {
|
||||
for (MapEntry<String, (dynamic, bool)> hostedValueEntry in initialValues.hostedValues!.entries) {
|
||||
String k = hostedValueEntry.key;
|
||||
dynamic v = hostedValueEntry.value.$1;
|
||||
dynamic isReq = hostedValueEntry.value.$2;
|
||||
//
|
||||
setValue(k, v, isRequired: isReq);
|
||||
}
|
||||
}
|
||||
//3. Form Group Values
|
||||
if (initialValues.groupValues != null && initialValues.groupValues!.isNotEmpty) {
|
||||
_initializeFormGroups(initialValues.groupValues!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//SECTION - Overrides
|
||||
@@ -74,12 +97,26 @@ class AstromicFormController extends FormController {
|
||||
final Stream<List<(String internalCode, String? message)>>? errorStream;
|
||||
//S1 - Methods
|
||||
|
||||
/// Get the field state and message of a specific field using it's ID.
|
||||
(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 Exception('The state of the field ID $fieldId does not exist.');
|
||||
}
|
||||
fieldStates[fieldId] = state;
|
||||
fieldMessages[fieldId] = message;
|
||||
_stateStreamController.add((fieldId, state));
|
||||
}
|
||||
|
||||
/// Reset the state of a specific field using it's ID.
|
||||
void resetState(String fieldId) => setState(fieldId, AstromicFieldState.idle);
|
||||
//!SECTION
|
||||
|
||||
//SECTION - Hosted Values
|
||||
//S1 - State Variables
|
||||
final Map<String, (dynamic, bool)> _hostedValues = <String, (dynamic, bool)>{};
|
||||
final Map<String, (dynamic value, bool isRequired)> _hostedValues = <String, (dynamic, bool)>{};
|
||||
|
||||
//S1 - Streams
|
||||
static final StreamController<(String, bool)> _hostedValueValidationStreamController = StreamController<(String id, bool)>.broadcast();
|
||||
@@ -140,6 +177,7 @@ class AstromicFormController extends FormController {
|
||||
//S1 - State Variables
|
||||
final List<FormGroupStructure> _formGroups = <FormGroupStructure>[];
|
||||
//S1 - Methods
|
||||
|
||||
/// Does the controller has a field group with this ID.
|
||||
bool hasFieldGroup(String formGroupID) => getGroupStructure(formGroupID) != null;
|
||||
|
||||
@@ -245,21 +283,12 @@ class AstromicFormController extends FormController {
|
||||
|
||||
for (final String fieldID in structure.fields) {
|
||||
final String fullID = standeredGroupFormat(baseID, index.toString(), fieldID);
|
||||
String? preFilled;
|
||||
if (structure.preFields?.containsKey(fieldID) ?? false) {
|
||||
preFilled = structure.preFields![fieldID];
|
||||
}
|
||||
controller(fullID, initialText: preFilled);
|
||||
controller(fullID);
|
||||
}
|
||||
|
||||
for (final String valueID in structure.values ?? <String>[]) {
|
||||
final String fullID = standeredGroupFormat(baseID, index.toString(), valueID);
|
||||
(String, dynamic)? preFilled;
|
||||
if (structure.preValues?.containsKey(valueID) ?? false) {
|
||||
preFilled = structure.preValues![valueID];
|
||||
}
|
||||
controller(fullID, initialText: preFilled?.$1);
|
||||
setValue(valueID, preFilled?.$2);
|
||||
controller(fullID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,26 +562,71 @@ class AstromicFormController extends FormController {
|
||||
//SECTION - Helper Methods
|
||||
String standeredGroupFormat(String groupID, String groupIndex, String? secondaryID) => '$groupID-#$groupIndex${secondaryID == null ? "" : "-$secondaryID"}';
|
||||
|
||||
void _addInitialControllers(Map<String, (String, bool)>? initialValues) {
|
||||
if (initialValues != null) {
|
||||
// Add in the initial field states...
|
||||
fieldStates.addEntries(initialValues.entries.map((MapEntry<String, (String, bool)> e) => MapEntry<String, AstromicFieldState>(
|
||||
e.key, // controller ID
|
||||
AstromicFieldState.idle, // Initial state of any new controller is Idle
|
||||
)));
|
||||
// void _addInitialControllers(Map<String, (String, bool)>? initialValues) {
|
||||
// if (initialValues != null) {
|
||||
// // Add in the initial field states...
|
||||
// fieldStates.addEntries(initialValues.entries.map((MapEntry<String, (String, bool)> e) => MapEntry<String, AstromicFieldState>(
|
||||
// e.key, // controller ID
|
||||
// AstromicFieldState.idle, // Initial state of any new controller is Idle
|
||||
// )));
|
||||
|
||||
// Add in the initial field messages...
|
||||
fieldMessages.addEntries(initialValues.entries.toList().map((MapEntry<String, (String, bool)> e) => MapEntry<String, String?>(
|
||||
e.key, // Controller ID
|
||||
null, // The initial message it has which is Null
|
||||
)));
|
||||
// // Add in the initial field messages...
|
||||
// fieldMessages.addEntries(initialValues.entries.toList().map((MapEntry<String, (String, bool)> e) => MapEntry<String, String?>(
|
||||
// e.key, // Controller ID
|
||||
// null, // The initial message it has which is Null
|
||||
// )));
|
||||
// }
|
||||
// }
|
||||
|
||||
// void _addInitialHostedValues(Map<String, (dynamic, bool)>? initialValues) {
|
||||
// if (initialValues != null) {
|
||||
// for (MapEntry<String, (dynamic, bool)> vEntry in initialValues.entries) {
|
||||
// setValue(vEntry.key, vEntry.value.$1, isRequired: vEntry.value.$2);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
_initializeFormGroups(Map<String, InitialFormGroupValue> initVals, {Map<String, int>? parents}) {
|
||||
for (MapEntry<String, InitialFormGroupValue> groupValueEntry in initVals.entries) {
|
||||
String groupID = groupValueEntry.key;
|
||||
InitialFormGroupValue groupValue = groupValueEntry.value;
|
||||
|
||||
for (int i = 0; i < groupValue.instancesCount; i++) {
|
||||
int currentGroupIndex = i;
|
||||
// Check for the subgroups
|
||||
if (groupValueEntry.value.subGroups != null && groupValueEntry.value.subGroups!.isNotEmpty) {
|
||||
// There are subgroups.
|
||||
_initializeFormGroups(groupValueEntry.value.subGroups!, parents: <String, int>{...?parents, groupID: currentGroupIndex});
|
||||
}
|
||||
|
||||
String? prefix = parents?.entries.map((MapEntry<String, int> parentEntry) => standeredGroupFormat(parentEntry.key, parentEntry.value.toString(), null)).join('-');
|
||||
|
||||
// Fields
|
||||
if (groupValue.fieldValues != null) {
|
||||
for (MapEntry<String, List<String?>> fve in groupValue.fieldValues!.entries) {
|
||||
assert(fve.value.length == groupValue.instancesCount, 'Your supplied list of `${fve.key}` is not `${groupValue.instancesCount}` as stated..');
|
||||
if (groupValue.fieldObscurityValues != null) {
|
||||
assert(groupValue.fieldObscurityValues!.length == groupValue.instancesCount, 'Your supplied obscurity list of `${fve.key}` is not `${groupValue.instancesCount}` as stated..');
|
||||
}
|
||||
String fieldKey = fve.key;
|
||||
String fID = standeredGroupFormat((prefix != null ? '$prefix-' : '') + groupID, i.toString(), fieldKey);
|
||||
String? fieldValue = fve.value[i] ?? '';
|
||||
bool obscValue = groupValue.fieldObscurityValues?[fieldKey]?[i] ?? false;
|
||||
controller(fID, initialText: fieldValue, isObscure: obscValue);
|
||||
}
|
||||
}
|
||||
|
||||
void _addInitialHostedValues(Map<String, (dynamic, bool)>? initialValues) {
|
||||
if (initialValues != null) {
|
||||
for (MapEntry<String, (dynamic, bool)> vEntry in initialValues.entries) {
|
||||
setValue(vEntry.key, vEntry.value.$1, isRequired: vEntry.value.$2);
|
||||
// Values
|
||||
if (groupValue.hostedValues != null) {
|
||||
for (MapEntry<String, List<(dynamic, bool)>> hve in groupValue.hostedValues!.entries) {
|
||||
assert(hve.value.length == groupValue.instancesCount, 'Your supplied list of `${hve.key}` is not `${groupValue.instancesCount}` as stated..');
|
||||
String fieldKey = hve.key;
|
||||
String fID = standeredGroupFormat((prefix != null ? '$prefix-' : '') + groupID, i.toString(), fieldKey);
|
||||
dynamic fieldValue = hve.value[i].$1;
|
||||
bool isReq = hve.value[i].$2;
|
||||
|
||||
setValue(fID, fieldValue, isRequired: isReq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
part of '../controller.dart';
|
||||
/// Get the field state and message of a specific field using it's ID.
|
||||
(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 Exception('The state of the field ID $fieldId does not exist.');
|
||||
}
|
||||
fieldStates[fieldId] = state;
|
||||
fieldMessages[fieldId] = message;
|
||||
_stateStreamController.add((fieldId, state));
|
||||
}
|
||||
|
||||
/// Reset the state of a specific field using it's ID.
|
||||
void resetState(String fieldId) => setState(fieldId, AstromicFieldState.idle);
|
||||
@@ -5,16 +5,12 @@ import 'package:flutter/foundation.dart';
|
||||
class FormGroupStructure {
|
||||
final String id;
|
||||
final List<String> fields;
|
||||
final Map<String, String>? preFields;
|
||||
final List<String>? values;
|
||||
final Map<String, (String, dynamic)>? preValues;
|
||||
final List<(int initialCount, FormGroupStructure structure)>? subGroups;
|
||||
FormGroupStructure({
|
||||
required this.id,
|
||||
required this.fields,
|
||||
this.values,
|
||||
this.preFields,
|
||||
this.preValues,
|
||||
this.subGroups,
|
||||
});
|
||||
|
||||
@@ -30,8 +26,6 @@ class FormGroupStructure {
|
||||
id: id ?? this.id,
|
||||
fields: fields ?? this.fields,
|
||||
values: values ?? this.values,
|
||||
preFields: preFields ?? this.preFields,
|
||||
preValues: preValues ?? this.preValues,
|
||||
subGroups: subGroups ?? this.subGroups,
|
||||
);
|
||||
}
|
||||
@@ -41,8 +35,6 @@ class FormGroupStructure {
|
||||
'id': id,
|
||||
'fields': fields,
|
||||
'values': values,
|
||||
'preFields': preFields,
|
||||
'preValues': preValues,
|
||||
'subGroups': subGroups?.map(((int initialCount, FormGroupStructure structure) x) => <String, dynamic>{'structure': x.$2.toMap(), 'initialCount': x.$1}).toList(),
|
||||
};
|
||||
}
|
||||
@@ -52,8 +44,6 @@ class FormGroupStructure {
|
||||
id: map['id'] as String,
|
||||
fields: List<String>.from(map['fields'] as List<String>),
|
||||
values: map['values'] != null ? List<String>.from(map['values'] as List<String>) : null,
|
||||
preFields: map['preFields'] != null ? map['preFields'] as Map<String,String> : null,
|
||||
preValues: map['preValues'] != null ? map['preValues'] as Map<String,(String,dynamic)>: null,
|
||||
subGroups: map['subGroups'] != null
|
||||
? (map['subGroups'] as List<Map<String, dynamic>>).map((Map<String, dynamic> map) => (int.tryParse(map['initialCount']) ?? 0, FormGroupStructure.fromMap(map['structure']))).toList()
|
||||
: null,
|
||||
@@ -66,23 +56,18 @@ class FormGroupStructure {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'FormGroupStructure(id: $id, fields: $fields, values: $values, preFields: $preFields, preValues: $preValues, subGroups: $subGroups)';
|
||||
return 'FormGroupStructure(id: $id, fields: $fields, values: $values, subGroups: $subGroups)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant FormGroupStructure other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.id == id &&
|
||||
listEquals(other.fields, fields) &&
|
||||
listEquals(other.values, values) &&
|
||||
mapEquals(other.preFields, preFields) &&
|
||||
mapEquals(other.preValues, preValues) &&
|
||||
listEquals(other.subGroups, subGroups);
|
||||
return other.id == id && listEquals(other.fields, fields) && listEquals(other.values, values) && listEquals(other.subGroups, subGroups);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^ fields.hashCode ^ values.hashCode ^ preFields.hashCode ^ preValues.hashCode ^ subGroups.hashCode;
|
||||
return id.hashCode ^ fields.hashCode ^ values.hashCode ^ subGroups.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
80
lib/src/form/src/models/initial_form_group_values.model.dart
Normal file
80
lib/src/form/src/models/initial_form_group_values.model.dart
Normal file
@@ -0,0 +1,80 @@
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class InitialFormGroupValue {
|
||||
final int instancesCount;
|
||||
final Map<String, List<String?>>? fieldValues;
|
||||
final Map<String, List<bool>>? fieldObscurityValues;
|
||||
final Map<String, List<(dynamic, bool)>>? hostedValues;
|
||||
final Map<String, InitialFormGroupValue>? subGroups;
|
||||
InitialFormGroupValue({
|
||||
required this.instancesCount,
|
||||
this.fieldValues,
|
||||
this.fieldObscurityValues,
|
||||
this.hostedValues,
|
||||
this.subGroups,
|
||||
});
|
||||
|
||||
InitialFormGroupValue copyWith({
|
||||
int? instancesCount,
|
||||
Map<String, List<String?>>? fieldValues,
|
||||
Map<String, List<bool>>? fieldObscurityValues,
|
||||
Map<String, List<(dynamic, bool)>>? hostedValues,
|
||||
Map<String, InitialFormGroupValue>? subGroups,
|
||||
}) {
|
||||
return InitialFormGroupValue(
|
||||
instancesCount: instancesCount ?? this.instancesCount,
|
||||
fieldValues: fieldValues ?? this.fieldValues,
|
||||
fieldObscurityValues: fieldObscurityValues ?? this.fieldObscurityValues,
|
||||
hostedValues: hostedValues ?? this.hostedValues,
|
||||
subGroups: subGroups ?? this.subGroups,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'instancesCount': instancesCount,
|
||||
'fieldValues': fieldValues,
|
||||
'fieldObscurityValues': fieldObscurityValues,
|
||||
'hostedValues': hostedValues,
|
||||
'subGroups': subGroups,
|
||||
};
|
||||
}
|
||||
|
||||
factory InitialFormGroupValue.fromMap(Map<String, dynamic> map) {
|
||||
return InitialFormGroupValue(
|
||||
instancesCount: map['instancesCount'] as int,
|
||||
fieldValues: map['fieldValues'] != null ? Map<String, List<String?>>.from(map['fieldValues'] as Map<String, List<String?>>) : null,
|
||||
fieldObscurityValues: map['fieldObscurityValues'] != null ? Map<String, List<bool>>.from(map['fieldObscurityValues'] as Map<String, List<bool>>) : null,
|
||||
hostedValues: map['hostedValues'] != null ? Map<String, List<(dynamic, bool)>>.from(map['hostedValues'] as Map<String, List<(dynamic, bool)>>) : null,
|
||||
subGroups: map['subGroups'] != null ? Map<String, InitialFormGroupValue>.from(map['subGroups'] as Map<String, InitialFormGroupValue>) : null,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory InitialFormGroupValue.fromJson(String source) => InitialFormGroupValue.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InitialFormGroupValue(instancesCount: $instancesCount, fieldValues: $fieldValues, fieldObscurityValues: $fieldObscurityValues, hostedValues: $hostedValues, subGroups: $subGroups)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant InitialFormGroupValue other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.instancesCount == instancesCount &&
|
||||
mapEquals(other.fieldValues, fieldValues) &&
|
||||
mapEquals(other.fieldObscurityValues, fieldObscurityValues) &&
|
||||
mapEquals(other.hostedValues, hostedValues) &&
|
||||
mapEquals(other.subGroups, subGroups);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return instancesCount.hashCode ^ fieldValues.hashCode ^ fieldObscurityValues.hashCode ^ hostedValues.hashCode ^ subGroups.hashCode;
|
||||
}
|
||||
}
|
||||
78
lib/src/form/src/models/initial_values.model.dart
Normal file
78
lib/src/form/src/models/initial_values.model.dart
Normal file
@@ -0,0 +1,78 @@
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'initial_form_group_values.model.dart';
|
||||
|
||||
class AstromicFormInitialValues {
|
||||
// Field Values
|
||||
final Map<String, String?>? fieldValues;
|
||||
final Map<String, bool>? fieldObscurityValues;
|
||||
// Hosted Values
|
||||
final Map<String, (dynamic, bool)>? hostedValues;
|
||||
// Form Groups
|
||||
final Map<String, InitialFormGroupValue>? groupValues;
|
||||
AstromicFormInitialValues({
|
||||
this.fieldValues,
|
||||
this.fieldObscurityValues,
|
||||
this.hostedValues,
|
||||
this.groupValues,
|
||||
});
|
||||
|
||||
AstromicFormInitialValues copyWith({
|
||||
Map<String, String?>? fieldValues,
|
||||
Map<String, bool>? fieldObscurityValues,
|
||||
Map<String, (dynamic, bool)>? hostedValues,
|
||||
Map<String, InitialFormGroupValue>? groupValues,
|
||||
}) {
|
||||
return AstromicFormInitialValues(
|
||||
fieldValues: fieldValues ?? this.fieldValues,
|
||||
fieldObscurityValues: fieldObscurityValues ?? this.fieldObscurityValues,
|
||||
hostedValues: hostedValues ?? this.hostedValues,
|
||||
groupValues: groupValues ?? this.groupValues,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'fieldValues': fieldValues,
|
||||
'fieldObscurityValues': fieldObscurityValues,
|
||||
'hostedValues': hostedValues,
|
||||
'groupValues': groupValues,
|
||||
};
|
||||
}
|
||||
|
||||
factory AstromicFormInitialValues.fromMap(Map<String, dynamic> map) {
|
||||
return AstromicFormInitialValues(
|
||||
fieldValues: map['fieldValues'] != null ? Map<String, String?>.from(map['fieldValues'] as Map<String, String?>) : null,
|
||||
fieldObscurityValues: map['fieldObscurityValues'] != null ? Map<String, bool>.from(map['fieldObscurityValues'] as Map<String, bool>) : null,
|
||||
hostedValues: map['hostedValues'] != null ? Map<String, (dynamic, bool)>.from(map['hostedValues'] as Map<String, dynamic>) : null,
|
||||
groupValues: map['groupValues'] != null ? Map<String, InitialFormGroupValue>.from(map['groupValues'] as Map<String, InitialFormGroupValue>) : null,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory AstromicFormInitialValues.fromJson(String source) => AstromicFormInitialValues.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AstromicFormInitialValues(fieldValues: $fieldValues, fieldObscurityValues: $fieldObscurityValues, hostedValues: $hostedValues, groupValues: $groupValues)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant AstromicFormInitialValues other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return mapEquals(other.fieldValues, fieldValues) &&
|
||||
mapEquals(other.fieldObscurityValues, fieldObscurityValues) &&
|
||||
mapEquals(other.hostedValues, hostedValues) &&
|
||||
mapEquals(other.groupValues, groupValues);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return fieldValues.hashCode ^ fieldObscurityValues.hashCode ^ hostedValues.hashCode ^ groupValues.hashCode;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user