I want have a TextFormField
that formats the input depending on a given separator
and interval
.
E.g. separator = '-'
and interval = 4
the output should be the following:
Input: 1234 Output: 1234
Input 12345678 Output: 1234-5678
Input: 12345678910 Output: 1234-5678-910
The separator should be inserted right when the user types in the 5th character in this example.
I tried multiple things now, but can not get a general working solution. That was my last try:
void _addSeperator(String value) {
final separator = widget.separator!;
final separatorInterval = widget.separatorInterval!;
value = value.replaceAll(separator, ''); // Remove existing separators
int length = value.length;
int separatorCount = (length / separatorInterval).floor();
for (int i = 1; i <= separatorCount; i++) {
int index = i * separatorInterval +
(i - 1); // Calculate the index to insert separator
if (index < length) {
value = value.substring(0, index) +
separator +
value.substring(index, value.length);
}
}
_controller.text = value;
}
I thought this shouldnt be that hard, but I can not make it work. Also didn't find anything on this. Let me know if you need more info.
I got it working with this:
class UISeparatorInputFormatOptions {
final String separator;
final int interval;
UISeparatorInputFormatOptions({
required this.separator,
required this.interval,
});
}
class UISeparatorInputFormatter extends TextInputFormatter {
/// IMPORTANT: String must not contain the options.separator
/// otherwise this InputFormatter will not work correctly.
final UISeparatorInputFormatOptions options;
UISeparatorInputFormatter({
required this.options,
});
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
// Remove existing separators
String newText = newValue.text.replaceAll(
options.separator,
'',
);
StringBuffer buffer = StringBuffer();
for (int i = 0; i < newText.length; i++) {
if (i > 0 && i % options.interval == 0) {
buffer.write(options.separator);
}
buffer.write(newText[i]);
}
String formattedString = buffer.toString();
return newValue.copyWith(
text: formattedString,
// This ensures that the cursor follows the text properly
selection: TextSelection.collapsed(offset: formattedString.length),
);
}
}