Flutter表单验证插件ready_form的使用

Flutter表单验证插件ready_form的使用

ReadyForm 是一个用于简化表单处理的Widget。它可以帮助你进行表单验证,并且在验证失败时滚动到第一个无效项。

功能

  • 验证子元素
  • 如果验证失败,则滚动到第一个无效项
  • 可以添加揭示效果
  • ProgressButton 与之平滑配合使用

使用方法

基本用法

return ReadyForm(
  onPostData: () async {
    /// 提交你的数据
    return OnPostDataResult();
  },
  child: ListView(
    children: [
      TextFormField(),
      TextFormField(),
      TextFormField(),
      TextFormField(),
      ProgressButton(child: Text("登录")),
    ],
  ),
);

当你按下进度按钮时,表单将被提交并检查验证规则。

自定义提交方式

如果你需要自行提交表单或不使用 ProgressButton,可以使用 ReadyFormKey

final ReadyFormKey formKey = ReadyFormKey();

Widget build(BuildContext context) {
  return ReadyForm(
    onPostData: () async {
      /// 提交你的数据
      return OnPostDataResult();
    },
    child: ListView(
      children: [
        TextFormField(),
        TextFormField(),
        TextFormField(),
        TextFormField(),
        ElevatedButton(
          onPressed: () {
            formKey.onSubmit();
          },
          child: Text("登录"),
        ),
      ],
    ),
  );
}

你也可以通过 ReadyForm.of(context) 来访问父表单:

return ReadyForm(
  onPostData: () async {
    /// 提交你的数据
    return OnPostDataResult();
  },
  child: ListView(
    children: [
      TextFormField(),
      TextFormField(),
      TextFormField(),
      TextFormField(),
      Builder(builder: (context) {
        // 当前上下文现在可以访问父表单
        return ElevatedButton(
          onPressed: () {
            ReadyForm.of(context)!.onSubmit();
          },
          child: Text("登录"),
        );
      }),
    ],
  ),
);

全局配置

你可以通过 ReadyFormConfig 配置所有表单。

键盘操作

有一个名为 KeyboardActions 的Widget,它会在键盘打开时在顶部添加三个按钮:“下一个”、“上一个”和“隐藏键盘”。这些图标在iOS上特别有用,因为iOS键盘本身没有隐藏按钮。

默认情况下,ReadyForm 使用此Widget,但你可以在单个表单中禁用它。你也可以单独使用此Widget。

确保此Widget正常工作,你需要传递首选的 FocusTraversalPolicy(建议使用 OrderedTraversalPolicy),并且每个字段都需要用 FocusTraversalOrder 包裹。

FocusTraversalOrder(
  order: NumericFocusOrder(1),
  child: ...,
)

验证模式

每个表单都可以设置验证模式,而不是使用Flutter的 AutoValidateMode 枚举。你可以使用 FormAutoValidateMode,其中包含 onSubmit

这也可以全局配置。

滚动到无效字段

默认情况下,该包会在 [onSubmit] 时滚动到第一个无效字段。

但是有时你可能想要覆盖这种行为:

EnsureContextVisible(
  after: (context) async {
    /// 这将在默认行为之后调用
  },
  before: (context) async {
    /// 这将在默认行为之前调用
  },
);
EnsureContextVisible.override(
  ensureVisible: (context) async {
    /// 这将覆盖默认行为
  },
);

如果要包裹单个字段,可以这样做:

if (yourCondition) {
  EnsureContextVisible.override(
    ensureVisible: (context) async {
      // 自定义滚动逻辑
    },
  );
}

提交错误

有时你希望在调用 onPostData 后显示自定义错误。

如你所见,onPostData 可以返回 OnPostDataResult,其中可能包含错误映射。从 onPostData 返回的错误不会影响循环,但它们可以通过两种方式向用户展示。

使用 ReadyFormErrorMessages

这个Widget可以显示提交错误信息,你也可以使用自定义构建器来自定义UI。

如果你使用了构建器,你还可以访问无效字段。

return ReadyForm(
  onPostData: () async {
    /// 提交你的数据
    return OnPostDataResult({
      "email": "该电子邮件已存在"
    });
  },
  child: ListView(
    children: [
      ReadyFormErrorMessages(),
      TextFormField(),
      TextFormField(),
      TextFormField(),
      TextFormField(),
      ProgressButton(child: Text("登录")),
    ],
  ),
);

使用 SubmitErrorMessageFor

这个Widget用于显示指定键的错误。

