From 94b0ff01ad5045332d3d172f35bb40fe4359705e Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Sun, 10 Jul 2022 21:13:52 +0200 Subject: [PATCH] doc: update readme with usage --- packages/wyatt_form_bloc/README.md | 134 +++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 7 deletions(-) diff --git a/packages/wyatt_form_bloc/README.md b/packages/wyatt_form_bloc/README.md index 2ac8212b..794fa32d 100644 --- a/packages/wyatt_form_bloc/README.md +++ b/packages/wyatt_form_bloc/README.md @@ -30,21 +30,25 @@ Form Bloc for Dart & Flutter. ## Features - Form - * FormInput: *atom of a form* + * FormInputValidator: - Store data - Validate this data - * FormEntry: *shell of this atom* + * FormInputMetadata: + - Store infos and options about an input. + * FormEntry: - Associate a key to an input - Configure form attribute (exportation, name...) - * FormData: *collection of entries* - - Contain all entries + * FormInput: + - Associaite a key, to a validator and metadata. + * FormData: *collection of inputs* + - Contain all inputs - Basic set operation - FormDataCubit * Data management behind a form. - Use entries to pass a FormData object - - You can use several pre configured FormInput for validation - - You can use updateFormData() to change FormData and validators during runtime (intersection, union, difference or replace) + - You can use several pre configured `FormInputValidator` for validation + - You can use updateFormData() to change `FormData` during runtime (intersection, union, difference or replace) - Consistent * Every class have same naming convention @@ -59,4 +63,120 @@ import 'package:wyatt_form_bloc/wyatt_form_bloc.dart'; ## Usage -todo \ No newline at end of file +Firstly, you have to create your form inputs. + +```dart +static List getNormalEntries() { + return const [ + FormInput(formFieldName, Name.pure()), + FormInput(formFieldEmail, Email.pure()), + FormInput(formFieldPhone, Phone.pure()), + FormInput(formFieldList, ListOption.pure(defaultValue: ['checkbox3'])), + FormInput(formFieldRadio, TextString.pure()), + FormInput(formFieldPro, Boolean.pure(), metadata: FormInputMetadata(name: 'business')), + FormInput(formFieldHidden, Boolean.pure(), metadata: FormInputMetadata(export: false)), + ]; +} + +static List getBusinessEntries() { + const entries = [ + FormInput(formFieldSiren, Siren.pure()), + FormInput(formFieldIban, Iban.pure()), + ]; + return getNormalEntries() + entries; +} + +static FormData getNormalFormData() { + return FormData(getNormalEntries()); +} + +static FormData getProFormData() { + return FormData(getBusinessEntries()); +} +``` + +> Let's create functions to enable dynamic changes in runtime. + +> When creating metadata with `FormInputMetadata`, `T` is the type of `extra` object. + +Then a `FormData` is a collection of inputs. You can `validate`, `contains`, `intersection`, `difference`, `union`, or `clone` this data. + +After that, you have to extends `FormDataCubit`. + +```dart +class CustomFormCubit extends FormDataCubit { + CustomFormCubit({required FormData inputs}) : super(inputs: inputs); + + @override + Future submitForm() { + log(state.data.toMap().toString()); + // Handle all your logic here. + emit(...) + } +} +``` + +> The submited form is in `state.data` ! + +Don't forget to create and provide it ! + +```dart +FormDataCubit _formCubit = CustomFormCubit(inputs: getNormalFormData()); + +return BlocProvider( + create: (context) => _formCubit, + child: const WidgetTree(), +); +``` + +You can now create the first form input ! + +```dart +class _EmailInput extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return TextField( + onChanged: (email) => context + .read() + .dataChanged(formFieldEmail, Email.dirty(email)), + keyboardType: TextInputType.emailAddress, + decoration: InputDecoration( + labelText: 'email', + helperText: '', + errorText: state.data.isNotValid(formFieldEmail) + ? 'invalid email' + : null, + ), + ); + }, + ); + } +} +``` + +Then, you can create the trigger + +```dart +class _SignUpButton extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (previous, current) => previous.status != current.status, + builder: (context, state) { + return state.status.isSubmissionInProgress + ? const CircularProgressIndicator() + : ElevatedButton( + onPressed: state.status.isValidated + ? () => context.read().submitForm() + : null, + child: const Text('SIGN UP'), + ); + }, + ); + } +} +``` + +> With `state.status` you can access the status of the form to check if there is an error or if it's in submission. \ No newline at end of file