Line data Source code
1 : import 'package:flutter/services.dart'; 2 : import 'package:folly_fields/util/decimal.dart'; 3 : import 'package:folly_fields/validators/abstract_validator.dart'; 4 : 5 : /// 6 : /// 7 : /// 8 : class DecimalValidator extends AbstractParserValidator<Decimal> { 9 : final String decimalSeparator; 10 : final String thousandSeparator; 11 : final int precision; 12 : 13 : /// 14 : /// 15 : /// 16 1 : DecimalValidator( 17 : this.precision, { 18 : this.decimalSeparator = ',', 19 : this.thousandSeparator = '.', 20 2 : }) : assert(precision >= 0, 'precision must be positive or zero.'), 21 1 : super( 22 1 : <TextInputFormatter>[ 23 1 : FilteringTextInputFormatter.digitsOnly, 24 : ], 25 : ); 26 : 27 : /// 28 : /// 29 : /// 30 1 : @override 31 : String format(Decimal decimal) { 32 1 : List<String> parts = decimal.doubleValue 33 2 : .toStringAsFixed(precision) 34 1 : .replaceAll('.', '') 35 1 : .split('') 36 1 : .reversed 37 1 : .toList(growable: true); 38 : 39 2 : int start = precision + 4; 40 2 : if (precision > 0) { 41 3 : parts.insert(precision, decimalSeparator); 42 : } else { 43 : start = 3; 44 : } 45 : 46 3 : for (int pos = start; parts.length > pos; pos += 4) { 47 2 : parts.insert(pos, thousandSeparator); 48 : } 49 : 50 2 : return parts.reversed.join(); 51 : } 52 : 53 : /// 54 : /// 55 : /// 56 0 : @override 57 : String strip(String value) => value; 58 : 59 : /// 60 : /// 61 : /// 62 0 : String _internalStrip(String value) => super.strip(value); 63 : 64 : /// 65 : /// 66 : /// 67 0 : @override 68 0 : bool isValid(String value) => valid(value) == null; 69 : 70 : /// 71 : /// 72 : /// 73 0 : @override 74 : TextInputType get keyboard => TextInputType.number; 75 : 76 : /// 77 : /// 78 : /// 79 0 : @override 80 : Decimal? parse(String? value) { 81 0 : Decimal decimal = Decimal(precision: precision); 82 : 83 0 : if (value == null || value.isEmpty) { 84 : return decimal; 85 : } 86 : 87 0 : List<String> parts = _internalStrip(value).split('').toList(growable: true); 88 : 89 0 : for (int pos = parts.length; pos <= precision; pos++) { 90 0 : parts.insert(0, '0'); 91 : } 92 : 93 0 : if (precision > 0) { 94 0 : parts.insert(parts.length - precision, '.'); 95 : } 96 : 97 0 : decimal.doubleValue = double.parse(parts.join()); 98 : 99 : return decimal; 100 : } 101 : 102 : /// 103 : /// 104 : /// 105 0 : @override 106 : String? valid(String value) => null; 107 : }