Reputation: 5025
In a TextField
I have a initial text 0.00
then how can I format the typed value once the user start typing in Flutter? I'm currently usig the flutter_money_formatter package but I can't get the expected behaviour.
For example, I want the following behaviour if user types the number: 1.800.45
:
When the user taps 1. We should have 0.01
When the user taps 8. We should display 0.18
When the user taps 0. We should display 1.80
When the user taps 0. We should display 1.800
When the user taps 4. We should display 1.800,4
When the user taps 5. We should display 1.800,45
.
My current code:
class _MoneyTextFormField extends StatelessWidget {
TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return TextFormField(
controller: _controller,
style: TextStyle(color: context.primaryColor),
keyboardType: TextInputType.number,
inputFormatters: [
TextInputFormatter.withFunction((oldValue, newValue) {
// remove characters to convert the value to double (because one of those may appear in the keyboard)
String newText = newValue.text.replaceAll(MoneyTextFormField._cents, '')
.replaceAll('.', '')
.replaceAll(',', '')
.replaceAll('_', '')
.replaceAll('-', '');
String value = newText;
int cursorPosition = newText.length;
if (newText.isNotEmpty) {
value = formatCurrency(double.parse(newText), fractionDigits: 0);
cursorPosition = value.length;
}
return TextEditingValue(
text: value,
selection: TextSelection.collapsed(offset: cursorPosition)
);
}),
],
);
}
}
The function to format the value:
/// Format the giving value and return the value as String
/// Note: the parameter should be a int or double
static String formatCurrency(num value,{int fractionDigits = 2}) {
ArgumentError.checkNotNull(value, 'value');
return FlutterMoneyFormatter(
amount: value.toDouble(),
settings: MoneyFormatterSettings(
thousandSeparator: '.',
decimalSeparator: ',',
fractionDigits: fractionDigits
),
).output.nonSymbol;
}
Note: this is not a duplicate of this one because the solution does not work for Flutter.
Upvotes: 6
Views: 8555
Reputation: 929
Here an implementation using TextField and the solution from Pedro to divide value by 100 before format
TextField(
autofillHints: null,
keyboardType: TextInputType.number,
controller: controller.expenseValueInputController,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
onChanged: (String textValue) {
var valueNumber = double.parse(textValue.replaceAll(RegExp(r"\D"), "")) / 100;
var fomattedValue = NumberFormat("#,##0.00", "en_US").format(valueNumber);
controller.expenseValueInputController.value = TextEditingValue(
text: fomattedValue,
selection: TextSelection.collapsed(offset: fomattedValue.length),
);
}
)
Upvotes: 0
Reputation: 1
$`import 'package:intl/intl.dart';`
onChange: (value) {
setState(() {
value = NumberFormat.currency(
name: "", decimalDigits: 0)
.format(int.parse(value));
_price.value = TextEditingValue(
text: value,
selection: TextSelection.collapsed(
offset: value.length),
);
});
}
Upvotes: -1
Reputation: 19514
You can use this way.
bool isFirst = true;
TextFormField(
controller: addAmountController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
onChanged: (value) {
String newValue = value.replaceAll(',', '').replaceAll('.', '');
if (value.isEmpty || newValue == '00') {
addAmountController.clear();
isFirst = true;
return;
}
double value1 = double.parse(newValue);
if (!isFirst) value1 = value1 * 100;
value = NumberFormat.currency(customPattern: '###,###.##').format(value1 / 100);
addAmountController.value = TextEditingValue(
text: value,
selection: TextSelection.collapsed(offset: value.length),
);
},
)
Upvotes: 5
Reputation: 5025
I just found the solution for this using the Intl package. Just use the formatCurrency
method bellow and everything will be fixed.
Note: The value should always be in cents. That is why we divide it by 100 to give us the cents and pass the result into the formatter.
static String formatCurrency(num value,{int fractionDigits = 2}) {
ArgumentError.checkNotNull(value, 'value');
// convert cents into hundreds.
value = value / 100;
return NumberFormat.currency(
customPattern: '###,###.##',
// using Netherlands because this country also
// uses the comma for thousands and dot for decimal separators.
locale: 'nl_NL'
).format(value);
}
Upvotes: 3