flutter_pattern_formatter icon indicating copy to clipboard operation
flutter_pattern_formatter copied to clipboard

Does not allow entering 0 in the decimal section

Open Sun3 opened this issue 5 years ago • 7 comments

When using the ThousandsFormatter(allowFraction: true) and you try to enter a zero in the decimal section it does not allow it.

Does not allow the following zeros in the decimal section:

3,500.01
3,500.10

Any thoughts to make it work? Thank you

Sun3 avatar Aug 15 '20 02:08 Sun3

Checking to see if this is something that will be fixed, it's a major issue.

Thank you.

Sun3 avatar Aug 28 '20 04:08 Sun3

I have narrowed down where it's causing the .0 or .10 not to show up but is removed when typing it:

When you enter a number 1,500.0 the double.tryParse(decimalDigits) removes the .0 as you are typing, making it impossible to enter decimals that start with a 0. This is common in the financial world like 1,500.0125.

Also when you enter a number 1,500.10 the double.tryParse(decimalDigits) removes the 0 after the .10 making it impossible to enter decimals that have zeros 0 after a digit in the decimal section. This is also common in the financial world like 1,500.1045.

Code that is causing the issue:

  @override
  String _formatPattern(String digits) {
    if (digits == null || digits.isEmpty) return digits;
    num number;
    if (allowFraction) {
      String decimalDigits = digits;
      if (_decimalSeparator != '.') {
        decimalDigits = digits.replaceFirst(RegExp(_decimalSeparator), '.');
      }
      // THIS CAUSES THE ISSUE
      number = double.tryParse(decimalDigits) ?? 0.0;
    } else {
      number = int.tryParse(digits) ?? 0;
    }
    final result = (formatter ?? _formatter).format(number);
    if (allowFraction && digits.endsWith(_decimalSeparator)) {
      return '$result$_decimalSeparator';
    }
    return result;
  }

Thank you and I hope this helps to solve this issue.

Sun3 avatar Aug 31 '20 22:08 Sun3

Checking to see if there is any news on this issue. I am wondering if this package is not going to be updated.

Thank you.

Sun3 avatar Sep 14 '20 21:09 Sun3

If anyone is interested in a quick fix I have placed my solution:

// Fix the .0 or .01 or .10 and similar issues
if (digits.contains('.')) {
  List<String> decimalPlacesValue = digits.split(".");
  String decimalOnly = decimalPlacesValue[1];
  double digitsOnly = double.tryParse(decimalPlacesValue[0]);
  String result = (formatter ?? _formatter).format(digitsOnly);
  result = result + '.' + '$decimalOnly';
  return result;
}

The full code for the ThousandsFormatter class:

class ThousandsFormatter extends NumberInputFormatter {
  static final NumberFormat _formatter = NumberFormat.decimalPattern();

  final FilteringTextInputFormatter _decimalFormatter;
  final String _decimalSeparator;
  final RegExp _decimalRegex;

  final NumberFormat formatter;
  final bool allowFraction;

  ThousandsFormatter({this.formatter, this.allowFraction = false})
      : _decimalSeparator = (formatter ?? _formatter).symbols.DECIMAL_SEP,
        _decimalRegex = RegExp(allowFraction
            ? '[0-9]+([${(formatter ?? _formatter).symbols.DECIMAL_SEP}])?'
            : r'\d+'),
        _decimalFormatter = FilteringTextInputFormatter.allow(RegExp(allowFraction
            ? '[0-9]+([${(formatter ?? _formatter).symbols.DECIMAL_SEP}])?'
            : r'\d+'));

  @override
  String _formatPattern(String digits) {
    if (digits == null || digits.isEmpty) return digits;
    num number;
    if (allowFraction) {
      String decimalDigits = digits;
      if (_decimalSeparator != '.') {
        decimalDigits = digits.replaceFirst(RegExp(_decimalSeparator), '.');
      }
      number = double.tryParse(decimalDigits) ?? 0.0;
    } else {
      number = int.tryParse(digits) ?? 0;
    }
    final result = (formatter ?? _formatter).format(number);
    if (allowFraction && digits.endsWith(_decimalSeparator)) {
      return '$result$_decimalSeparator';
    }

    // Fix the .0 or .01 or .10 and similar issues
    if (digits.contains('.')) {
      List<String> decimalPlacesValue = digits.split(".");
      String decimalOnly = decimalPlacesValue[1];
      double digitsOnly = double.tryParse(decimalPlacesValue[0]);
      String result = (formatter ?? _formatter).format(digitsOnly);
      result = result + '.' + '$decimalOnly';
      return result;
    }
    return result;
  }

