formatEditUpdate method
- TextEditingValue oldValue,
- TextEditingValue newValue
override
Called when text is being typed or cut/copy/pasted in the EditableText.
You can override the resulting text based on the previous text value and the incoming new text value.
When formatters are chained, oldValue
reflects the initial value of
TextEditingValue at the beginning of the chain.
Implementation
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
locale ??= platformLocaleCode;
var form = NumberFormat.decimalPattern(locale);
decimalDigits ??= form.decimalDigits ?? 4;
var simb = form.symbols;
var decimalSeparator = simb.DECIMAL_SEP;
var minusSign = simb.MINUS_SIGN;
var percentSign = simb.PERCENT;
String formattedValue = "";
string newValueText = newValue.text.trimAll;
// Remove any non-digit characters
for (int i = 0; i < newValueText.length; i++) {
var e = newValueText.charAt(i);
if (i == 0 && (e == minusSign)) {
formattedValue += e;
continue;
}
if (e.isNumber) {
formattedValue += e;
continue;
}
if (e == decimalSeparator && !formattedValue.contains(decimalSeparator)) {
formattedValue += e;
continue;
}
if (e == percentSign && i == newValueText.length - 1) {
formattedValue += e;
continue;
}
}
// Check if the first character is a plus or minus sign
bool isNegative = false;
if (formattedValue.isNotEmpty && (formattedValue[0] == minusSign)) {
isNegative = formattedValue[0] == minusSign;
formattedValue = formattedValue.substring(1);
}
// Check if the last character is a percent sign
bool hasPercentSign = false;
if (formattedValue.isNotEmpty && formattedValue[formattedValue.length - 1] == percentSign) {
hasPercentSign = true;
formattedValue = formattedValue.substring(0, formattedValue.length - 1);
}
// Check if the newText contains a decimal separator
bool hasDecimalSeparator = formattedValue.contains(decimalSeparator);
// Split the newText into integer and decimal parts
List<String> parts = formattedValue.split(decimalSeparator);
String integerPart = parts[0];
String decimalPart = (parts.length > 1 ? parts[1] : '').first(decimalDigits!);
// Format the integer part
formattedValue = NumberFormat.decimalPattern(locale).format(int.parse(integerPart));
// Add the decimal separator and decimal part if necessary
if (hasDecimalSeparator) {
formattedValue += '$decimalSeparator$decimalPart';
}
// Add the percent sign if necessary
if (hasPercentSign) {
if (calculateDecimal) {
formattedValue = (double.parse(formattedValue.removeAny([percentSign])) / 100).toStringAsFixed(decimalDigits!);
} else {
formattedValue += percentSign;
}
}
// Add the plus or minus sign if necessary
if (isNegative) {
formattedValue = '$minusSign$formattedValue';
}
return TextEditingValue(
text: formattedValue,
selection: TextSelection.collapsed(offset: (formattedValue.contains(percentSign) ? formattedValue.indexOf(percentSign) - 1 : formattedValue.length).clamp(0, formattedValue.length - 1)),
);
}