Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text form field initial value #15484

Merged
merged 2 commits into from Mar 14, 2018

Conversation

Projects
None yet
4 participants
@HansMuller
Copy link
Contributor

commented Mar 13, 2018

Currently TextFormField.initialValue defaults to an empty string and is used to initialize the TextFormField controller's TextEditingController.text. If an explicit TextEditingController parameter is provided, it is counter-productive to unconditionally initialize it since doing so clears its state.

This PR changes the default value of TextFormField.initialValue to null and only uses it if the TextFormField's controller is internally generated. If a controller is specified, the initialValue is defined by the controller's text and the initialValue parameter must be null.

This is an incompatible change.

Without this change, it is difficult to build a lazily constructed list - like a ListView - of TextFormFields because each time a TextFormField is recreated its TextEditingController is effectively reset. Given this change the following app works as expected. The state of all 25 TextFormField's is preserved upon scrolling because their TextEditingControllers are persistent.

class FormFieldLifetime extends StatefulWidget {
  @override
  _FormFieldLifetimeState createState() => new _FormFieldLifetimeState();
}

class _FormFieldLifetimeState extends State<FormFieldLifetime> {
  final List<TextEditingController> _controllers = new List.generate(25, (int n) {
    return new TextEditingController();
  }).toList();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("FormFieldLifetime")),
      body: new Form(
        child: new ListView(
          children: new List<Widget>.generate(_controllers.length, (int n) {
            return new TextFormField(
              controller: _controllers[n],
            );
          }).toList(),
        ),
      ),
    );
  }
}

HansMuller added some commits Mar 13, 2018

@@ -204,8 +204,8 @@ void main() {
expect(editableText.widget.controller.text, equals('world'));
});

testWidgets('Provide initial value to input when controller is specified', (WidgetTester tester) async {

This comment has been minimized.

Copy link
@gspencergoog

gspencergoog Mar 13, 2018

Contributor

Don't you still want to also test that the initialValue gets set on the implicitly created controller?

This comment has been minimized.

Copy link
@HansMuller

HansMuller Mar 13, 2018

Author Contributor

Good point, yes. The previous test, Provide initial value to input when no controller is specified checks the implicitly created controller's initial value.

@gspencergoog

This comment has been minimized.

Copy link
Contributor

commented Mar 14, 2018

32384589-a60f0e74-c078-11e7-9bc1-e5b5287aea9d

@HansMuller HansMuller merged commit 9a3b6c3 into flutter:master Mar 14, 2018

4 checks passed

cla/google All necessary CLAs are signed
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
flutter-build

@HansMuller HansMuller deleted the HansMuller:text_form_field_initial_value branch Mar 14, 2018

DaveShuckerow pushed a commit to DaveShuckerow/flutter that referenced this pull request May 14, 2018

@acidjazz

This comment has been minimized.

Copy link

commented May 15, 2018

@HansMuller I'm having an issue trying out this solution here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.