Last active
July 17, 2023 20:53
-
-
Save MelbourneDeveloper/6f75cdb12f0a6a911c5e7e73bb7da7f5 to your computer and use it in GitHub Desktop.
Delayed Save On Text Edit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(const MainApp()); | |
} | |
class DelayedTextEditingController { | |
DelayedTextEditingController( | |
this.onValidated, | |
this.update, | |
this.validate, | |
String initialText, | |
) : textController = TextEditingController(text: initialText) { | |
textController.addListener(() async { | |
await doValidation(); | |
_updateFuture ??= Future.delayed( | |
const Duration(seconds: 2), | |
() async { | |
_updateFuture = null; | |
if (_lastValidValue == null || _lastUpdatedValue == _lastValidValue) { | |
return; | |
} | |
_lastUpdatedValue = _lastValidValue; | |
await update(_lastValidValue!); | |
}, | |
); | |
}); | |
} | |
Future<void> doValidation() async { | |
var text = textController.text; | |
errorMessage = await validate(text); | |
onValidated(); | |
if (errorMessage == null) { | |
_lastValidValue = text; | |
} | |
} | |
final TextEditingController textController; | |
Future<void> Function(String newValue) update; | |
Future<String?> Function(String value) validate; | |
final void Function() onValidated; | |
String? errorMessage; | |
Future<void>? _updateFuture; | |
String? _lastValidValue; | |
String? _lastUpdatedValue; | |
} | |
class ProfileRepo { | |
Future<void> updateName(String name) async { | |
await Future.delayed( | |
const Duration(milliseconds: 50), () => print('name updated to $name')); | |
} | |
Future<void> updateEmailAddress(String email) async { | |
await Future.delayed(const Duration(milliseconds: 50), | |
() => print('email updated to $email')); | |
} | |
} | |
class Controller extends ChangeNotifier { | |
Controller(this.profileRepo, String name, String emailAddress) { | |
nameController = DelayedTextEditingController( | |
notifyListeners, | |
(s) => profileRepo.updateName(s), | |
(s) async => s.isNotEmpty ? null : 'Ouch name is required', | |
name); | |
emailController = DelayedTextEditingController( | |
notifyListeners, | |
(s) => profileRepo.updateEmailAddress(s), | |
(s) async => s.isNotEmpty ? null : 'Ouch email is required', | |
emailAddress); | |
} | |
late final DelayedTextEditingController emailController; | |
late final DelayedTextEditingController nameController; | |
final ProfileRepo profileRepo; | |
} | |
class MainApp extends StatefulWidget { | |
const MainApp({super.key}); | |
@override | |
State<MainApp> createState() => _MainAppState(); | |
} | |
class _MainAppState extends State<MainApp> { | |
Controller controller = | |
Controller(ProfileRepo(), 'Bob Smith', '[email protected]'); | |
@override | |
Widget build(BuildContext context) => MaterialApp( | |
home: Scaffold( | |
body: AnimatedBuilder( | |
animation: controller, | |
builder: (context, child) => Center( | |
child: Padding( | |
padding: const EdgeInsets.all(50), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
TextField( | |
controller: controller.nameController.textController, | |
decoration: InputDecoration( | |
errorText: controller.nameController.errorMessage), | |
), | |
TextField( | |
controller: controller.emailController.textController, | |
decoration: InputDecoration( | |
errorText: controller.emailController.errorMessage), | |
) | |
], | |
), | |
), | |
), | |
), | |
), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment