Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting TextEditingController.text selects input in TextField in Web #419

Closed
Kurczaak opened this issue Mar 13, 2024 · 1 comment
Closed
Assignees
Labels
bug Something isn't working needs triage

Comments

@Kurczaak
Copy link

Kurczaak commented Mar 13, 2024

Describe the bug
User cannot type in a TextField because each keystroke selects whole input causing the whole text to be replaced with the next keystroke. Reproducible only in Web, both Android and iOS work great.

To Reproduce

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

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

class MyApp extends HookWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: MyTextInput(),
      ),
    );
  }
}

class MyTextInput extends HookWidget {
  const MyTextInput({super.key});

  @override
  Widget build(BuildContext context) {
    final textValue = useState('Initial Value');
    final textEditingController =
        useTextEditingController(text: textValue.value);

    useEffect(() {
      Timer.periodic(const Duration(seconds: 1), (timer) {
        textValue.value = 'Updated at ${DateTime.now()}';
        textEditingController.text = textValue.value;
      });
      return null;
    }, const []);

    return TextField(
      controller: textEditingController,
    );
  }
}

Run the app in Web and try to type something or set the cursor at the very end of the field. The bug is not reproducible using StatefulWidget or running on Android or iOS. The effect is even more noticable when combined with BLoC listener or builder and when the text of TextField depends on the state data.

One way to fix this is to use TextEditingValue like so:

textEditingController.value = TextEditingValue(
         text: textValue.value,
         selection: TextSelection.collapsed(offset: textValue.value.length),
       );

Expected behavior
TextField input doesn't automatically get selected

@Kurczaak Kurczaak added bug Something isn't working needs triage labels Mar 13, 2024
@rrousselGit
Copy link
Owner

This has nothing to do with flutter_hooks and can be reproduced with stateful widgets:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

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

class MyApp extends HookWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyTextInput(),
      ),
    );
  }
}

class MyTextInput extends StatefulWidget {
  @override
  State<MyTextInput> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyTextInput> {
  var textValue = 'Initial Value';
  final controller = TextEditingController(
    text: 'Initial Value',
  );

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

    Timer.periodic(const Duration(seconds: 1), (timer) {
      setState(() {
        textValue = 'Updated at ${DateTime.now()}';
        controller.text = textValue;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: controller,
    );
  }
}

So I'll close this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs triage
Projects
None yet
Development

No branches or pull requests

2 participants