Search code examples
flutterdoubletextfieldinputformatter

Ensure only valid input number format in Flutter TextField


I've got a TextField in my flutter app, for help inputting numbers for a calculator function. For this TextField, I have set the keyboard to be numbers only, using

keyboardType: TextInputType.number

Now, this works perfectly, in a sense that it ensures only the number input keyboard appears. This keyboard allows the user to input numbers from 0 to 9, as well as a decimal point. The problem is, it doesn't stop users inputting multiple decimal points. Once a user adds more than one, it makes the number invalid and the calculator doesn't work.

Essentially, what I need to do is ensure the user can only input 1 decimal point and digits, but no other characters.

I came across the inputFormatters feature on another question on this forum and I've tried to use it like so:

TextField(
 inputFormatters: <TextInputFormatter>[
      FilteringTextInputFormatter.allow(RegExp("[0-9].")),
  ], // Only numbers and a decimal point can be entered
),

Whilst this does help to ensure only digits and decimal points are entered, it doesn't stop multiple decimal points being entered, when only one should be.

How can I edit this filtering rule, or what else can I do, to ensure only 1 decimal point can be entered, to ensure a number is always in the correct format (i.e. is always an integer or double)?

Thanks!


Solution

  • Have you tried using DecimalTextInputFormatter input formatter?

    TextFormField(
      inputFormatters: [DecimalTextInputFormatter(decimalRange: 1)],
      keyboardType: TextInputType.numberWithOptions(decimal: true),
    )
    

    You can achieve the same result using a regular expression along with FilteringTextInputFormatter (following your approach) like:

    FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,1}')),
    

    The range {0,1} does the trick.

    RegExp(r'^\d+\.?\d?') is also a valid expression for this case.

    Update (April 2024)

    Same result can be achieved using directly FilteringTextInputFormatters via:

    FilteringTextInputFormatters.numbersOnly