Flutter how to get user input using text form in show dialog?

1,892

You can copy paste run full code below
You can call setState in onSaved
code snippet

onSaved: (val) {
                  titleController.text = val;
                  setState(() {});
                },

working demo

enter image description here

full code

import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  final TextEditingController titleController = new TextEditingController();
  final GlobalKey<FormState> _keyDialogForm = new GlobalKey<FormState>();

  @override
  void initState() {
    super.initState();

    titleController.text = 'Hello';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomInset: false,
        body: Center(
          child: Column(
            children: <Widget>[
              Text(titleController.text),
              SizedBox(
                height: 50,
              ),
              FlatButton(
                  color: Colors.redAccent,
                  onPressed: () {
                    showTitleDialog();
                  },
                  child: Text(
                    'Show Dialog',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      color: Colors.white,
                    ),
                  ))
            ],
          ),
        ));
  }

  Future showTitleDialog() {
    return showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Form(
              key: _keyDialogForm,
              child: Column(
                children: <Widget>[
                  TextFormField(
                    decoration: const InputDecoration(
                      icon: Icon(Icons.ac_unit),
                    ),
                    maxLength: 8,
                    textAlign: TextAlign.center,
                    onSaved: (val) {
                      titleController.text = val;
                      setState(() {});
                    },
                    autovalidate: true,
                    validator: (value) {
                      if (value.isEmpty) {
                        return 'Enter Title Name';
                      }

                      return null;
                    },
                  )
                ],
              ),
            ),
            actions: <Widget>[
              FlatButton(
                onPressed: () {
                  if (_keyDialogForm.currentState.validate()) {
                    _keyDialogForm.currentState.save();

                    Navigator.pop(context);
                  }
                },
                child: Text('Save'),
                color: Colors.blue,
              ),
              FlatButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text('Cancel')),
            ],
          );
        });
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Test(),
    );
  }
}
Share:
1,892
Jang Delos Santos
Author by

Jang Delos Santos

Updated on December 20, 2022

Comments

  • Jang Delos Santos
    Jang Delos Santos over 1 year

    I'm trying to get the user input to change the title using a text form in show dialog but it seems the state is rebuilding whenever the keyboard shows/closes, my code is working before, but when I did flutter upgrade to v1.17 it's not working anymore. I've been stuck here for a couple of days now and I don't know what's wrong with my code or what error might be causing it, I can only see "getSelectedText on inactive InputConnection" and "mSecurityInputMethodService is null" in the debug console, please help.

    Here's a sample of my code:

    import 'package:flutter/material.dart';
    
    class Test extends StatefulWidget {
      @override
      _TestState createState() => _TestState();
    }
    
    class _TestState extends State<Test> {
      final TextEditingController titleController = new TextEditingController();
      final GlobalKey<FormState> _keyDialogForm = new GlobalKey<FormState>();
    
      @override
      void initState() {
        super.initState();
    
        titleController.text = 'Hello';
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            resizeToAvoidBottomInset: false,
            body: Center(
              child: Column(
                children: <Widget>[
                  Text(titleController.text),
                  SizedBox(
                    height: 50,
                  ),
                  FlatButton(
                      color: Colors.redAccent,
                      onPressed: () {
                        showTitleDialog();
                      },
                      child: Text(
                        'Show Dialog',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ))
                ],
              ),
            ));
      }
    
      Future showTitleDialog() {
        return showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: Form(
                  key: _keyDialogForm,
                  child: Column(
                    children: <Widget>[
                      TextFormField(
                        decoration: const InputDecoration(
                          icon: Icon(Icons.ac_unit),
                        ),
                        maxLength: 8,
                        textAlign: TextAlign.center,
                        onSaved: (val) {
                          titleController.text = val;
                        },
                        autovalidate: true,
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'Enter Title Name';
                          }
    
                          return null;
                        },
                      )
                    ],
                  ),
                ),
                actions: <Widget>[
                  FlatButton(
                    onPressed: () {
                      if (_keyDialogForm.currentState.validate()) {
                        _keyDialogForm.currentState.save();
    
                        Navigator.pop(context);
                      }
                    },
                    child: Text('Save'),
                    color: Colors.blue,
                  ),
                  FlatButton(
                      onPressed: () {
                        Navigator.pop(context);
                      },
                      child: Text('Cancel')),
                ],
              );
            });
      }
    }
    
  • Jang Delos Santos
    Jang Delos Santos almost 4 years
    thanks for the response, but what version of flutter are you using? it does work, but after I run flutter upgrade to v1.17 it's not working anymore
  • chunhunghan
    chunhunghan almost 4 years
    my version is 1.19.0-1.0.pre. you need to call setState to rebuild widget.
  • Jang Delos Santos
    Jang Delos Santos almost 4 years
    oh I see, I tried it now in my main.dart and it works, so my problem now is if it is inside tab bar it's still broken. thanks for clarifying things and for the help.