Skip to content

Calling TextEditingController.clear() does not call formatEditUpdate of formatter  #86354

Closed

Description

@siqwin

Calling TextEditingController.clear() does not call formatEditUpdate of TextInputFormatter's.
This makes it difficult to keep the formatter state in sync with TextEditingController.

Example case:

Some TextInputFormatter allows you to format the phone number in something like (555) 333-44-55, but it also has a method to get the phone in its original form without formatting like 555334455. There is also a field clear button that calls the method TextEditingController.clear(). When you click on this button, the text field will be erased, but this will not call the method formatEditUpdate, so it is still possible to get the value from the formatter.

There is a way out to force the programmer to also call some cleanup method on the formatter itself, but it is quite difficult to keep track of this.

Activity

  1. TahaTesser commented on Jul 14, 2021

    @TahaTesser
    Contributor

    Hi @siqwin

    Thanks for filing the issue

    Calling TextEditingController.clear() does not call formatEditUpdate of TextInputFormatter's.
    This makes it difficult to keep the formatter state in sync with TextEditingController.

    Can you please provide a minimal code sample to demonstrate this and your flutter doctor -v

  2. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jul 14, 2021
  3. siqwin commented on Jul 14, 2021

    @siqwin
    Author

    Example:

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() => runApp(MaterialApp(home: DemoPage()));
    
    class DemoPage extends StatefulWidget {
      DemoPage({Key? key}) : super(key: key);
    
      @override
      _DemoPageState createState() => _DemoPageState();
    }
    
    class _DemoPageState extends State<DemoPage> {
      final TextEditingController controller = TextEditingController();
      final DemoFormatter formatter = DemoFormatter();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: SafeArea(
            minimum: EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                TextFormField(
                  controller: controller,
                  decoration: InputDecoration(
                    hintText: "Enter something",
                    suffixIcon: ValueListenableBuilder<TextEditingValue>(
                      valueListenable: controller,
                      builder: (context, value, _) {
                        return Visibility(
                          visible: value.text.isNotEmpty,
                          child: IconButton(
                            icon: Icon(Icons.clear),
                            onPressed: () {
                              controller.clear();
                              print("Now controller.value is empty: ${controller.value}");
                              print("But formatter.value is not: ${formatter.value}");
                            },
                          ),
                        );
                      },
                    ),
                  ),
                  inputFormatters: [formatter],
                )
              ],
            ),
          ),
        );
      }
    }
    
    class DemoFormatter extends TextInputFormatter {
      TextEditingValue value = TextEditingValue.empty;
    
      @override
      TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
        print("DemoFormatter::formatEditUpdate: $newValue");
        value = newValue;
        return newValue;
      }
    }
    

    Steps:

    1. Type something to the text field, for example, '1', you will get a log:
    DemoFormatter::formatEditUpdate: TextEditingValue(text: ┤1├, selection: TextSelection(baseOffset: 1, extentOffset: 1, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))
    
    1. Click on the clear button, you will get a log:
    Now controller.value is empty: TextEditingValue(text: ┤├, selection: TextSelection(baseOffset: 0, extentOffset: 0, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))
    But formatter.value is not: TextEditingValue(text: ┤1├, selection: TextSelection(baseOffset: 1, extentOffset: 1, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))
    
    Flutter doctor
    [√] Flutter (Channel stable, 2.2.0, on Microsoft Windows [Version 10.0.19041.1083], locale ru-RU)
        • Flutter version 2.2.0 at C:\Users\Qwin\fvm\versions\master
        • Framework revision 1b7e2ccf6a (3 months ago), 2021-04-06 13:07:18 +0300
        • Engine revision a9d88a4d18
        • Dart version 2.13.0
    
    [√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
        • Android SDK at P:\Applications\Android\SDK
        • Platform android-30, build-tools 30.0.3
        • ANDROID_HOME = P:\Applications\Android\SDK
        • Java binary at: C:\Applications\AndroidStudio\jre\bin\java
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
        • All Android licenses accepted.
    
    [√] Chrome - develop for the web
        • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
    
    [√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.5.2)
        • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
        • Visual Studio Community 2019 version 16.5.29926.136
        • Windows 10 SDK version 10.0.18362.0
    
    [√] Android Studio (version 4.1.0)
        • Android Studio at C:\Applications\AndroidStudio
        • Flutter plugin can be installed from:
           https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
           https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    
    [√] Connected device (4 available)
        • sdk gphone x86 (mobile) • emulator-5554 • android-x86    • Android 11 (API 30) (emulator)
        • Windows (desktop)       • windows       • windows-x64    • Microsoft Windows [Version 10.0.19041.1083]
        • Chrome (web)            • chrome        • web-javascript • Google Chrome 91.0.4472.124
        • Edge (web)              • edge          • web-javascript • Microsoft Edge 91.0.864.67
    
    • No issues found!
    
  4. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jul 14, 2021
  5. TahaTesser commented on Jul 15, 2021

    @TahaTesser
    Contributor

    Hi @siqwin
    Thanks for the details, I can confirm the issue

    stable master
    ❌ ❌

    Check flutter doctor -v outputs for each channel below

    flutter doctor -v
    [✓] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Version 10.0.22000.65], locale en-US)
        • Flutter version 2.2.3 at C:\Users\Taha\Code\flutter_stable
        • Framework revision f4abaa0735 (2 weeks ago), 2021-07-01 12:46:11 -0700
        • Engine revision 241c87ad80
        • Dart version 2.13.4
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
        • Android SDK at C:\Users\Taha\Code\android-sdk
        • Platform android-30, build-tools 30.0.3
        • ANDROID_SDK_ROOT = C:\Users\Taha\Code\android-sdk
        • Java binary at: C:\Users\Taha\Code\android-studio\jre\bin\java
        • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174)
        • All Android licenses accepted.
    
    [✓] Chrome - develop for the web
        • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
    
    [✓] Visual Studio - develop for Windows (Visual Studio Community 2019 16.10.3)
        • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
        • Visual Studio Community 2019 version 16.10.31424.327
        • Windows 10 SDK version 10.0.19041.0
    
    [!] Android Studio (not installed)
        • Android Studio not found; download from https://developer.android.com/studio/index.html
          (or visit https://flutter.dev/docs/get-started/install/windows#android-setup for detailed instructions).
    
    [✓] VS Code (version 1.58.1)
        • VS Code at C:\Users\Taha\AppData\Local\Programs\Microsoft VS Code
        • Flutter extension version 3.24.0
    
    [✓] Connected device (4 available)
        • Android SDK built for x86 (mobile) • emulator-5554 • android-x86    • Android 8.1.0 (API 27) (emulator)
        • Windows (desktop)                  • windows       • windows-x64    • Microsoft Windows [Version 10.0.22000.65]
        • Chrome (web)                       • chrome        • web-javascript • Google Chrome 91.0.4472.124
        • Edge (web)                         • edge          • web-javascript • Microsoft Edge 91.0.864.67
    
    ! Doctor found issues in 1 category.
    [✓] Flutter (Channel master, 2.4.0-5.0.pre.55, on Microsoft Windows [Version 10.0.22000.65], locale en-US)
        • Flutter version 2.4.0-5.0.pre.55 at C:\Users\Taha\Code\flutter_master
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision b549e829e8 (9 hours ago), 2021-07-14 15:51:10 -0700
        • Engine revision 093c4ed1a3
        • Dart version 2.14.0 (build 2.14.0-312.0.dev)
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
        • Android SDK at C:\Users\Taha\Code\android-sdk
        • Platform android-30, build-tools 30.0.3
        • ANDROID_SDK_ROOT = C:\Users\Taha\Code\android-sdk
        • Java binary at: C:\Users\Taha\Code\android-studio\jre\bin\java
        • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174)
        • All Android licenses accepted.
    
    [✓] Chrome - develop for the web
        • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe
    
    [✓] Visual Studio - develop for Windows (Visual Studio Community 2019 16.10.3)
        • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
        • Visual Studio Community 2019 version 16.10.31424.327
        • Windows 10 SDK version 10.0.19041.0
    
    [✓] Android Studio (version 4.2.0)
        • Android Studio at C:\Users\Taha\Code\android-studio
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6842174)
    
    [✓] VS Code (version 1.58.1)
        • VS Code at C:\Users\Taha\AppData\Local\Programs\Microsoft VS Code
        • Flutter extension version 3.24.0
    
    [✓] Connected device (5 available)
        • Android SDK built for x86 (mobile) • emulator-5554 • android-x86     • Android 8.1.0 (API 27) (emulator)
        • Windows (desktop)                  • windows       • windows-x64     • Microsoft Windows [Version 10.0.22000.65]
        • Windows (UWP) (desktop)            • winuwp        • windows-uwp-x64 •
        • Chrome (web)                       • chrome        • web-javascript  • Google Chrome 91.0.4472.124
        • Edge (web)                         • edge          • web-javascript  • Microsoft Edge 91.0.864.67
    
    • No issues found!

    ✅ : No Issue ❌: Issue reproduced

  6. added
    a: text inputEntering text in a text field or keyboard related problems
    frameworkflutter/packages/flutter repository. See also f: labels.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    on Jul 15, 2021
  7. added
    P2Important issues not at the top of the work list
    on Apr 13, 2022
  8. tirth-patel-nc commented on May 9, 2025

    @tirth-patel-nc
    Member

    Triage Report

    I was able to reproduce the issue using the provided code sample on both the stable (3.29.3) and master (3.32.0-1.0.pre.474) channels.

    Code Sample (Same as OP)
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() => runApp(MaterialApp(home: DemoPage()));
    
    class DemoPage extends StatefulWidget {
      DemoPage({Key? key}) : super(key: key);
    
      @override
      _DemoPageState createState() => _DemoPageState();
    }
    
    class _DemoPageState extends State<DemoPage> {
      final TextEditingController controller = TextEditingController();
      final DemoFormatter formatter = DemoFormatter();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: SafeArea(
            minimum: EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                TextFormField(
                  controller: controller,
                  decoration: InputDecoration(
                    hintText: "Enter something",
                    suffixIcon: ValueListenableBuilder<TextEditingValue>(
                      valueListenable: controller,
                      builder: (context, value, _) {
                        return Visibility(
                          visible: value.text.isNotEmpty,
                          child: IconButton(
                            icon: Icon(Icons.clear),
                            onPressed: () {
                              controller.clear();
                              print("Now controller.value is empty: ${controller.value}");
                              print("But formatter.value is not: ${formatter.value}");
                            },
                          ),
                        );
                      },
                    ),
                  ),
                  inputFormatters: [formatter],
                )
              ],
            ),
          ),
        );
      }
    }
    
    class DemoFormatter extends TextInputFormatter {
      TextEditingValue value = TextEditingValue.empty;
    
      @override
      TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
        print("DemoFormatter::formatEditUpdate: $newValue");
        value = newValue;
        return newValue;
      }
    }
    Log After Typing `1`
    I/flutter (16621): DemoFormatter::formatEditUpdate: TextEditingValue(text: ┤1├, selection: TextSelection.collapsed(offset: 1, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))
    
    Log Clicking Clear `X`
    I/flutter (16621): Now controller.value is empty: TextEditingValue(text: ┤├, selection: TextSelection.collapsed(offset: 0, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))
    I/flutter (16621): But formatter.value is not: TextEditingValue(text: ┤1├, selection: TextSelection.collapsed(offset: 1, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))
    
    stable (3.29.3) - flutter doctor -v
    [✓] Flutter (Channel stable, 3.29.3, on macOS 15.4.1 24E263 darwin-arm64, locale
        en-IN) [970ms]
        • Flutter version 3.29.3 on channel stable at
          /Users/tirthpatel/Development/flutter_stable/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision ea121f8859 (4 weeks ago), 2025-04-11 19:10:07 +0000
        • Engine revision cf56914b32
        • Dart version 3.7.2
        • DevTools version 2.42.3
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
        [855ms]
        • Android SDK at /Users/tirthpatel/Library/Android/sdk
        • Platform android-36, build-tools 36.0.0
        • Java binary at: /Applications/Android
          Studio.app/Contents/jbr/Contents/Home/bin/java
          This is the JDK bundled with the latest Android Studio installation on
          this machine.
          To manually set the JDK path, use: `flutter config
          --jdk-dir="path/to/jdk"`.
        • Java version OpenJDK Runtime Environment (build 21.0.6+-13355223-b631.42)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 16.3) [556ms]
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 16E140
        • CocoaPods version 1.16.2
    
    [✓] Chrome - develop for the web [9ms]
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2024.3) [9ms]
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 21.0.6+-13355223-b631.42)
    
    [✓] VS Code (version 1.99.3) [8ms]
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension can be installed from:
          🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
    
    [✓] Connected device (3 available) [5.5s]
        • macOS (desktop)                 • macos                 • darwin-arm64   •
          macOS 15.4.1 24E263 darwin-arm64
        • Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin         •
          macOS 15.4.1 24E263 darwin-arm64
        • Chrome (web)                    • chrome                • web-javascript •
          Google Chrome 135.0.7049.115
    
    [✓] Network resources [559ms]
        • All expected network resources are available.
    
    • No issues found!
    
    master (3.32.0-1.0.pre.474) - flutter doctor -v
    [✓] Flutter (Channel master, 3.32.0-1.0.pre.474, on macOS 15.4.1 24E263 darwin-arm64, locale en-IN) [1,380ms]
        • Flutter version 3.32.0-1.0.pre.474 on channel master at /Users/tirthpatel/Development/flutter_master/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 83082c19b7 (6 hours ago), 2025-05-08 15:54:18 -0700
        • Engine revision 83082c19b7
        • Dart version 3.9.0 (build 3.9.0-100.2.beta)
        • DevTools version 2.46.0
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0) [761ms]
        • Android SDK at /Users/tirthpatel/Library/Android/sdk
        • Emulator version 35.4.9.0 (build_id 13025442) (CL:N/A)
        • Platform android-36, build-tools 36.0.0
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
          This is the JDK bundled with the latest Android Studio installation on this machine.
          To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version OpenJDK Runtime Environment (build 21.0.6+-13355223-b631.42)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 16.3) [428ms]
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 16E140
        • CocoaPods version 1.16.2
    
    [✓] Chrome - develop for the web [7ms]
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2024.3) [7ms]
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 21.0.6+-13355223-b631.42)
    
    [✓] VS Code (version 1.99.3) [6ms]
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.110.0
    
    [✓] Connected device (2 available) [5.5s]
        • macOS (desktop) • macos  • darwin-arm64   • macOS 15.4.1 24E263 darwin-arm64
        • Chrome (web)    • chrome • web-javascript • Google Chrome 136.0.7103.93
    
    [✓] Network resources [599ms]
        • All expected network resources are available.
    
    • No issues found!
    
  9. LongCatIsLooong commented on Jul 7, 2026

    @LongCatIsLooong
    Contributor

    I believe this is intended and documented (but only on EditableText?). Formatters only runs on user input (e.g., via the onscreen keyboard or a physical keyboard), programmatical changes do not trigger the formatter. The behavior is a bit strange because the TextEditingController.clear call can be triggered by a user input (e.g., clicking the "clear" button).

  10. binSaed commented on Jul 28, 2026

    @binSaed
    Contributor

    I've opened a PR for this: #190166. It adds a note to TextEditingController.clear() clarifying that TextInputFormatters are not invoked on programmatic changes.

  11. github-actions commented on Sep 4, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  12. locked as resolved and limited conversation to collaborators on Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: text inputEntering text in a text field or keyboard related problemsd: api docsIssues with https://api.flutter.dev/found in release: 3.29Found to occur in 3.29found in release: 3.32Found to occur in 3.32frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions