Michael S
Michael S

Reputation: 769

Flutter FilteringTextInputFormatter delete string after illegal input

I like to allow positive and negative decimals in a Flutter TextField. I have created a simple example:

RegExp(r'^-?[0-9]*') This RegEx allows: 123 -123 But, if I like to add between 1 and 2 a new number like 0 and I hit the wrong key like 'a' the part '23' is deleted.

Looks like the problem is the '^', because, if I change the RegExp like this RegExp(r'-?[0-9]*') the part '23' is not deleted if I hit between 1 and 2 the 'a' key. But this RegExp allows inputs like '1---2---3.

One solution would be to write an on change listener and verify the input with the RegExp '^-?[0-9]*' and if it´s false the content will be replaced with the old value.

But I would be nice to use instead a RegExp.

Here is a code example

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class MyTextFieldFilter extends StatefulWidget {
  const MyTextFieldFilter({Key? key}) : super(key: key);

  static const String id = 'MyTextFieldFilter';

  @override
  State<MyTextFieldFilter> createState() => _MyTextFieldFilter();
}

class _MyTextFieldFilter extends State<MyTextFieldFilter> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: TextField(
          keyboardType: TextInputType.text,
          inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^-?[0-9]*'))],
        ),
      ),
    );
  }
}

Greetings Michael

Upvotes: 6

Views: 1278

Answers (2)

Oleksandr Bondarenko
Oleksandr Bondarenko

Reputation: 21

You dont need onChangeListener. You can use this and entered numbers will not be deleted:

inputFormatters: [ 
 TextInputFormatter.withFunction(
  (TextEditingValue oldValue, TextEditingValue newValue) {
    return RegExp(r'^-?[0-9]*').hasMatch(newValue.text) 
         ? newValue 
         : oldValue;
  },
 ),
]

Upvotes: 2

derpda
derpda

Reputation: 1149

One way to circumvent your issue would be to use the regex r'^(-[0-9]*|[0-9]*)'.

The regex structure (<pattern1>|<pattern2>|...) matches either <pattern1>, <pattern2> or any additional patterns you may want to specify.

You can test it here!

Upvotes: 1

Related Questions