25

There is a way to validate the input of the user with a TextFormField or TextField,to reject the input if it's not an email.

Andres Diaz
  • 421
  • 1
  • 5
  • 10

9 Answers9

44

You can use regex for this

Form and TextFormField like so

Form(
  autovalidateMode: AutovalidateMode.always,
  child: TextFormField(
    validator: validateEmail,
  ),
)

then the validation function

String? validateEmail(String? value) {
  const pattern = r"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'"
      r'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-'
      r'\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*'
      r'[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4]'
      r'[0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9]'
      r'[0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\'
      r'x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])';
  final regex = RegExp(pattern);

  return value!.isNotEmpty && !regex.hasMatch(value)
      ? 'Enter a valid email address'
      : null;
}

Link to regex https://stackoverflow.com/a/201378/12695188

genericUser
  • 4,417
  • 1
  • 28
  • 73
JideGuru
  • 7,102
  • 6
  • 26
  • 48
27

To validate the form, you can use the autovalidate flag and set up a validator for email. There are many options, including regex or manually writing your own checker, but there are also packages available which implement email checking already.

For example, https://pub.dev/packages/email_validator.

To use it, add it to your pubspec:

dependencies:
  email_validator: '^1.0.0'
import 'package:email_validator/email_validator.dart';

...

Form(
  autovalidate: true,
  child: TextFormField(
    validator: (value) => EmailValidator.validate(value) ? null : "Please enter a valid email",
  ),
)

There are many other validation packages, some of which support may different types of validation. See this search for more https://pub.dev/packages?q=email+validation.

rmtmckenzie
  • 37,718
  • 9
  • 112
  • 99
  • How can you make the validator display the message only when a submit button is pressed? When you do it this way it will display "Please enter a valid email" from the first letter you type. – Lakshan Costa Aug 27 '21 at 09:58
  • 1
    There's a few easy options. One way to do it is to have a boolean in your class, something like `bool submitButtonPressed` and to set autovalidate to false until submit has been pressed. Or you could return null from your validator until that is true. Or... upi could put change listeners for `onSubmitted` or `onChanged` or `onEditingComplete` on each form element and manage the whole thing manually. – rmtmckenzie Aug 30 '21 at 05:50
  • Is there is a modified version of this? For example I want to see if a mail ends with 'robert@harvard.edu' or not – Tim's Dec 10 '21 at 11:33
  • The validation logic is quite simple - either you return null if the string is valid or an error string if not. So if you want to check for @harvard.edu, you could simply do something like `(EmailValidator.validate(value) && email.endsWith("@harvard.edu"))`. Or use regex. – rmtmckenzie Dec 10 '21 at 12:29
6
  TextFormField(
          validator: (val) => val.isEmpty || !val.contains("@")
              ? "enter a valid eamil"
              : null,
         
          decoration: InputDecoration(hintText: 'email'),
        ),

In the validator first we are checking if the formfeild is empty and also we are checking if the text entered dose not contains "@" in it . If those conditions are true then we are returning a text "enter a valid email" or else we are not returning anything

S.R Keshav
  • 1,965
  • 1
  • 11
  • 14
2

I suggest use of this excellent library called validators

  1. Add dependency to your package's pubspec.yaml file:
    dependencies:
      validators: ^2.0.0 # change to latest version
  1. Run from the command line:
    $ pub get
    // on VSCode u need not do anything.
  1. Import in your Dart code:
    import 'package:validators/validators.dart';
  1. Validate your field
Form(
  child: TextFormField(
    validator: (val) => !isEmail(val) ? "Invalid Email" : null;,
  ),
)
raaaay
  • 496
  • 7
  • 14
aWebDeveloper
  • 36,687
  • 39
  • 170
  • 242
2

QUICK FIX Use this in your TextFormField.

validator: (value) {
  if(value == null || value.isEmpty || !value.contains('@') || !value.contains('.')){
    return 'Invalid Email';
  }
  return null;
},
1

The previous answers all discuss options for verifying a TextFormField in a Form. The question asks about doing this in

TextFormField or TextField

TextField does not support the validator: named parameter but you can use any of the previously mentioned techniques to check the validity of the email every time the user modifies the email address text. Here is a simple example:

  TextField(
    keyboardType: TextInputType.emailAddress,
    textAlign: TextAlign.center,
    onChanged: (value) {
      setState(() {
        _email = value;
        _emailOk = EmailValidator.validate(_email);
      });
    },
    decoration:
        kTextFieldDecoration.copyWith(hintText: 'Enter your email'),
  ),

You can use the validation result as you see fit. One possibility is to keep a login button deactivated until a valid email address has been entered:

  ElevatedButton(
    child: Text('Log In'),
    // button is disabled until something has been entered in both fields.
    onPressed: (_passwordOk && _emailOk) ? ()=> _logInPressed() : null,
  ),
j-vasil
  • 139
  • 1
  • 9
1

If you use flutter_form_builder with flutter_builder_validators

email verification can be done easily

FormBuilderTextField(
  name: 'email',
  decoration: InputDecoration(
    labelText: 'Email',
    errorText: _emailError,
  ),
  validator: FormBuilderValidators.compose([
      FormBuilderValidators.required(),
      FormBuilderValidators.email(),
  ]),
),
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
fuzes
  • 1,777
  • 4
  • 20
  • 40
0
TextFormField(
  validator: (value) {
    if(value.isEmpty) {
      return "Please enter email";
    } else if(!value.contains("@")) {
      return "Please enter valid email";
    }
  },
  decoration: InputDecoration(hintText: 'email'),
),
-2

No need to use external libraries or Regex! Put your text field inside a form, set autovalidate to 'always' and inside TextFormField add a validator function:

 Form(
  autovalidateMode: AutovalidateMode.always,
  child: TextFormField(
    validator: validateEmail,
  ),
)

Validator function:

 String? validateEmail(String? value) {    
      if (value != null) {
        if (value.length > 5 && value.contains('@') && value.endsWith('.com')) {
          return null;
        }
     return 'Enter a Valid Email Address';
    }

note: length > 5 because '.com' and '@' make 5 characters.

Adrish
  • 112
  • 1
  • 3
  • 1
    You can't use the check `value.endsWith('.com')` since every email address does not end with `.com`. There are for example email addresses which end with .co, .org, .net, .xyz and .fi – Crossoni May 05 '22 at 09:20