return ReadyForm(
  onPostData: () async {
    /// 提交你的数据
    return OnPostDataResult({
      "email": "该电子邮件已存在"
    });
  },
  child: ListView(
    children: [
      TextFormField(),
      SubmitErrorMessageFor(messageFor: 'email'),
      TextFormField(),
      TextFormField(),
      TextFormField(),
      ProgressButton(child: Text("登录")),
    ],
  ),
);

/// 或者如果你需要显示该字段的其他错误

return ReadyForm(
  onPostData: () async {
    return OnPostDataResult({"email": "该电子邮件已存在"});
  },
  child: ListView(
    children: [
      SubmitErrorMessageFor(
        messageFor: 'email',
        builder: (form, error) {
          return TextFormField(
            decoration: InputDecoration(
              errorText: error,
              hintText: "电子邮件",
            ),
          );
        },
      ),
      TextFormField(),
      TextFormField(),
      TextFormField(),
      ProgressButton(child: Text("登录")),
    ],
  ),
);

示例代码

以下是完整的示例代码:

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const FormPage(),
    );
  }
}

class FormPage extends StatelessWidget {
  const FormPage({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: ReadyForm(
        autoValidateMode: FormAutoValidateMode.onSubmit,
        onPostData: () async {
          await Future.delayed(const Duration(milliseconds: 300));
          return OnPostDataResult({"email": "该电子邮件已存在"});
        },
        child: ListView(
          padding: const EdgeInsets.all(20),
          children: [
            SubmitErrorMessageFor(
              messageFor: 'email',
              builder: (form, error) {
                return TextFormField(
                  decoration: InputDecoration(
                    errorText: error,
                    hintText: "电子邮件",
                  ),
                );
              },
            ),
            TextFormField(),
            const SubmitErrorMessageFor(messageFor: 'email'),
            TextFormField(),
            TextFormField(),
            TextFormField(),
            TextFormField(),
            TextFormField(),
            ProgressButton(
              onPressed: () async {
                await Future.delayed(const Duration(seconds: 3));
              },
              child: const Text("登录"),
            )
          ],
        ),
      ),
    );
  }
}

更多关于Flutter表单验证插件ready_form的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter表单验证插件ready_form的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用ready_form插件进行表单验证的代码示例。ready_form是一个方便的插件,可以帮助你轻松地进行表单验证。

首先,确保你已经在pubspec.yaml文件中添加了ready_form依赖:

dependencies:
  flutter:
    sdk: flutter
  ready_form: ^最新版本号  # 请替换为最新的版本号

然后,运行flutter pub get来安装依赖。

下面是一个完整的示例,展示了如何使用ready_form进行表单验证:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _formKey = GlobalKey<FormState>();
  final _formValidator = FormValidator();

  String? email;
  String? password;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Form Validation with ready_form'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          validator: (values) {
            return _formValidator.validate(values).errors;
          },
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              TextFormField(
                decoration: InputDecoration(labelText: 'Email'),
                validator: (value) {
                  return _formValidator.validateField('email', value) ?? null;
                },
                onSaved: (value) {
                  email = value;
                },
              ),
              TextFormField(
                decoration: InputDecoration(labelText: 'Password'),
                obscureText: true,
                validator: (value) {
                  return _formValidator.validateField('password', value) ?? null;
                },
                onSaved: (value) {
                  password = value;
                },
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () async {
                  final result = await _formValidator.validateForm({
                    'email': email,
                    'password': password,
                  });

                  if (result.isValid) {
                    // Handle valid form submission
                    print('Form is valid. Email: $email, Password: $password');
                  } else {
                    // Handle form errors
                    result.errors.forEach((field, errors) {
                      errors.forEach((error) {
                        ScaffoldMessenger.of(context).showSnackBar(
                          SnackBar(content: Text("$field: $error")),
                        );
                      });
                    });
                  }
                },
                child: Text('Submit'),
              ),
            ],
          ),
        ),
      ),
    );
  }

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

    // Define validation rules
    _formValidator.addField('email', [
      RequiredValidator(errorText: 'Email is required'),
      EmailValidator(errorText: 'Invalid email address'),
    ]);

    _formValidator.addField('password', [
      RequiredValidator(errorText: 'Password is required'),
      MinLengthValidator(minLength: 6, errorText: 'Password must be at least 6 characters long'),
    ]);
  }
}

在这个示例中,我们定义了一个简单的表单,包含两个字段:电子邮件和密码。我们使用ready_form插件来添加验证规则。在initState方法中,我们为这两个字段添加了验证规则,例如电子邮件字段必须填写且格式正确,密码字段必须填写且至少包含6个字符。

当用户点击提交按钮时,验证逻辑会检查每个字段是否符合定义的规则,并在有错误时显示相应的SnackBar消息。

请根据你的具体需求调整验证规则和表单字段。

回到顶部