Skip to content

Instantly share code, notes, and snippets.

@roipeker
Last active June 8, 2020 14:04
Show Gist options
  • Save roipeker/445edb28e2ec9d09238e07cbb7dce28d to your computer and use it in GitHub Desktop.
Save roipeker/445edb28e2ec9d09238e07cbb7dce28d to your computer and use it in GitHub Desktop.
TextController money format util.
// roipeker©2020
// demo codepen : https://codepen.io/roipeker/pen/oNbXRQz
// demo web : https://dev.roipeker.website/flutter_demos/textcontroller_currency/
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'text_controller_format.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => WidgetsBinding.instance.focusManager.primaryFocus?.unfocus(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.dark,
home: Scaffold(
appBar: AppBar(
title: Text('TextController Currency Format'),
centerTitle: true,
elevation: 0,
),
body: Center(
child: SizedBox(
width: 200,
child: TextInputMoney(),
),
),
),
),
);
}
}
class TextInputMoney extends StatefulWidget {
@override
_TextInputMoneyState createState() => _TextInputMoneyState();
}
class _TextInputMoneyState extends State<TextInputMoney> {
TextEditingController _textControl;
TextControllerFormat _formatControl;
@override
void initState() {
super.initState();
_textControl = TextEditingController();
_formatControl = TextControllerFormat(_textControl);
_textControl.addListener(_formatControl.formatMoney);
// call one time, to refresh the text with the default.
_formatControl.formatMoney();
}
@override
void dispose() {
_textControl.removeListener(_formatControl.formatMoney);
_textControl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
const style = TextStyle(
fontFamily: 'JetbrainMono',
fontFeatures: [
FontFeature.proportionalFigures(),
FontFeature.slashedZero()
],
);
return TextField(
controller: _formatControl.controller,
style: style,
keyboardType: TextInputType.numberWithOptions(),
textDirection: TextDirection.ltr,
textAlign: TextAlign.end,
maxLength: 18,
decoration: InputDecoration(
border: InputBorder.none,
counter: SizedBox.shrink(),
fillColor: Theme.of(context).backgroundColor,
filled: true,
contentPadding: EdgeInsets.all(12),
),
);
}
}
// roipeker©2020
// demo codepen : https://codepen.io/roipeker/pen/oNbXRQz
// demo web : https://dev.roipeker.website/flutter_demos/textcontroller_currency/
import 'package:flutter/widgets.dart';
class TextControllerFormat {
final TextEditingController controller;
int _lastSelPos = 0;
String _lastText;
TextControllerFormat(this.controller);
void formatMoney() {
String str = controller.text;
if (controller.selection.baseOffset > -1) {
_lastSelPos = str.length - controller.selection.baseOffset;
}
if (_lastText == str) return;
_lastText = str;
str = str.replaceAll(RegExp(r'[^0-9]'), '').trim();
var value = double.tryParse(str) ?? 0.0;
if (value != 0) value /= 100;
var numberParts = '$value'.split('.');
if (numberParts.length == 1) {
numberParts.add('0');
}
var intPart = numberParts[0];
// make sure we have 2 digits in decimals when input 1 char.
var decPart = numberParts[1].padLeft(2, '0');
var output = '';
var intList = intPart.split('').toList();
final len = intList.length;
intList.asMap().entries.forEach((e) {
output += e.value;
final j = len - e.key - 1;
final isLast = e.key == len - 1;
if (j % 3 == 0 && !isLast) {
output += '.';
}
});
output += ',' + decPart;
controller.value = controller.value.copyWith(
selection: TextSelection.collapsed(offset: output.length - _lastSelPos),
text: output,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment