Flutter TextEditingController clear wont reset the error message

Viewed 2477

I using the flutter form autovalidateMode: AutovalidateMode.onUserInteraction to do validate if textfield didnt fill in.

How to make the validate error message hide when submit the form and reset the textfield again?

Below is my code to demo the my problem, after fill in the textfield and press submit. The red error message also show up which is not UX friendly.

DartPad link: https://dartpad.dev/d26c3f57be04acaafae2ee127a688e3f

Code

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: MyCustomForm(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();
  final TextEditingController taskController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Form(
      key: _formKey,
      autovalidateMode: AutovalidateMode.onUserInteraction,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          TextFormField(
            controller: taskController,
            validator: (value) {
              if (value.isEmpty) {
                return 'Please enter some text';
              }
              return null;
            },
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 16.0),
            child: ElevatedButton(
              onPressed: () {
                // Validate returns true if the form is valid, or false
                // otherwise.
                if (_formKey.currentState.validate()) {
                  // If the form is valid, display a Snackbar and reset
                  Scaffold.of(context)
                      .showSnackBar(SnackBar(content: Text('Processing Data')));
                  taskController.clear();
                }
              },
              child: Text('Submit'),
            ),
          ),
        ],
      ),
    );
  }
}
3 Answers

We can use InputDecoration to toggle the errorStyle and achieve the desired result.

Output:

enter image description here

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: MyCustomForm(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();
  final TextEditingController taskController = TextEditingController();
  bool hideError = false;
  bool first = true;

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Form(
      key: _formKey,
      autovalidateMode: AutovalidateMode.onUserInteraction,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          TextFormField(
              controller: taskController,
              decoration: hideError && !first
                  ? InputDecoration(
                      errorStyle: TextStyle(height: 0),
                      )
                  : null,
              validator: (value) {
                if (value.isEmpty) {
                  print(value);

                  return 'Please enter some text';
                }
                return null;
              },
              onChanged: (value) {
                setState(() {
                  hideError = false;
                  first = false;
                });
              }),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 16.0),
            child: ElevatedButton(
              onPressed: () {
                // Validate returns true if the form is valid, or false
                // otherwise.
                setState(() {
                  hideError = true;
                });
                if (_formKey.currentState.validate()) {
                  // If the form is valid, display a Snackbar and reset
                  
                  Scaffold.of(context)
                      .showSnackBar(SnackBar(content: Text('Processing Data')));
                  taskController.clear();
                  
                }
              },
              child: Text('Submit'),
            ),
          ),
        ],
      ),
    );
  }
}

If you do not want to show error message then simple delete the validator.

validator: (value) {
          if (value.isEmpty) {
            return 'Please enter some text';
          }
          return null;
        },

remove this from your code !!

validator: (String value) {
          if (value.isEmpty) {
            return ' ';
          }
          return null;
        },

Do this, by returning an empty String you can still see the text Field red.

Related