Problem to keep value in a Textfield with the components PageController and PageView

48 views Asked by At

I have a problem to keep the value of my Texfield field when I return to one of my pages of my form. I'm using the components PageController with PageView.

I wrote a simple exemple to explain. It's not optimized but it's enough to explain my problem.

I have 3 pages. The first two pages are a form containing a Textfield component. The last page is a summary. The appBar and bottomNavigationBar components are cross-functional components.

enter image description here

Use case of the problem :

When I click on the button "Next" it works, the value on my differents fields are saved in a object "FormData". BUT, my problem is, when I click on previous button. I lose the value I entered in my field although it is still in my formData object

Here the body :

@override
    Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('PageView Example'),
          ),
          body: Column(
            children: [
              linearProgressIndicator(),
              Expanded(
                child: PageView(
                  controller: _pageController,
                  children: <Widget>[
                    FormPage1(),
                    FormPage2(),
                    SummaryPage(),
                  ],
                ),
              ),
            ],
          ),
          bottomNavigationBar: bottomBarWidget(),
        );
      }

The code of the buttons :

void _navigateToNextPage() {
    if (_pageController.page!.round() < 2) {
      _pageController.nextPage(
          duration: Duration(milliseconds: 500), curve: Curves.easeInOut);
    }
  }

  void _navigateToPreviousPage() {
    if (_pageController.page!.round() > 0) {
      _pageController.previousPage(
          duration: Duration(milliseconds: 500), curve: Curves.easeInOut);
    }
  }

The code of FormPage

class FormData extends ChangeNotifier {
  String? field1;
  String? field2;
}

class FormPage1 extends StatelessWidget {
  TextEditingController controllerTitle = TextEditingController();

  @override
  Widget build(BuildContext context) {
    var formData = Provider.of<FormData>(context);
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Page 1 - Form'),
            TextField(
              controller: controllerTitle,
              onChanged: (value) {
                formData.field1 = value;
              },
              decoration: InputDecoration(labelText: 'Field 1'),
            ),
          ],
        ),
      ),
    );
  }
}

The SummaryPage

class SummaryPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var formData = Provider.of<FormData>(context);
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('Summary Page'),
          Text('Field 1: ${formData.field1 ?? ""}'),
          Text('Field 2: ${formData.field2 ?? ""}'),
        ],
      ),
    );
  }
}
1

There are 1 answers

0
Mickael Roignant On

Adding the property "initialValue:" I get an ERROR :

enter image description here

So I added in the first component my formData : var formData = Provider.of(context); I don't know if it's a right way to do it but it's work.

@override
  Widget build(BuildContext context) {
    var _formData = Provider.of<FormData>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('PageView Example'),
      ),
      body: Column(
        children: [
          linearProgressIndicator(),
          Expanded(
            child: PageView(
              controller: _pageController,
              children: <Widget>[
                FormPage1(formData: _formData),
                FormPage2(),
                SummaryPage(),
              ],
            ),
          ),
        ],
      ),
      bottomNavigationBar: bottomBarWidget(),
    );
  }



class _FormPage1State extends State<FormPage1> {
      TextEditingController controllerTitle = TextEditingController();
    
      @override
      void initState() {
          setState(() {
            if (widget.formData.field1 != null) {
              controllerTitle.text = widget.formData.field1!;
            }
          });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        var formData = Provider.of<FormData>(context);
    
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Page 1 - Form'),
                TextFormField(
                  controller: controllerTitle,
                  onChanged: (value) {
                    formData.field1 = value;
                  },
                  decoration: InputDecoration(labelText: 'Field 1'),
                ),
              ],
            ),
          ),
        );
      }
    }