import 'package:flutter/services.dart'; class RupiahInputFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue) { if (newValue.text.isEmpty) { return newValue; } final digits = newValue.text.replaceAll(RegExp(r'[^0-9]'), ''); if (digits.isEmpty) { return const TextEditingValue(text: ''); } final formatted = _formatRupiah(digits); int newOffset = formatted.length; if (oldValue.text.isNotEmpty) { final oldLength = oldValue.text.replaceAll(RegExp(r'[^0-9]'), '').length; final newLength = digits.length; final oldCursor = oldValue.selection.baseOffset; if (newLength < oldLength) { final digitsBeforeCursor = oldValue.text.substring(0, oldCursor).replaceAll(RegExp(r'[^0-9]'), '').length; newOffset = (digitsBeforeCursor).clamp(0, formatted.length); } else if (oldCursor < oldValue.text.length) { final digitsBeforeCursor = oldValue.text.substring(0, oldCursor).replaceAll(RegExp(r'[^0-9]'), '').length; newOffset = (digitsBeforeCursor).clamp(0, formatted.length); } } return TextEditingValue( text: formatted, selection: TextSelection.collapsed(offset: newOffset), ); } String _formatRupiah(String digits) { final buffer = StringBuffer(); final len = digits.length; for (int i = 0; i < len; i++) { if (i > 0 && (len - i) % 3 == 0) { buffer.write('.'); } buffer.write(digits[i]); } return buffer.toString(); } static String formatNumber(int number) { return RupiahInputFormatter()._formatRupiah(number.toString()); } static int? getRawValue(String formattedText) { final digits = formattedText.replaceAll(RegExp(r'[^0-9]'), ''); if (digits.isEmpty) return null; return int.tryParse(digits); } }