import 'package:flutter/services.dart';
class CurrencyFormatter extends TextInputFormatter {
// adding money separator (like point)
RegExp pointingString(int modulreResult) =>
RegExp('(?<=.{${modulreResult == 0 ? 3 : modulreResult}}).{3}');
// checkking string money format
RegExp firstNotZeroRegex(String pointCurrency) =>
RegExp(r'([1-9][0-9]{0,2})(\' + pointCurrency + r'{1}[0-9]{3})*');
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
const pointCurrency = '.';
var newCurrentText = newValue.text;
if (newCurrentText.length > 3) {
final newString = newCurrentText.replaceAll(RegExp(r'\D+'), '');
final splitFirst = newString.length % 3;
final regexAccrdingDatalength = pointingString(splitFirst);
final returnStringAsItString = newString.replaceAllMapped(
regexAccrdingDatalength,
(m) => '$pointCurrency${m.group(0) ?? ''}',
);
newCurrentText = returnStringAsItString;
}
if (firstNotZeroRegex(pointCurrency).hasMatch(newCurrentText)) {
return TextEditingValue(
text: newCurrentText,
selection: TextSelection.collapsed(offset: newCurrentText.length),
);
}
return TextEditingValue(
text: newValue.text,
selection: TextSelection.collapsed(offset: newValue.text.length),
);
}
}
Formatter ini difungsikan untuk membuat nilai yang diinput user menjadi berformat seperti currency rupiah (contohnya: 5.000).
Cara Kerja formatter ini dengan menambahkan (dan mengupdate) titik setiap user telah meng-input sebanyak lebih dari kelipatan 3.
(Contohnya ketika panjang karakter ada di 4 dan 5, lalu 7 dan 8, 10 dan 11 dan seterusnya ).
Adanya penggunaan RegExp
mempengauhi lokasi titik nilai yang user input.
a. function pointingString
RegExp pointingString(int modulreResult) => RegExp('(?<=.{${modulreResult == 0 ? 3 : modulreResult}}).{3}');
Method RegExp
akan mengambil (melakukan Group) pada 3 nilai setelah nilai kondisi pada nilai String
.
Nilai kondisi (nilai setelah ?<=
) dibuat relatif berdasarkan parameter method, dengan range 0 - 2.
Jika nilai yang diinput 0, maka nilai yang diubah menjadi 3 (Jadi rangenya menjadi 1 - 3).
Penjelasan tiap lambang dalam regex:
Symbole | Name | Description |
---|---|---|
(?<=...) | Positive Lookbehind | Jika pattern (group) awal benar, maka pattern (group) akhir diambil contoh: /(?<=foo)bar/ foobar fuubar |
. | Any Single Character | Semua karakter dari numeric, alphabetic, space, dan character istimewah |
{...} | Exactly ... of (pattern) | Pattern (group) yang mengharuskan/mengambil pattern(group) dedepan kurawa sebanyak nilai dalam kurung kurawa contoh: /a{3}/ a aa aaa aaaa |
(Power by : Tables Generator)
b. variable firstNotZeroRegex
RegExp firstNotZeroRegex(String pointCurrency) => RegExp(r'([1-9][0-9]{0,2})(\' + pointCurrency + r'{1}[0-9]{3})*');
Method RegExp
akan mengambil (melakukan Group) pada:
- jika patter(Group) pertama ada 3 nilai numeric dan nilai di depan bukan 0
- jika patter(Group) setelah patter (Group) pertama ada 1 character relatif yang dimasukan parameter (contoh titik (.)) dan 3 nilai numeric dari 0 s/d 9. (Dengan catatan patter(Group) pertama terpenuhi)
Penjelasan tiap lambang dalam regex:
Symbole | Name | Description |
---|---|---|
[... - ...] | An Character in Range | pattern (group) character yang ada dalam range tersebut. Biasanya untuk Numeric (0 - 9) atau huruf (besar (A - Z) atau kecil (a-z)). Untuk nilai awal range tidak selalu dimulai dari 0 atau "A"\"a". developer bisa mementukan nilai awal yang ingin dimasukan dalam range contoh: /[a-z]+/ Only a - z |
{..., ...} | Between ... and ... of | Patter (group) yang mengharuskan/mengambil patter (group) didepan kurawa sebanyak range yang ditentukan ({3,6} artinya 3 sampai 6) dalam kurung kurawa. contoh: /a{3,6}/ a aa aaa aaaa |
\ | makes any character literal | Mengubah symbol yang ada/digunakan dalam Regex (atau RegExp) menjadi character atau pattern (group). contoh: /\./ titik . |
* | zero or more of | Patter (group) untuk karakter di depan bintang sebanyak 0 atau lebih. |