Trim() input value of any TextField in a Form by default in flutter app

4,475

Solution 1

just add

inputFormatters: [WhitelistingTextInputFormatter(RegExp(r'[a-zA-Z0-9]'))],

as property to TextInputField and user will not even able to type space or any other chars except whitelisted and you can remove also additional checks from validator

full example

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: TextFormField(
              inputFormatters: [WhitelistingTextInputFormatter(RegExp(r'[a-zA-Z0-9]'))],
              keyboardType: TextInputType.text,
              decoration: new InputDecoration(
                labelText: 'Enter your nickname',
              ),
              validator: (val) {
                if (val.isEmpty == true) {
                  return 'Nickname is required!';
                }
                return null;
              },
              onSaved: (val) {},
            ),
          ),
        ),
      ),
    );
  }
}

Solution 2

Trim the text value on onChanged callback and assign it back to the controller.

Solution 3

As @Darish suggested, here is the sample code for it.

A caveat though, need to select at the end of text if trimmed. This will only work if spaces in between are disallowed.

class _MyHomePageState extends State<MyHomePage> {
  final alphaNumericText = RegExp(r'^[a-zA-Z0-9]+$');
  final textController = TextEditingController();

  @override
  void dispose() {
    super.dispose();
    textController?.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextFormField(
          controller: textController,
          keyboardType: TextInputType.text,
          decoration: new InputDecoration(
            labelText: 'Enter your nickname',
          ),
          onChanged: (val) {
            final trimVal = val.trim();
            if (val != trimVal)
              setState(() {
                textController.text = trimVal;
                textController.selection = TextSelection.fromPosition(TextPosition(offset: trimVal.length));
              });
          },
          validator: (val) {
            if (val.isEmpty == true) {
              return 'Nickname is required!';
            }
            if (alphaNumericText.hasMatch(val) == false) {
              return 'Use alphanumeric characters only in nickname.';
            }
            return null;
          },
        ),
      ),
    );
  }
}
Share:
4,475
James Mwase
Author by

James Mwase

Updated on December 17, 2022

Comments

  • James Mwase
    James Mwase 11 months

    I have different form fields and I want to trim each value of the form field by default before the validator method gets fired.

    The reason I want to achieve this is because if I run a regex on an Input value when the validator method gets fired, the regex will return false on input_text.hasMatch because of a useless space character at the end of the input value.

    For example. The code below on alphaNumericText.hasMatch(val) will return false because of a useless extra space character(s) at the end of the input value.

    final alphaNumericText = RegExp(r'^[a-zA-Z0-9]+$');
    
    TextFormField(
                      keyboardType: TextInputType.text,
                      decoration: new InputDecoration(
                        labelText: 'Enter your nickname',
                      ),
                      validator: (val) {
                        if (val.isEmpty == true) {
                          return 'Nickname is required!';
                        }
                        if (alphaNumericText.hasMatch(val) == false) {
                          return 'Use alphanumeric characters only in nickname.';
                        }
                        return null;
                      },
                      onSaved: (val) => this.nickname = val,
                    ),
    

    Note I do not want to achieve this by modifying the alphaNumericText RegExp to entertain extra spaces at the end of input value. I do not want to achieve this in this way.

    What I want is every value in all TextFields in a form to be validated by default before the validator method is called.

  • ByronSchuurman
    ByronSchuurman about 3 years
    WhitelistingTextInputFormatter is deprecated, use FilteringTextInputFormatter instead.