41

I want to input only decimal number in TextField in Flutter. I tried below code but that's not working. It allows alpha (a-z) and special characters.

TextField(
  controller:
      new TextEditingController(text: listDisplay[position].getBlockQty(),
  ),       
  textAlign: TextAlign.center,
  maxLines: 1,       
  keyboardType: TextInputType.numberWithOptions(
      decimal: true,
      signed: false),       
),
9
  • For me this is working. What does you mean by alpha works. Commented Apr 11, 2019 at 11:30
  • Alpha (A-Z) and also allows special characters like, +,- Commented Apr 11, 2019 at 11:46
  • What do you mean it allows alpha words? it is showing them but they are not clickable. Commented Apr 11, 2019 at 11:49
  • @CopsOnRoad, in my case it inputs alpha (a-z) and special characters. Commented Apr 11, 2019 at 11:51
  • 1
    @CopsOnRoad, I am entering data from hardware keyboard. So that is problem?? Commented Apr 11, 2019 at 11:52

7 Answers 7

56

try this:

inputFormatters: [
  FilteringTextInputFormatter.allow(RegExp(r"[0-9.]")),
  TextInputFormatter.withFunction((oldValue, newValue) {
    final text = newValue.text;
    return text.isEmpty
        ? newValue
        : double.tryParse(text) == null
            ? oldValue
            : newValue;
  }),
],

demo:

TextFormField(
  keyboardType: TextInputType.numberWithOptions(
    decimal: true,
    signed: false,
  ),
  onChanged: _yourOnChange,
  inputFormatters: [
    FilteringTextInputFormatter.allow(RegExp(r"[0-9.]")),
    TextInputFormatter.withFunction((oldValue, newValue) {
      final text = newValue.text;
      return text.isEmpty
          ? newValue
          : double.tryParse(text) == null
              ? oldValue
              : newValue;
    }),
  ],
)
Sign up to request clarification or add additional context in comments.

Comments

20

You can use TextInputFormatter for this case.

Here is an example for the same,

Subclass TextInputFormatter

import 'package:flutter/services.dart';

class RegExInputFormatter implements TextInputFormatter {
  final RegExp _regExp;

  RegExInputFormatter._(this._regExp);

  factory RegExInputFormatter.withRegex(String regexString) {
    try {
      final regex = RegExp(regexString);
      return RegExInputFormatter._(regex);
    } catch (e) {
      // Something not right with regex string.
      assert(false, e.toString());
      return null;
    }
  }

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    final oldValueValid = _isValid(oldValue.text);
    final newValueValid = _isValid(newValue.text);
    if (oldValueValid && !newValueValid) {
      return oldValue;
    }
    return newValue;
  }

  bool _isValid(String value) {
    try {
      final matches = _regExp.allMatches(value);
      for (Match match in matches) {
        if (match.start == 0 && match.end == value.length) {
          return true;
        }
      }
      return false;
    } catch (e) {
      // Invalid regex
      assert(false, e.toString());
      return true;
    }
  }
}

Use it in with your textfield

final _amountValidator = RegExInputFormatter.withRegex('^\$|^(0|([1-9][0-9]{0,}))(\\.[0-9]{0,})?\$');
...
TextField(
  inputFormatters: [_amountValidator],
  keyboardType: TextInputType.numberWithOptions(
    decimal: true,
     signed: false,
   ),
 )

5 Comments

for restrict: RegExInputFormatter.withRegex('^[0-9]{0,6}(\\.[0-9]{0,2})?\$')
Does this work for locale's with commas instead of periods for the decimal character?
I haven't tried that. But I believe you need to update the regex for that.
@Johnykutty With all above requirements I want to allow minus numbers too. What changes are required in the Regex?
@DhavalKansara you could add ([-]{0,1}) to the begining of the regex. Something like '^\$|^(0|([1-9][0-9]{0,}))(\\.[0-9]{0,})?\$' PS: I haven't tried this in code, tried in regexpal.com
10

I am using this code and it's giving different results , on some phones it shows only numbers and on others it shows dashes and other chars , so it depends on the launcher or something like that i guess, in iPhone i guess it will show the correct keyboard ( i have tried on iPhone 7s plus).

the inputFormatters will allow only numbers so you will get what you want.

   TextField(
     textAlign: TextAlign.start,
     keyboardType: TextInputType.numberWithOptions(decimal: true),
     inputFormatters: <TextInputFormatter>[
                          FilteringTextInputFormatter.digitsOnly
                       ],
   ),

1 Comment

FilteringTextInputFormatter.digitsOnly allows inputting only digits, no commas or periods
9

I've been looking the answer to this problem too and found it after many attempts and hard work.

you can use this regex for decimal.

inputFormatters: [
        FilteringTextInputFormatter.allow(RegExp(r'^[0-9]+\.?[0-9]*'))
      ],

4 Comments

Good!! It also works.
Great answer, one optimisation is use \. in the regex. e.g. r'^[0-9]+\.?[0-9]*' as . in regex could be any single character like 123:1.
Didn't spend a lot of time on this, but that RegExp let spaces and multiple periods through for me. Also, I wanted the decimal places to be optional. Found this in a Javascript RegExp answer that caught spaces and multiple periods: Try the following expression: ^\d+\.\d{0,2}$ If you want the decimal places to be optional, you can use the following: ^\d+(\.\d{1,2})?$
remember to use ^ and $ so hasMatch() method does a proper match for full input text: ^[0-9]+\.?[0-9]*$ and not passes on cases like 4..
4

Add the inputFormatters line:

 TextField(
     inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}'))],
          ...)

Comments

1

I have used this code in one of my Project and its working fine. I hope it will helps you.

TextField(
         decoration: InputDecoration(
         border: InputBorder.none,
         hintText: "Amount",
         hintStyle:
         TextStyle(color: Colors.grey, fontSize: 12.0),
         ),
         style: TextStyle(color: Colors.black, fontSize: 12.0),
         controller: _amountController[index],
         textInputAction: TextInputAction.done,
         keyboardType: TextInputType.numberWithOptions(decimal: true),)

enter image description here

4 Comments

TextInputType.numberWithOptions not working. I already mentioned in question.
@SagarZala I have added the screen. You can see its working.
on Huawei that is not working at all, Mate 20 pro, I can see the chars too with the numbers
simply using TextInputType.numberWithOptions(decimal: true) doesn't work. It will allow 12.123.121 type of input
1

try this one for decimal

import 'package:flutter/services.dart';
...
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp('[0-9.,]+')),],
onChanged: (value) => doubleVar = double.parse(value),

Also

RegExp('([0-9]+(.[0-9]+)?)') For allow digits and only one dot

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.