Is there a way for InputFormatters on a TextFormField to be executed when the form is initially displayed?

Viewed 2994

When inputFormatters are specified on a TextFormField, the initialValue is not processed by the inputFormatters.

This seems odd. Is there a recommended way to get the inputFormatters to format the initialValue.

For example, I have a 5 digit number (i.e. 12345) that should be displayed with a comma separator (12,345) in the input field. By default it displays as 12345, but as soon as I edit the value, the comma separator appears. The comma separator should be displayed on the initial value.

3 Answers

You can create a static method to validate your initialValue

class MyFormater extends TextInputFormatter {
  static String defaultFormat(String text) {
    // Do whatever you want
    return text;
  }

  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    // Your validations/formats
    return null;
  }
}

and then you can use it as so

TextFormField(
            initialValue: MyFormater.defaultFormat(someString),
            inputFormatters: [MyFormater()],
          )

I doubt there is other way that will trigger the TextInputFormatter before it has any focus. That initialValue is mean to be already validated and work as a placeholder.

you can use this to set the text directly to the controller without interacting with the text field

var textEditingController = TextEditingController();
textEditingController.value = myFormatter.formatEditUpdate(TextEditingValue(text: ''), TextEditingValue(text: 'my initial value'));

you can set custom inputFormatters in TextField. for that you must define your filter, for example a function that take String and return a neat( or filtered ) String. in my case function neatCost() get a string and separate 3 by 3 chars by "," for example take "12345" and return "12,345". for creating custom inputFormatters :

class NeatCostFilterFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    final StringBuffer newText = StringBuffer();
    newText.write(neatCost(newValue.text.replaceAll(",", "")));
    print(newValue.text);
    print(neatCost(newValue.text.replaceAll(",", "")).length);
    return TextEditingValue(
      text: newText.toString(),
      selection: TextSelection.collapsed(offset: neatCost(newValue.text.replaceAll(",", "")).length),
    );
  }
}

and the function:

String neatCost(String cost) {
  String res=cost;
  if(cost!=null) {
    for (int i = 3; i < res.length; i += 4) {
      res = res.replaceRange(res.length - i, res.length - i, ",");
    }
    return res;
  }else{
    return "";
  }
}

after that yo can set your custom formatter to the TextField just like this:

new TextField(
    inputFormatters: <TextInputFormatter>[new NeatCostFilterFormatter()]
    )
Related