Flutter Formatting – How to Format User Input Double in TextField as and When Being Entered?

flutterformattingintl

I'm trying to display the user input double (may be without decimal dot and that follows) number as a formatted value e.g. 123456789012.1234 as 12345,67,89,012.1234 using not the western numbering system, but using Indian Subcontinent numbering system as shown. Preferably, no commas after crore.

With the intl package, I could display formatted output, but I also need to format the input being entered by the user in the text input filed. And this I could not manage to get working.

The minimal code:

I've written the following minimal code to show my problem. Here, as I enter 123 an then 4 a comma appears at the correct place (i.e. 1,234) but then when I enter the fifth digit i.e. 5 in succession, only 0 is displayed which is erroneous.

How can I fix this?

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

final _controller = TextEditingController();

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('intl Formatter With Formatted Text Field'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(20.0),
          child: TextField(
            controller: _controller,
            keyboardType: TextInputType.number,
            onChanged: (value) {
              NumberFormat numberFormat = NumberFormat("#,##,##,###.########");
              final formattedValue =
                  numberFormat.format(double.tryParse(value) ?? 0.0);
              _controller.value = TextEditingValue(
                text: formattedValue,
              );
            },
          ),
        ),
      ),
    );
  }
}

Best Answer

The issue with your current code is that the value contains a comma (,) after entering 1234. When entering the next character (e.g. 5) 1,2345 is passed to double.tryParse which fails to parse the value, because it contains a comma and the parser only respects dots (.) for separating decimal places.

One option to circumvent this is to remove all commas before passing the value to double.tryParse, like so:

value = value.replaceAll(",", "");

Here is dart.dev sample.