formatEditUpdate method
Implementation
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
// print('old: ${oldValue.toJSON()}');
// print('new: ${newValue.toJSON()}');
int signals = RegExp('-').allMatches(newValue.text).length;
bool isNegative = oldValue.text.startsWith('-');
bool delNegative = false;
if (isNegative && signals != 1) {
isNegative = false;
delNegative = true;
}
if (!isNegative && signals == 1) {
isNegative = true;
}
String newText = newValue.text.replaceAll('-', '');
/// Empty value
if (newText.isEmpty ||
newText == decimalSeparator ||
newText == thousandSeparator) {
// print('New value is empty or equals to "$decimalSeparator" '
// 'or equals to "$thousandSeparator"');
// print('\n');
return TextEditingValue(
text: '${isNegative ? '-0' : '0'}$decimalSeparator'
.padRight(precision + (isNegative ? 3 : 2), '0'),
selection: TextSelection.collapsed(offset: (isNegative ? 2 : 1)),
);
}
/// Char not allowed.
if (allow.allMatches(newText).length != newText.length) {
// print('Char not allowed.');
// print('\n');
return oldValue;
}
int oldDecimalCount = oldValue.text.split(decimalSeparator).length;
int oldThousandCount = oldValue.text.split(thousandSeparator).length;
int newDecimalCount = newText.split(decimalSeparator).length;
int newThousandCount = newText.split(thousandSeparator).length;
if (oldDecimalCount < newDecimalCount ||
oldThousandCount < newThousandCount) {
int curPos = oldValue.text.indexOf(decimalSeparator) + 1;
// print('curPos: $curPos');
if (newValue.selection.baseOffset <= curPos) {
Map<String, dynamic> oldValueJson = oldValue.toJSON();
oldValueJson['selectionBase'] = curPos;
oldValueJson['selectionExtent'] = curPos;
// print('\n');
return TextEditingValue.fromJSON(oldValueJson);
}
// print('\n');
return oldValue;
}
/// Decimal Part
if (newText.contains(decimalSeparator)) {
List<String> parts = newText.split(decimalSeparator);
// print('Integer Part: ${parts.first}');
// print('Decimal Part: ${parts.last}');
String decimalPart = parts.last;
decimalPart = decimalPart.length > precision
? decimalPart.substring(0, precision)
: decimalPart.padRight(precision, '0');
newText = '${parts.first}$decimalSeparator$decimalPart';
} else {
if (newText.length == 1) {
newText += decimalSeparator.padRight(precision + 1, '0');
} else {
int pos = newText.length - precision;
newText = newText.substring(0, pos) +
decimalSeparator +
newText.substring(pos);
}
}
int firstLength = newText.length;
/// Integer Part
List<String> parts = newText.split(decimalSeparator);
int integerPart =
int.tryParse(parts.first.replaceAll(thousandSeparator, '')) ?? 0;
List<String> numbers = integerPart.toString().split('').reversed.toList();
for (int pos = 3; pos < numbers.length; pos += 4) {
numbers.insert(pos, thousandSeparator);
}
newText = numbers.reversed.join() + decimalSeparator + parts.last;
/// Cursor Positioning
int newTextLength = newText.length;
int newPos = newValue.selection.baseOffset;
// print('newPos: $newPos');
newPos += newTextLength - firstLength;
// print('delta: ${newTextLength - firstLength}');
if (delNegative) {
newPos -= 2;
}
if (newPos < 1) {
newPos = 0;
}
newText = (isNegative ? '-' : '') + newText;
if (newPos > newText.length) {
newPos = newText.length;
}
Map<String, dynamic> newValueJson = newValue.toJSON();
newValueJson['text'] = newText;
newValueJson['selectionBase'] = newPos;
newValueJson['selectionExtent'] = newPos;
// print('newValueJson: $newValueJson');
// print('\n');
return TextEditingValue.fromJSON(newValueJson);
}