  @override
  TextEditingValue _formatValue(
      TextEditingValue oldValue, TextEditingValue newValue) {
    return _decimalFormatter.formatEditUpdate(oldValue, newValue);
  }

  @override
  bool _isUserInput(String s) {
    return s == _decimalSeparator || _decimalRegex.firstMatch(s) != null;
  }
}

I hope this helps anyone else having the same issue.

Sun3 avatar Sep 15 '20 22:09 Sun3

i hope the author will update this. seems to be ignored

chitgoks avatar Apr 15 '21 10:04 chitgoks

If anyone is interested in a quick fix I have placed my solution:

// Fix the .0 or .01 or .10 and similar issues
if (digits.contains('.')) {
  List<String> decimalPlacesValue = digits.split(".");
  String decimalOnly = decimalPlacesValue[1];
  double digitsOnly = double.tryParse(decimalPlacesValue[0]);
  String result = (formatter ?? _formatter).format(digitsOnly);
  result = result + '.' + '$decimalOnly';
  return result;
}

The full code for the ThousandsFormatter class:

class ThousandsFormatter extends NumberInputFormatter {
  static final NumberFormat _formatter = NumberFormat.decimalPattern();

  final FilteringTextInputFormatter _decimalFormatter;
  final String _decimalSeparator;
  final RegExp _decimalRegex;

  final NumberFormat formatter;
  final bool allowFraction;

  ThousandsFormatter({this.formatter, this.allowFraction = false})
      : _decimalSeparator = (formatter ?? _formatter).symbols.DECIMAL_SEP,
        _decimalRegex = RegExp(allowFraction
            ? '[0-9]+([${(formatter ?? _formatter).symbols.DECIMAL_SEP}])?'
            : r'\d+'),
        _decimalFormatter = FilteringTextInputFormatter.allow(RegExp(allowFraction
            ? '[0-9]+([${(formatter ?? _formatter).symbols.DECIMAL_SEP}])?'
            : r'\d+'));

  @override
  String _formatPattern(String digits) {
    if (digits == null || digits.isEmpty) return digits;
    num number;
    if (allowFraction) {
      String decimalDigits = digits;
      if (_decimalSeparator != '.') {
        decimalDigits = digits.replaceFirst(RegExp(_decimalSeparator), '.');
      }
      number = double.tryParse(decimalDigits) ?? 0.0;
    } else {
      number = int.tryParse(digits) ?? 0;
    }
    final result = (formatter ?? _formatter).format(number);
    if (allowFraction && digits.endsWith(_decimalSeparator)) {
      return '$result$_decimalSeparator';
    }

    // Fix the .0 or .01 or .10 and similar issues
    if (digits.contains('.')) {
      List<String> decimalPlacesValue = digits.split(".");
      String decimalOnly = decimalPlacesValue[1];
      double digitsOnly = double.tryParse(decimalPlacesValue[0]);
      String result = (formatter ?? _formatter).format(digitsOnly);
      result = result + '.' + '$decimalOnly';
      return result;
    }
    return result;
  }

  @override
  TextEditingValue _formatValue(
      TextEditingValue oldValue, TextEditingValue newValue) {
    return _decimalFormatter.formatEditUpdate(oldValue, newValue);
  }

  @override
  bool _isUserInput(String s) {
    return s == _decimalSeparator || _decimalRegex.firstMatch(s) != null;
  }
}

I hope this helps anyone else having the same issue.

Rahhh!! Thank you so much for this fix!

shabeenabarde avatar Jun 28 '21 17:06 shabeenabarde

@Sun3 Thank you! I was having the same issue, that fixed it. Hopefully it gets fixed on the main repo but the issue seems to be ignored :/

FranLMSP avatar Nov 17 '21 01:11 FranLMSP