Skip to content
Snippets Groups Projects

Fix/dynamic form

Merged Manish Kumar requested to merge fix/dynamicForm into master
1 file
+ 60
56
Compare changes
  • Side-by-side
  • Inline
+ 60
56
@@ -92,7 +92,7 @@ class DynamicFormState extends State<DynamicForm> {
TextEditingController dateController;
TextEditingController timeController;
// La boucle Future.forEach assure que tout soit exécuté avant de passer au prochain tour de boucle
// Itération sur les champs
widget.fields.forEach(
(field) {
if (field[1] == DateTime) {
@@ -102,7 +102,8 @@ class DynamicFormState extends State<DynamicForm> {
// S'il y a une valeur par défaut et qu'on souhaite qu'elle soit affichée
if (field.length > 4 && field[4]) {
dateController.text = dateFormater(field[3]);
// On est obligé d'attendre que la variable context soit accessible
// On utilise le contexte du parent qui facilite l'appel,
// sinon il faudrait faire un appel asynchrone qui ne smblait pas fonctionner dans les tests
timeController.text =
TimeOfDay.fromDateTime(field[3]).format(widget.context);
}
@@ -143,8 +144,7 @@ class DynamicFormState extends State<DynamicForm> {
// Variable possédant tous les éléments du formulaire à afficher
final processedFields = <Widget>[];
var placeholder;
final node = FocusScope.of(context);
var editingMode;
var textInputAction;
// Construction et ajout des champs selon les paramètres entrés
for (int i = 0; i < controllers.entries.length; i++) {
@@ -159,19 +159,19 @@ class DynamicFormState extends State<DynamicForm> {
// Champ de type String
if (field.value['type'] == String) {
// Assignation de editingMode qui détermine si l'utilisateur peut accéder au champ suivant
// directement depuis le clavier. C'est désactivé (unfocus) si c'est le dernier champ ou si
// Assignation de textInputAction qui détermine si l'utilisateur peut accéder au champ suivant
// directement depuis le clavier. C'est désactivé (done) si c'est le dernier champ ou si
// le prochain champ est de type DateTime et requiert que l'utilisateur tape sur le champ pour faire
// apparaître le calendrier ou l'horloge
if (i == controllers.entries.length - 1 ||
controllers.entries.elementAt(i + 1).value['type'] == DateTime)
editingMode = () => node.unfocus();
textInputAction = TextInputAction.done;
else
editingMode = () => node.nextFocus();
textInputAction = TextInputAction.next;
processedFields.add(
_buildStringField(placeholder, field.value['required'], context,
controllers[field.key]['fieldController'], editingMode),
controllers[field.key]['fieldController'], textInputAction),
);
// Champ de type DateTime
} else if (field.value['type'] == DateTime) {
@@ -249,51 +249,7 @@ class DynamicFormState extends State<DynamicForm> {
body: widget.buttonText,
fontSize: 30.0,
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
onPressed: () {
// Test de validité du formulaire
if (_formKey.currentState.validate()) {
// Dictionnaire en retour avec les bons types
var resMap = Map();
controllers.entries.forEach(
(controller) {
if (controller.value['type'] == String) {
controller.value.containsKey('value') &&
controller.value['fieldController'].text.length == 0
? resMap[controller.key] = controller.value['value']
: resMap[controller.key] =
controller.value['fieldController'].text;
} else if (controller.value['type'] == DateTime) {
// Combinaison des champs date et heure si la date n'est pas null
var selectedDate = controller.value['dateValue'];
var selectedTime = controller.value['timeValue'];
// Test de tout type d'entrée possible, qui peuvent arriver si le champ est optionnel
if (selectedDate == null) {
resMap[controller.key] = null;
} else if (selectedDate != null && selectedTime == null) {
resMap[controller.key] = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
);
} else {
resMap[controller.key] = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
}
}
},
);
widget.onSubmit(resMap);
} else {
setState(() {
validForm = false;
});
}
},
onPressed: validateForm,
),
),
);
@@ -301,6 +257,54 @@ class DynamicFormState extends State<DynamicForm> {
return processedFields;
}
/// Méthode validant le formulaire
void validateForm() {
// Test de validité du formulaire
if (_formKey.currentState.validate()) {
// Dictionnaire en retour avec les bons types
var resMap = Map();
controllers.entries.forEach(
(controller) {
if (controller.value['type'] == String) {
controller.value.containsKey('value') &&
controller.value['fieldController'].text.length == 0
? resMap[controller.key] = controller.value['value']
: resMap[controller.key] =
controller.value['fieldController'].text;
} else if (controller.value['type'] == DateTime) {
// Combinaison des champs date et heure si la date n'est pas null
var selectedDate = controller.value['dateValue'];
var selectedTime = controller.value['timeValue'];
// Test de tout type d'entrée possible, qui peuvent arriver si le champ est optionnel
if (selectedDate == null) {
resMap[controller.key] = null;
} else if (selectedDate != null && selectedTime == null) {
resMap[controller.key] = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
);
} else {
resMap[controller.key] = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
}
}
},
);
// Appel de la fonction passée en paramètre au widget
widget.onSubmit(resMap);
} else {
setState(() {
validForm = false;
});
}
}
@override
Widget build(BuildContext context) {
// Construction du formulaire avec la clé créée
@@ -353,7 +357,7 @@ Widget _buildStringField(
bool requiredField,
BuildContext context,
TextEditingController controller,
Function onEditingComplete,
TextInputAction textInputAction,
) {
return Container(
margin: EdgeInsets.only(top: 20),
@@ -362,7 +366,7 @@ Widget _buildStringField(
validator: customValidator(requiredField),
decoration: _buildInputDecoration(name, context),
controller: controller,
onEditingComplete: onEditingComplete,
textInputAction: textInputAction,
style: TextStyle(color: Theme.of(context).primaryColor),
),
);
Loading