Paolo Cristofoli
Paolo Cristofoli

Reputation: 93

Flutter: how to manage forms in tabs

I have a tabbar with three tabs with a different form for each one. I have a save button on the bottom to save all of them. Problem is, the three form's globalkeys currentstate are accessible only when the relative tab is active. So the formkey1.currentstate is null when I'm in tab 2 and 3, and so on. Note that I'm managing state with provider.
Any clues on how to solve this?
Here is a short version of the code:

class Myclass extends StatelessWidget{  
     final  _formKey1 = GlobalKey<FormState>();
     final  _formKey2 = GlobalKey<FormState>();
     final  _formKey3 = GlobalKey<FormState>();

 @override
  Widget build(BuildContext context) {
    return DefaultTabController(length: 3, child:
      Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            tabs: [
              Tab(text: "TAB ONE"),
              Tab(text: "TAB TWO"),
              Tab(text: "TAB THREE"),
            ],
          ),
        ),
       bottomNavigationBar: 
          child: Row(
            children: [
                FlatButton(
                  onPressed: (){
                    _save(context);
                  },
                  child: Text("Save"),
              ),
            ],
          )
        ),
        body: TabBarView(children: [

          Form(key: _formKey1, ...),
          Form(key: _formKey2, ...),
          Form(key: _formKey3, ...),
      ])
    ),);
  }

  void _save(BuildContext context) async {
    print(_formKey1.currentState); // NULL ON TAB 2 AND 3
    print(_formKey2.currentState); // NULL ON TAB 1 AND 3
    print(_formKey3.currentState); // NULL ON TAB 1 AND 2
    //my save procedure
}}

Upvotes: 5

Views: 2528

Answers (3)

manish adhikari
manish adhikari

Reputation: 1

you also can use instances of class (Model) to store data while navigating each page

Upvotes: 0

Spike L
Spike L

Reputation: 454

You should use AutomaticKeepAliveClientMixin for each TabView page if you want to keep their states. Also you can you use a KeepAliveWrapper to wrap each page. Here is the code:

class KeepAliveWrapper extends StatefulWidget {
  final Widget child;

  const KeepAliveWrapper({Key key, this.child}) : super(key: key);

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

class __KeepAliveWrapperState extends State<KeepAliveWrapper>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.child;
  }

  @override
  bool get wantKeepAlive => true;
}

Use it like this:

KeepAliveWrapper(
        child: Form(
          key: _formKey1,
          child: Container(),
        ),
      )

Note that before visiting each tab, your sub pages are still not built.

Upvotes: 4

RusJaI
RusJaI

Reputation: 794

You can navigate to a new page (new class) which contains a form. For these 3 forms you can create 3 classes and at the tab bar you can navigate into those 3 classes. Inside a class you can nicely handle your form. No difference in the view! just try it!

Upvotes: -1

Related Questions