diff --git a/example/lib/main.dart b/example/lib/main.dart index 70de86f..6dbb3a5 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -41,9 +41,10 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), child: TextField( decoration: InputDecoration( - border: OutlineInputBorder(), - isDense: true, - labelText: 'Integer Number'), + border: OutlineInputBorder(), + isDense: true, + labelText: 'Integer Number', + ), keyboardType: TextInputType.number, inputFormatters: [ LengthLimitingTextInputFormatter(15), @@ -56,9 +57,10 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), child: TextField( decoration: InputDecoration( - border: OutlineInputBorder(), - isDense: true, - labelText: 'Decimal Number'), + border: OutlineInputBorder(), + isDense: true, + labelText: 'Decimal Number', + ), keyboardType: TextInputType.number, inputFormatters: [ LengthLimitingTextInputFormatter(15), @@ -71,9 +73,10 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), child: TextField( decoration: InputDecoration( - border: OutlineInputBorder(), - isDense: true, - labelText: 'Card Number'), + border: OutlineInputBorder(), + isDense: true, + labelText: 'Card Number', + ), keyboardType: TextInputType.number, inputFormatters: [ LengthLimitingTextInputFormatter(19), @@ -86,9 +89,10 @@ class MyHomePage extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), child: TextField( decoration: InputDecoration( - border: OutlineInputBorder(), - isDense: true, - hintText: 'dd/MM/yyyy'), + border: OutlineInputBorder(), + isDense: true, + hintText: 'dd/MM/yyyy', + ), keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'\d+|-|/')), @@ -96,7 +100,25 @@ class MyHomePage extends StatelessWidget { ], style: TextStyle(fontSize: 16.0, color: Colors.black), ), - ) + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0), + child: TextField( + decoration: InputDecoration( + border: OutlineInputBorder(), + isDense: true, + labelText: 'Currency Number Format', + ), + keyboardType: TextInputType.number, + inputFormatters: [ + CurrencyFormatter( + locale: 'de_DE', // locale of country + symbol: '€', // symbol beside value + ), + ], + style: TextStyle(fontSize: 16.0, color: Colors.black), + ), + ), ], ), ), diff --git a/lib/currency_formatter.dart b/lib/currency_formatter.dart new file mode 100644 index 0000000..804c5d3 --- /dev/null +++ b/lib/currency_formatter.dart @@ -0,0 +1,74 @@ +import 'dart:math'; + +import 'package:flutter/services.dart'; +import 'package:intl/intl.dart'; + +class CurrencyFormatter extends TextInputFormatter { + CurrencyFormatter({ + this.locale, + this.name, + this.symbol, + this.isGrouped = false, + }); + + final String? locale; + final String? name; + final String? symbol; + final bool isGrouped; + + @override + TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { + final isInserted = oldValue.text.length + 1 == newValue.text.length && newValue.text.startsWith(oldValue.text); + final isRemoved = oldValue.text.length - 1 == newValue.text.length && oldValue.text.startsWith(newValue.text); + + if (!isInserted && !isRemoved) { + return oldValue; + } + + final format = NumberFormat.currency( + locale: locale, + name: name, + symbol: symbol, + ); + + if (isGrouped) { + format.turnOffGrouping(); + } + + final isNegativeValue = newValue.text.startsWith('-'); + var newText = newValue.text.replaceAll(RegExp('[^0-9]'), ''); + + if (isRemoved && !_lastCharacterIsDigit(oldValue.text)) { + final length = newText.length - 1; + newText = newText.substring(0, length > 0 ? length : 0); + } + + if (newText.trim() == '') { + return newValue.copyWith( + text: isNegativeValue ? '-' : '', + selection: TextSelection.collapsed(offset: isNegativeValue ? 1 : 0), + ); + } else if (newText == '00' || newText == '000') { + return TextEditingValue( + text: isNegativeValue ? '-' : '', + selection: TextSelection.collapsed(offset: isNegativeValue ? 1 : 0), + ); + } + + num newInt = int.parse(newText); + if (format.decimalDigits! > 0) { + newInt /= pow(10, format.decimalDigits!); + } + + final newString = (isNegativeValue ? '-' : '') + format.format(newInt).trim(); + return TextEditingValue( + text: newString, + selection: TextSelection.collapsed(offset: newString.length), + ); + } + + static bool _lastCharacterIsDigit(String text) { + final lastChar = text.substring(text.length - 1); + return RegExp('[0-9]').hasMatch(lastChar); + } +} diff --git a/lib/pattern_formatter.dart b/lib/pattern_formatter.dart index 089b774..212908e 100644 --- a/lib/pattern_formatter.dart +++ b/lib/pattern_formatter.dart @@ -2,3 +2,4 @@ library pattern_input_formatter; export 'numeric_formatter.dart'; export 'date_formatter.dart'; +export 'currency_formatter.dart';