Search code examples
flutterdarttext-formatting

Flutter input formatting in textformfield


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))),

Solution

  • 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 ;
    }