Skip to content

[proposal] Provide a way to retrieve the data of all textfields within a Form widget #107528

Description

@casvanluijtelaar

Use case

the Flutter Form widget can be extremely powerful and has a lot of potential to simplify form implementations. Sadly I'm finding myself having to create my own Form widgets because there is not simple build-in way to aggregate all the form data in one place. Just like the form can interact with all its FormField children through validation, saving, ... it should also have an option to submit it's childrens data. Similar to how HTML handles form submission.

Proposal

since the FormState already has all its FormFieldState children registered it would be trivial to collect all their values. the implementation difficulties come from returning the form data in a manageable way.

I would propose adding a submissionKey string to the FormField<T> base class. this allows us to aggregate all the FormField data under a Map<String, dynamic> where the entries would be shaped as: submissionKey: value.

this would require all FormField to have a non-null submissionKey. This can be hande by either throwing an exception when calling a form submit on a null submissionKey, or not adding FormField values to the end Form submit data if the submissionKey is null.

This would be a minor addition to the framework with no breaking or changing code, that would still have enormous benefits.

comparing the current closest implementation of this:

Form(
  child: Column(
    children: [
      TextField( 
        onSave: (value) {
          data['name'] = value;
        },
      ),
      TextField(
        onSave: (value) {
          data['email'] = value;
        },
      ),
      TextField(
         onSave: (value) {
          data['message'] = value;
        },
      ),
      MaterialButton(
        child: Text('submit'),
        onPressed: () {
          final form = Form.of(context);
          if(!form.validate()) return;

          form.save();
          /// handle data in stateful widget...
        }
      ),
    ],
  ),    
);

would be turned into something like this:

Form(
  child: Column(
    children: [
      TextField(
        submissionKey: 'name',
        ...
      ),
      TextField(
        submissionKey: 'email',
        ...
      ),
      TextField(
        submissionKey: 'message',
        ...
      ),
      MaterialButton(
        child: Text('submit'),
        onPressed: () {
          final form = Form.of(context);
          if(!form.validate()) return;
          
          final data = form.submit();
          // final object = FormObject.fromJson(data); ...
        }
      );
    ],
  ),    
);

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: text inputEntering text in a text field or keyboard related problemsc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterf: material designflutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.team-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions