I'm trying to format textformfield while typing. I've managed to get it working...well sort of. Currently the textformfield takes in number and works like this:
user types in number for example "1" - > user types in second number ex. "2" the formatting changes the value to "1.2" by adding . in between -> user types in a third number "3" the formatting changes the value to "12.3".
Now my issue is that this is a price field and I want to round up to two digits after the . SO it would be 1.00, 1.20 or 12.30.
I've been sitting on this for a bit now and I have no idea how to make it work.
I want to make sure that there cannot be more than 5 characters inside with largest value example (12.30)
The Code:
TextFormField(
validator: (fuelPriceValue) {
if (fuelPriceValue!.isEmpty) {
return null;
}
},
onChanged: (fuelPriceValue) {
fuelPrice = (fuelPriceValue as TextEditingController);
},
controller: fuelPrice,
keyboardType: TextInputType.number,
inputFormatters: [
LengthLimitingTextInputFormatter(4),
FilteringTextInputFormatter.allow(RegExp(r'\d*')),
TextInputFormatter.withFunction((oldValue, newValue) {
LengthLimitingTextInputFormatter(3);
if (newValue.text.length == 2) {
return TextEditingValue(
text: '${newValue.text.substring(0, 1)}.${newValue.text.substring(1)}',
selection: TextSelection.fromPosition(TextPosition(offset: newValue.text.length + 1))
);
}
LengthLimitingTextInputFormatter(4);
if (newValue.text.length == 3) {
return TextEditingValue(
text: '${newValue.text.substring(0, 2)}.${newValue.text.substring(2)}',
selection: TextSelection.fromPosition(TextPosition(offset: newValue.text.length + 1))
);
}
if (newValue.text.length == 4) {
return TextEditingValue(
text: '${newValue.text.substring(0, 2)}.${newValue.text.substring(2)}',
selection: TextSelection.fromPosition(TextPosition(offset: newValue.text.length))
);
}
return TextEditingValue(
text: newValue.text,
selection: TextSelection.collapsed(offset: newValue.text.length),
);
}),
],
// inputFormatters: [
// LengthLimitingTextInputFormatter(5),
// FilteringTextInputFormatter.allow(RegExp(r'\d*')),
// TextInputFormatter.withFunction((oldValue, newValue) {
//
// LengthLimitingTextInputFormatter(3);
// if (newValue.text.length == 2) {
// return TextEditingValue(
// text: '${newValue.text.substring(0, 1)}.${newValue.text.substring(1)}',
// selection: TextSelection.fromPosition(TextPosition(offset: newValue.text.length + 1))
// );
// }
// LengthLimitingTextInputFormatter(4);
// if (newValue.text.length == 3) {
// return TextEditingValue(
// text: '${newValue.text.substring(0, 2)}.${newValue.text.substring(2)}',
// selection: TextSelection.fromPosition(TextPosition(offset: newValue.text.length + 1))
// );
// }
// if (newValue.text.length == 4) {
// return TextEditingValue(
// text: '${newValue.text.substring(0, 2)}.${newValue.text.substring(2)}',
// selection: TextSelection.fromPosition(TextPosition(offset: newValue.text.length))
// );
// }
// return TextEditingValue(
// text: newValue.text,
// selection: TextSelection.collapsed(offset: newValue.text.length),
// );
// }),
// ],
decoration: InputDecoration(
errorBorder: OutlineInputBorder(),
border: OutlineInputBorder(),
contentPadding: EdgeInsets.only(left: 10))),
its just idea not final solution.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class TextExample extends StatefulWidget {
const TextExample({super.key});
@override
State<TextExample> createState() => _TextExampleState();
}
class _TextExampleState extends State<TextExample> {
TextEditingController c = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
child: Column(
children: [
TextFormField(
controller: c,
onChanged: (value) {
//TextSelection.fromPosition(TextPosition(offset: c.text.length));
},
keyboardType: TextInputType.number,
inputFormatters: [
LengthLimitingTextInputFormatter(4),
FilteringTextInputFormatter.allow(RegExp(r"[0-9.]")),
TextInputFormatter.withFunction((oldValue, newValue) {
String input = newValue.text;
if(input.length==2){
if(!input.contains(".")){
input = input[0] + "."+input[1];
}else{
}
}
if(input.length==3){
if(input.contains(".")){
input = input.replaceAll(".", "");
input = input[0] + "."+input[1];
}else{
}
}
if(input.length==4){
var count = '.'.allMatches(input).length;
if(count>1){
input = oldValue.text;
return upr(input);
}else if(count==1){
if(input.contains(".") && input.length==4){
// var position = input.indexOf('.');
input = input.replaceAll(".", "");
input = input[0] + input[1]+"."+input[2];
if(int.parse(input[0]) != 1){
input = oldValue.text;
return upr(input);
}
if(int.parse(input[0]) == 1 && int.parse(input[1])>2 ){
input = oldValue.text;
return upr(input);
}
if(int.parse(input[0]) == 1 && int.parse(input[1])<3 && int.parse(input[3])>3){
input = oldValue.text;
return upr(input);
}
if(int.parse(input[0]) != 1 && int.parse(input[1])< 3 ){
input = oldValue.text;
return upr(input);
}
}
}else{
input = oldValue.text;
return upr(input);
}
}
if(input.length>4){
input = oldValue.text;
return upr(input);
}
return upr(input);
}),
],
),
],
),
),
),
);
}
}
TextEditingValue upr(input){
TextEditingValue val1 = TextEditingValue(
text:input,
selection: TextSelection.fromPosition(TextPosition(offset: input.length))
);
return val1 ;
}