Home > Blockchain >  Flutter unable to update dynamic TextEditingController text
Flutter unable to update dynamic TextEditingController text

Time:10-06

I'm generating TextFormFields dynamically and assigning unique TextEditingControllers individually. I then only update the text of the TextFormField that's currently in focus

Column textField(int n) {
  List<Widget> listForm = [];
  while (n > 0) {
    var textEditingController = TextEditingController();
    listForm.add(
      TextFormField(
        controller: textEditingController,
        onTap: () {
          debugPrint('Current Controller: $textEditingController');
          setState(() {
            _selectedField = textEditingController;
          });
        },
      ),
    );
    n--;
  }
  return Column(children: listForm);
}

with

InkWell(
  onTap: () {
    debugPrint('Selected $index!');
    if (_selectedField != null) {
      /// On tap is able to fetch the correct active TextFormField
      debugPrint('Active field: $_selectedField');
      _selectedField!.text = 'Hello!';  // doesn't work
      setState(() {
        /// Setting TextEditingController.text doesn't work
        _selectedField!.text = 'Item $index'; // doesn't work
      });
  }
},

I'm able to successfully fetch the TextEditingController, but unable to update their text. Any idea why TextEditingController.text doesnt work?

Minimal repro

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController? _selectedField;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        padding: const EdgeInsets.all(8.0),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(flex: 1, child: textField(3)),
              Expanded(flex: 1, child: listItems()),
            ],
          ),
        ),
      ),
    );
  }

  Column textField(int n) {
    List<Widget> listForm = [];
    while (n > 0) {
      var textEditingController = TextEditingController();
      listForm.add(
        TextFormField(
          controller: textEditingController,
          onTap: () {
            debugPrint('Current Controller: $textEditingController');
            setState(() {
              _selectedField = textEditingController;
            });
          },
        ),
      );
      n--;
    }
    return Column(children: listForm);
  }

  ListView listItems() {
    return ListView.builder(
      itemCount: 5,
      itemBuilder: (BuildContext context, int index) {
        return InkWell(
          onTap: () {
            debugPrint('Selected $index!');
            if (_selectedField != null) {
              /// On tap is able to fetch the correct active TextFormField
              debugPrint('Active field: $_selectedField');
              _selectedField!.text = 'Hello!';  // doesn't work
              setState(() {
                /// Setting TextEditingController.text doesn't work
                _selectedField!.text = 'Item $index'; // doesn't work
              });
            }
          },
          child: ListTile(
            title: Text('Item $index'),
          ),
        );
      },
    );
  }
}

CodePudding user response:

TextEditingValue() will work:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController? _selectedField = TextEditingController();
    List<Widget> listForm = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        padding: const EdgeInsets.all(8.0),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(flex: 1, child: textField(3)),
              Expanded(flex: 1, child: listItems()),
            ],
          ),
        ),
      ),
    );
  }

  Column textField(int n) {

    


    while (n > 0) {
      TextEditingController _textEditingController = TextEditingController();
      listForm.add(
        TextFormField(
          controller: _textEditingController,
          onTap: () {
          
              _selectedField = _textEditingController;

          
              debugPrint( 'selected'    _selectedField!.value.text );
              debugPrint('main'    _textEditingController.toString());
          },
        ),
      );
      n--;

    }
    return Column(children: listForm);
  }

  ListView listItems() {
    return ListView.builder(
      itemCount: 5,
      itemBuilder: (BuildContext context, int index) {
        return InkWell(
          onTap: () {
            debugPrint('Selected $index!');
            if (_selectedField != null) {
           
                _selectedField!.value =
                    TextEditingValue(text: 'Item $index'); // doesn't work
                debugPrint(_selectedField?.value.text);
                debugPrint(_selectedField.hashCode.toString());
                debugPrint('Item $index');  
            }
          },
          child: ListTile(
            title: Text('Item $index'),
          ),
        );
      },
    );
  }
}
  • Related