3

Let's say there is an empty TextFormField. After entering 2 characters manually I would like to insert a new one programmatically. So if length equals with 2 than insert a new one. It sounds really simple but strange behaviors appeared while I tried to achieve this. For example: The cursor continuously jumps back to the start and may cause this debug log:

Text selection index was clamped (-1->0) to remain in bounds. This may not be your fault, as some keyboards may select outside of bounds.

Or if I try to deal with the TextEditingController's value or selection property to place cursor at the end of the text, it causes more strange behaviors.

Can you provide me an example by using a TextField or a TextFormField with a TextEditingController and on onChanged() if text length is equals with 2 than insert a new character at the end and place back the cursor also at the end.

I tried these solutions but in this case they did not work:
How do you change the value inside of a textfield flutter?

Thank you!

EDIT: Example code:

void main() => runApp(MyApp());

/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'example',
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final TextEditingController controller = TextEditingController(text: '');

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: controller,
      onChanged: (value) {
        if (controller.text != null && controller.text.length == 2) {
          controller.text = '$value/';

          controller.selection = TextSelection.fromPosition(
              TextPosition(offset: controller.text.length));
          setState(() {});
        }
      },
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

}

The problem: If I replace the TextFormField to a TextField, it works as expected. I guess it is a bug that should be fixed.

I also found a link that in flutter version 1.20.1 and later this is an issue with TextFormFields.

https://github.com/flutter/flutter/issues/62654

Ricky
  • 553
  • 6
  • 21
  • the link you provide is working fine. please post your reproduce code. thanks. – chunhunghan Aug 18 '20 at 01:19
  • It's very strange because if I debug the process with a break point in my IDE it works fine but other than that it's not working. – Ricky Aug 18 '20 at 09:59

1 Answers1

0

TextFormField is a FormField that contains a TextField. While a Form isn't required to be its parent, using a Form makes it easier to manage multiple fields at once. You can stick with TextField if it works better and meets the requirements.

Omatt
  • 8,564
  • 2
  • 42
  • 144