diff --git a/lib/src/auth_screen.dart b/lib/src/auth_screen.dart index 8c5a51b..4a757f5 100644 --- a/lib/src/auth_screen.dart +++ b/lib/src/auth_screen.dart @@ -64,6 +64,7 @@ class _AuthScreenState extends State { final _animationDuration = const Duration(milliseconds: 300); final _animationCurve = Curves.ease; bool _formValid = false; + final _values = HashMap(); AppBar get _appBar => widget.customAppBar ?? @@ -89,6 +90,14 @@ class _AuthScreenState extends State { FocusScope.of(context).unfocus(); + for (var step in widget.steps) { + for (var field in step.fields) { + setState(() { + _values[field.name] = field.value; + }); + } + } + if (widget.steps.last == step) { var values = HashMap(); @@ -142,151 +151,180 @@ class _AuthScreenState extends State { @override Widget build(BuildContext context) { - return widget.isLoading - ? const Center( - child: SizedBox( - height: 120, - width: 120, - child: CircularProgressIndicator(), - ), - ) - : Scaffold( - backgroundColor: widget.customBackgroundColor ?? Colors.white, - appBar: _appBar, - body: Form( - key: _formKey, - child: PageView( - physics: const NeverScrollableScrollPhysics(), - controller: _pageController, - children: [ - for (var i = 0; i < widget.steps.length; i++) - Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + if (widget.isLoading) { + return const Center( + child: SizedBox( + height: 120, + width: 120, + child: CircularProgressIndicator(), + ), + ); + } + + return Scaffold( + backgroundColor: widget.customBackgroundColor ?? Colors.white, + appBar: _appBar, + body: Form( + key: _formKey, + child: PageView( + physics: const NeverScrollableScrollPhysics(), + controller: _pageController, + children: [ + for (var i = 0; i < widget.steps.length; i++) + Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (widget.titleWidget != null) ...[ + Expanded( + flex: widget.titleFlex ?? 1, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Spacer( + flex: widget.beforeTitleFlex ?? 3, + ), + widget.titleWidget!, + Spacer( + flex: widget.afterTitleFlex ?? 2, + ), + ], + ), + ), + ], + Expanded( + flex: widget.formFlex ?? 3, + child: Column( + children: [ + for (AuthField field + in widget.steps[i].fields.map((field) { + if (!_values.containsKey(field.name)) return field; + field.value = _values[field.name]!; + return field; + })) + Align( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (field.title != null) ...[ + field.title!, + ], + field.build(context, (v) { + _values[field.name] = v; + _validate(i); + }), + ], + ), + ), + ], + ), + ), + Padding( + padding: EdgeInsets.only( + top: 15.0, + bottom: 30.0, + left: widget.previousButtonBuilder == null && + widget.steps.first != widget.steps[i] + ? 30.0 + : 0.0, + right: widget.nextButtonBuilder == null && + widget.previousButtonBuilder == null + ? 30.0 + : 0.0, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: + widget.buttonMainAxisAlignment != null + ? widget.buttonMainAxisAlignment! + : (widget.previousButtonBuilder != null && + widget.previousButtonBuilder?.call( + onPrevious, + widget.previousBtnTitle, + i, + ) == + null) + ? MainAxisAlignment.start + : widget.steps.first != widget.steps[i] + ? MainAxisAlignment.center + : MainAxisAlignment.end, children: [ - if (widget.titleWidget != null) ...[ - Expanded( - flex: widget.titleFlex ?? 1, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - flex: widget.beforeTitleFlex ?? 3, - child: Container(), - ), - widget.titleWidget!, - Expanded( - flex: widget.afterTitleFlex ?? 2, - child: Container(), - ), - ], - ), - ), - Column( - children: [ - Row( - mainAxisAlignment: - widget.buttonMainAxisAlignment != null - ? widget.buttonMainAxisAlignment! - : (widget.previousButtonBuilder != - null && - widget.previousButtonBuilder - ?.call( - onPrevious, - widget - .previousBtnTitle, - i, - ) == - null) - ? MainAxisAlignment.start - : widget.steps.first != - widget.steps[i] - ? MainAxisAlignment.center - : MainAxisAlignment.end, + if (widget.previousButtonBuilder == null) ...[ + if (widget.steps.first != widget.steps[i]) + ElevatedButton( + onPressed: onPrevious, + child: Row( children: [ - if (widget.previousButtonBuilder == - null) ...[ - if (widget.steps.first != - widget.steps[i]) - ElevatedButton( - onPressed: onPrevious, - child: Row( - children: [ - const Icon( - Icons.arrow_back, - size: 18, - ), - Padding( - padding: - const EdgeInsets.only( - left: 4.0), - child: Text( - widget.previousBtnTitle), - ), - ], - ), - ), - ] else if (widget.previousButtonBuilder - ?.call(onPrevious, - widget.previousBtnTitle, i) != - null) ...[ - widget.previousButtonBuilder!.call( - onPrevious, - widget.previousBtnTitle, - i)! - ], - widget.nextButtonBuilder?.call( - !_formValid - ? null - : () async { - await onNext( - widget.steps[i]); - }, - widget.steps.last == widget.steps[i] - ? widget.submitBtnTitle - : widget.nextBtnTitle, - i, - _formValid, - ) ?? - ElevatedButton( - onPressed: !_formValid - ? null - : () async { - await onNext( - widget.steps[i]); - }, - child: Row( - children: [ - Text( - widget.steps.last == - widget.steps[i] - ? widget.submitBtnTitle - : widget.nextBtnTitle, - ), - const Padding( - padding: EdgeInsets.only( - left: 4.0), - child: Icon( - Icons.arrow_forward, - size: 18, - ), - ), - ], - ), - ), + const Icon( + Icons.arrow_back, + size: 18, + ), + Padding( + padding: + const EdgeInsets.only(left: 4.0), + child: Text(widget.previousBtnTitle), + ), ], ), - if (widget.loginButton != null) - Padding( - padding: const EdgeInsets.only(top: 20.0), - child: widget.loginButton!, - ), - ], - ), + ), + ] else if (widget.previousButtonBuilder?.call( + onPrevious, widget.previousBtnTitle, i) != + null) ...[ + widget.previousButtonBuilder! + .call(onPrevious, widget.previousBtnTitle, i)! ], - ]), - ]), - )); + widget.nextButtonBuilder?.call( + !_formValid + ? null + : () async { + await onNext(widget.steps[i]); + }, + widget.steps.last == widget.steps[i] + ? widget.submitBtnTitle + : widget.nextBtnTitle, + i, + _formValid, + ) ?? + ElevatedButton( + onPressed: !_formValid + ? null + : () async { + await onNext(widget.steps[i]); + }, + child: Row( + children: [ + Text( + widget.steps.last == widget.steps[i] + ? widget.submitBtnTitle + : widget.nextBtnTitle, + ), + const Padding( + padding: EdgeInsets.only(left: 4.0), + child: Icon( + Icons.arrow_forward, + size: 18, + ), + ), + ], + ), + ), + ], + ), + if (widget.loginButton != null) + Padding( + padding: const EdgeInsets.only(top: 20.0), + child: widget.loginButton!, + ), + ], + ), + ) + ], + ) + ], + ), + ), + ); } } diff --git a/lib/src/config/registration_options.dart b/lib/src/config/registration_options.dart index 01abe48..582081f 100644 --- a/lib/src/config/registration_options.dart +++ b/lib/src/config/registration_options.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_registration/flutter_registration.dart'; class RegistrationOptions { - RegistrationOptions({ + const RegistrationOptions({ required this.registrationRepository, required this.registrationSteps, required this.afterRegistration, @@ -35,8 +35,8 @@ class RegistrationOptions { previousButtonBuilder; final MainAxisAlignment? buttonMainAxisAlignment; final Color? backgroundColor; - Widget? titleWidget; - Widget? loginButton; + final Widget? titleWidget; + final Widget? loginButton; static List getDefaultSteps({ TextEditingController? emailController, diff --git a/lib/src/model/auth_bool_field.dart b/lib/src/model/auth_bool_field.dart index 503c4f4..163e15d 100644 --- a/lib/src/model/auth_bool_field.dart +++ b/lib/src/model/auth_bool_field.dart @@ -30,8 +30,9 @@ class AuthBoolField extends AuthField { onChanged: (v) { value = v; onChange?.call(value); - onValueChanged(); + onValueChanged(v); }, + initialValue: value, validator: (value) { for (var validator in validators) { var output = validator(value); diff --git a/lib/src/model/auth_drop_down.dart b/lib/src/model/auth_drop_down.dart index 9a2acba..0663ed5 100644 --- a/lib/src/model/auth_drop_down.dart +++ b/lib/src/model/auth_drop_down.dart @@ -11,9 +11,7 @@ class AuthDropdownField extends AuthField { this.textStyle, this.icon = const Icon(Icons.keyboard_arrow_down), required super.value, - }) { - selectedValue = value ?? items.first; - } + }); final List items; final Function(String?) onChanged; @@ -30,7 +28,7 @@ class AuthDropdownField extends AuthField { child: DropdownButtonFormField( icon: icon, style: textStyle, - value: selectedValue, + value: value, decoration: dropdownDecoration, items: items.map((String value) { return DropdownMenuItem( @@ -41,7 +39,7 @@ class AuthDropdownField extends AuthField { onChanged: (newValue) { selectedValue = newValue; onChanged(newValue); - onValueChanged(); + onValueChanged(newValue); }, validator: (value) { if (validators.isNotEmpty) { diff --git a/lib/src/model/auth_pass_field.dart b/lib/src/model/auth_pass_field.dart index 6cb978c..b9b7f86 100644 --- a/lib/src/model/auth_pass_field.dart +++ b/lib/src/model/auth_pass_field.dart @@ -9,10 +9,10 @@ import 'package:flutter_registration/flutter_registration.dart'; class AuthPassField extends AuthField { AuthPassField({ required super.name, - TextEditingController? textEditingController, super.title, super.validators = const [], super.value = '', + this.textEditingController, this.textStyle, this.onChange, this.iconSize, @@ -24,6 +24,7 @@ class AuthPassField extends AuthField { final double? iconSize; final Function(String value)? onChange; final InputDecoration? textFieldDecoration; + final TextEditingController? textEditingController; final EdgeInsets padding; @override @@ -33,11 +34,13 @@ class AuthPassField extends AuthField { child: FlutterFormInputPassword( style: textStyle, iconSize: iconSize ?? 24.0, + initialValue: textEditingController == null ? value : null, decoration: textFieldDecoration, + controller: textEditingController, onChanged: (v) { value = v; onChange?.call(value); - onValueChanged(); + onValueChanged(v); }, validator: (value) { for (var validator in validators) { diff --git a/lib/src/model/auth_text_field.dart b/lib/src/model/auth_text_field.dart index 3c7b7c0..a122945 100644 --- a/lib/src/model/auth_text_field.dart +++ b/lib/src/model/auth_text_field.dart @@ -8,20 +8,17 @@ import 'package:flutter_registration/flutter_registration.dart'; class AuthTextField extends AuthField { AuthTextField({ required super.name, - TextEditingController? textEditingController, super.title, super.validators = const [], super.value = '', + this.textEditingController, this.textStyle, this.onChange, this.textFieldDecoration, this.padding = const EdgeInsets.all(8.0), - }) { - textController = - textEditingController ?? TextEditingController(text: value); - } + }); - late TextEditingController textController; + final TextEditingController? textEditingController; final TextStyle? textStyle; final Function(String value)? onChange; final InputDecoration? textFieldDecoration; @@ -34,11 +31,12 @@ class AuthTextField extends AuthField { child: TextFormField( style: textStyle, decoration: textFieldDecoration, - controller: textController, + controller: textEditingController, + initialValue: textEditingController == null ? value : null, onChanged: (v) { value = v; onChange?.call(value); - onValueChanged(); + onValueChanged(v); }, validator: (value) { for (var validator in validators) {