Skip to content

Commit

Permalink
Merge pull request #1254 from flutter-form-builder-ecosystem/fix-1230…
Browse files Browse the repository at this point in the history
…-improve-focus-validation

fix: improve focus fields on validation
  • Loading branch information
deandreamatias authored Jun 15, 2023
2 parents 01ec8bb + 8cfd21a commit edcebe5
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
11 changes: 7 additions & 4 deletions lib/src/form_builder.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_form_builder/src/extensions/autovalidatemode_extension.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';

/// A container for form fields.
Expand Down Expand Up @@ -107,6 +106,12 @@ class FormBuilderState extends State<FormBuilder> {
final Map<String, dynamic> _savedValue = {};
// Because dart type system will not accept ValueTransformer<dynamic>
final Map<String, Function> _transformers = {};
bool _focusOnInvalid = true;

/// Will be true if will focus on invalid field when validate
///
/// Only used to internal logic
bool get focusOnInvalid => _focusOnInvalid;

bool get enabled => widget.enabled;

Expand Down Expand Up @@ -161,9 +166,6 @@ class FormBuilderState extends State<FormBuilder> {

void setInternalFieldValue<T>(String name, T? value) {
_instantValue[name] = value;
if (widget.autovalidateMode?.isEnable ?? false) {
validate();
}
widget.onChanged?.call();
}

Expand Down Expand Up @@ -253,6 +255,7 @@ class FormBuilderState extends State<FormBuilder> {
bool focusOnInvalid = true,
bool autoScrollWhenFocusOnInvalid = false,
}) {
_focusOnInvalid = focusOnInvalid;
final hasError = !_formKey.currentState!.validate();
if (hasError) {
final wrongFields =
Expand Down
13 changes: 8 additions & 5 deletions lib/src/form_builder_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>

bool get enabled => widget.enabled && (_formBuilderState?.enabled ?? true);
bool get readOnly => !(_formBuilderState?.widget.skipDisabled ?? false);
bool get _isEnableValidate =>
widget.autovalidateMode.isEnable ||
(_formBuilderState?.widget.autovalidateMode?.isEnable ?? false);
bool get _isAlwaysValidate =>
widget.autovalidateMode.isAlways ||
(_formBuilderState?.widget.autovalidateMode?.isAlways ?? false);
Expand Down Expand Up @@ -178,7 +175,6 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
_dirty = true;
if (enabled || readOnly) {
_formBuilderState!.setInternalFieldValue<T>(widget.name, value);
if (_isEnableValidate) validate();
return;
}
_formBuilderState!.removeInternalFieldValue(widget.name);
Expand Down Expand Up @@ -243,7 +239,14 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
}
final isValid = super.validate() && !hasError;

if (!isValid && focusOnInvalid && enabled) {
final fields = _formBuilderState?.fields ??
<String, FormBuilderFieldState<FormBuilderField<dynamic>, dynamic>>{};

if (!isValid &&
focusOnInvalid &&
(formState?.focusOnInvalid ?? true) &&
enabled &&
!fields.values.any((e) => e.effectiveFocusNode.hasFocus)) {
focus();
if (autoScrollWhenFocusOnInvalid) ensureScrollableVisibility();
}
Expand Down

0 comments on commit edcebe5

Please sign in to comment.