如何重置TextFormField中的错误消息?

时间:2019-08-20 13:05:49

标签: flutter dart

我知道这是一个简单的问题,但我没有找到如何做的。当用户在字段中输入内容时,如何重置TextFormField中的错误消息。像onchange监听器之类的东西。我注意到onChanged在TextField中可用,但在TextFormField中不可用。我该怎么办?

final _email = Container(
  child: TextFormField(
    decoration: InputDecoration(labelText: email),
    keyboardType: TextInputType.emailAddress,
    controller: emailController,
    validator: _validateEmail,
    onSaved: (input) => _stringEmail = input.toLowerCase().trim(),
  ),
);

更新:我正在使用控制器添加侦听器以供用户输入。但是我只想重置错误消息,而不是再次验证表单。这可能吗?我该怎么办?

  _resetEmailErrorMessage() {
    print("Second text field: ${emailController.text}");
    //replace clear to something that can reset the validation error message
    emailController.clear();
  }

  @override
  void initState() {
    super.initState();

    //start listening to changes
    emailController.addListener(_resetEmailErrorMessage);
  }

7 个答案:

答案 0 :(得分:4)

Form.autovalidate已过时。一旦用户再次开始与表单字段进行交互而无需自己管理任何状态,请使用Form.autovalidateMode = AutovalidateMode.onUserInteraction自动清除错误。

答案 1 :(得分:2)

您可以使用表格的自动验证功能

如果您正在寻找这种解决方案,

“输入后,它就会验证您的输入并显示/隐藏错误”

Flutter提供了自动验证功能,您只需要在表单级别启用它即可。

  1. 默认

    _autoValidate = false;

  2. 表格

    body:Form(key:_formKey,             自动验证:_autoValidate,....)

  3. 当用户按下一次提交时启用它,

    如果(_formKey.currentState.validate()){   // 都好 }其他{   //开始自动验证   setState((){     _autoValidate = true;   }); }

答案 2 :(得分:1)

TextFormField也具有onChanged选项,您可以尝试通过FormKey重置表单验证

final _email = Container(
 child: TextFormField(
 decoration: InputDecoration(labelText: email),
  keyboardType: TextInputType.emailAddress,
  controller: emailController,
  validator: _validateEmail,
  onChanged: (value){
    formKey.currentState.reset();
  },
  onSaved: (input) => _stringEmail = 
   input.toLowerCase().trim(),
  ),
);

答案 3 :(得分:0)

我建议使用控制器并收听用户输入。并且只要他输入内容,您就可以再次验证()您的表单

答案 4 :(得分:0)

这是一个有效的表格。您可以尝试验证表单,如下所示:

_formKey.currentState.validate()

您需要在TextFormField中定义验证字段。

答案 5 :(得分:0)

// Somewhere in `State` declaration 
final formKey = GlobalKey<FormState>();
bool autovalidate = false;

@override
void build(BuildContext context) {
  return Form(
    key: formKey,
    autovalidate: autovalidate,
    child: Column(
      children: [
        TextFormField(
          ...
          validator: (value) {
            return (value == null || value.isEmpty) ? 'Cannot be empty' : null;
          }
          onChanged: (value) {
            // Call this to refresh autovalidation result
            setState(() {});
          }
        ),
      ],
    ),
  );
}

void validate() {
  if(formKey.currentState.validate()) {
    // data is valid!
    return true;
  } elsee {
    // Activate autovalidation
    autovalidate = true;
  }
  return false;
}

答案 6 :(得分:0)

我没有看到您问题的任何答案。我还遇到了这样的情况,我希望用户一旦更改为“登录”或“注册”,身份验证表单的字段便会重置其验证错误。因此,我添加了以下逻辑:

class _AuthFormState extends State<AuthForm> {
...
  var _formFlipped = false;                                   // THIS RIGHT HERE

  void _trySubmit() {
    final isValid = _formKey.currentState.validate();
    FocusScope.of(context).unfocus();
    ...
  }

  @override
  Widget build(BuildContext context) {
    return 
      ...
            child: Form(
                ...
                  TextFormField(
                    key: ValueKey('email'),
                    validator: (value) {
                      if (_formFlipped) return null;          // THIS
                      if (value.isEmpty || !value.contains('@')) {
                        return 'Enter a valid email';
                      }
                      return null;
                    },
                    ...
                    RaisedButton(
                      child: Text(_isLogin ? 'Login' : 'Signup'),
                      onPressed: () {
                        setState(() {
                          _formFlipped = false;               // AND THIS
                        });
                        _trySubmit();
                      },
                    ),
                    FlatButton(
                      child: Text(_isLogin
                          ? 'Create new account'
                          : 'I already have an account'),
                      onPressed: () {                         // THIS TOO
                        setState(() {
                          _isLogin = !_isLogin;
                          _formFlipped = true;
                          _formKey.currentState.validate();
                        });
                      },
                    ),
        ...

BeforeAfter

编辑:

因此,基本上,您只需要在所有字段验证器上强制传递null即可清除消息。就像Yogesh所指出的那样,您可以简单地通过_formKey.currentState.reset();

但是,如果您需要更精细的控制,此方法将为您带来好处,因为您可以根据需要将if (_formFlipped) return null;或类似条件设置为不同的字段。