Home > Mobile >  Formatting digits with comma separator in the TextField while typing
Formatting digits with comma separator in the TextField while typing

Time:01-29

I want to use a comma separator in Flutter to format numbers in this format while typing: "#,##,##,###.##" but I don't want to include decimal places unless we type. The ThousandsFormatter class is formatting digits as expected, however, it is not allowing decimal input. I want to allow up to two decimal inputs when necessary without affecting the number formattings.

Here are some more examples of number formattings that I want with my code: 1,00,00,000 15,000.34 23,12,340.45, 45,434.5, 55,334 and so on. The digit inputs without decimals are working correctly.

It also has an another issue with comma. It adds the counting of comma to the maxLength of TextField input. Therefore to enter eight digits, I have set the maxLength to eleven.

Any suggestions would be appreciated. Here is the code I have tried:

class ThousandsFormatter:

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

    class ThousandsFormatter extends TextInputFormatter {
    @override
    TextEditingValue formatEditUpdate(
    TextEditingValue oldValue, TextEditingValue newValue) {
    final newText = newValue.text;
    if (newText.isEmpty) {
      return newValue;
    }
    int selectionIndex = newValue.selection.end;
    final String newTextFormatted = NumberFormat("#,##,##,###")
        .format(double.tryParse(newText.replaceAll(",", "")));
    if (newText == newTextFormatted) {
      return newValue;
    }
    selectionIndex  = -(newText.length - newTextFormatted.length);
    return TextEditingValue(
      text: newTextFormatted,
      selection: TextSelection.collapsed(offset: selectionIndex),
        );
      }
    }
 

main.dart

    TextField(
    onEditingComplete: () {
    FocusScope.of(context).requestFocus(_focusNodeY);
    },
    controller: principalController,
    decoration: InputDecoration(
    labelText: "Amount",
    isDense: true,
    counterText: "",     
    ),
    textAlign: TextAlign.start,
    maxLines: 1,
    maxLength: 11,
    keyboardType: TextInputType.number,
    inputFormatters: [
    FilteringTextInputFormatter.digitsOnly,
    FilteringTextInputFormatter.allow(
    RegExp(r'^[0-9] (\.[0-9]{0,2})?$')),
    ThousandsFormatter(),
    ],
    ),

CodePudding user response:

Based on the code you've provided, it looks like you're using the ThousandsFormatter class to format the input as a number with thousands separators, but you're also using the FilteringTextInputFormatter class to allow only digits and up to two decimal places.

To allow decimal places without affecting the formatting of the thousands separator, you could modify the ThousandsFormatter class to check if the input includes a decimal point, and if it does, format the number up to the decimal point and leave the decimal places as-is. For example:

class ThousandsFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue, TextEditingValue newValue) {
    final newText = newValue.text;
    if (newText.isEmpty) {
      return newValue;
    }
    int selectionIndex = newValue.selection.end;
    String newTextFormatted;
    if (newText.contains('.')) {
      final parts = newText.split('.');
      newTextFormatted = NumberFormat("#,##,##,###").format(double.tryParse(parts[0].replaceAll(",", "")))   '.'   parts[1];
    } else {
      newTextFormatted = NumberFormat("#,##,##,###").format(double.tryParse(newText.replaceAll(",", "")));
    }
    if (newText == newTextFormatted) {
      return newValue;
    }
    selectionIndex  = -(newText.length - newTextFormatted.length);
    return TextEditingValue(
      text: newTextFormatted,
      selection: TextSelection.collapsed(offset: selectionIndex),
    );
  }
}

This way, if the input includes a decimal point, it will format the number up to the decimal point and leave the decimal places as-is, and if it doesn't, it will format the entire number with thousands separators.

Regarding the maxLength of the TextField, you could remove the ThousandsFormatter from the list of inputFormatters when you are calculating the maxLength of TextField.

CodePudding user response:

Try this

var f = NumberFormat("#,##,##,###.##", "en_US");
        print(f.format(18));
        print(f.format(180000.00));
  • Related