rxlabz / flutter_formgen_poc

a Flutter code generation sandbox

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Flutter form generation POC

A little code generation experimentation : Define a FormModel, and generate a FormWidget

For example, this model :

@RXForm()
class UserFormModel extends ValueNotifier<Map<String, String>> {
  @required
  String email;
  String emailValidator(String value) =>
      validateMail(value) ?? validateRequired(value);

  String firstname;

  String lastname;

  @required
  @obscure
  String password;
  String passwordValidator(String value) => validateRequired(value);

  @override
  Map<String, String> get value => {
        'email': email,
        'lastname': lastname,
        'firstname': firstname,
        'password': password,
      };
  @override
  set value(_) {}

  UserFormModel({this.email, this.password}) : super(null);

  onSubmit() => notifyListeners();
}

will generate

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user_form_model.dart';

// **************************************************************************
// FormGenerator
// **************************************************************************

class UserForm extends StatefulWidget {
  UserForm(this.model);

  final UserFormModel model;

  @override
  _UserFormState createState() => _UserFormState();
}

class _UserFormState extends State<UserForm> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  TextEditingController emailController;

  TextEditingController firstnameController;

  TextEditingController lastnameController;

  TextEditingController passwordController;

  bool _autovalidate = false;

  @override
  void initState() {
    emailController = TextEditingController();
    firstnameController = TextEditingController();
    lastnameController = TextEditingController();
    passwordController = TextEditingController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Form(
        key: _formKey,
        child: ListView(children: [
          TextFormField(
              key: Key('emailField'),
              controller: emailController,
              decoration: InputDecoration(labelText: 'Email'),
              validator: widget.model.emailValidator,
              onSaved: (value) => widget.model.email = value,
              autovalidate: _autovalidate),
          TextFormField(
              key: Key('firstnameField'),
              controller: firstnameController,
              decoration: InputDecoration(labelText: 'Firstname'),
              onSaved: (value) => widget.model.firstname = value),
          TextFormField(
              key: Key('lastnameField'),
              controller: lastnameController,
              decoration: InputDecoration(labelText: 'Lastname'),
              onSaved: (value) => widget.model.lastname = value),
          TextFormField(
              key: Key('passwordField'),
              controller: passwordController,
              obscureText: true,
              decoration: InputDecoration(labelText: 'Password'),
              validator: widget.model.passwordValidator,
              onSaved: (value) => widget.model.password = value,
              autovalidate: _autovalidate),
          RaisedButton(
              child: Text('Submit'),
              onPressed: () {
                if (_formKey.currentState.validate()) {
                  _formKey.currentState.save();
                  widget.model.onSubmit();
                } else
                  setState(() => _autovalidate = true);
              })
        ]));
  }
}

and could be used this way :

class UserFormScreen extends StatefulWidget {
  @override
  _UserFormScreenState createState() => _UserFormScreenState();
}

class _UserFormScreenState extends State<UserFormScreen> {
  final UserFormModel formModel = UserFormModel();

  @override
  void initState() {
    formModel.addListener(() => print('submitted values ${formModel.value}'));
    super.initState();
  }

  @override
  void dispose() {
    formModel.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: UserForm(formModel),
      ),
    );
  }
}

Resources

About

a Flutter code generation sandbox


Languages

Language:Dart 89.4%Language:Objective-C 7.2%Language:Java 3.5%