Flutter表单管理插件mengle_forms的使用

Flutter表单管理插件mengle_forms的使用

本节提供了在您的Flutter项目中设置和使用Forms包的分步指南。

第一步:添加依赖项

为了使用Forms包,您需要将其作为依赖项添加到pubspec.yaml文件中:

dependencies:
  forms: ^latest_version

latest_version替换为您想要使用的Forms版本号。

第二步:安装包

在添加依赖项后,可以通过运行以下命令在终端中安装它:

flutter pub get

第三步:导入包

现在,您可以在Dart文件中导入Forms包:

import 'package:forms/forms.dart';

第四步:使用包

您可以使用Forms包在Flutter应用程序中创建表单。这是一个基本示例:

Forms(
  formElements: <FormControls>[...], // 表单控件列表
  onChanged: (value) {...}, // 处理表单更改的函数
  padding: 10.0, // 表单周围的填充
  formMap: {...}, // 表单值的映射
  errorMessages: {...}, // 错误消息的映射
  validations: {...}, // 验证规则的映射
  decorations: {...}, // 装饰设置的映射
  hideSaveBtn: false, // 是否隐藏保存按钮
  buttonSave: CustomSaveButton(), // 自定义保存按钮小部件
  actionSave: (formKey) {...}, // 处理表单提交的函数
);

这样,您就可以开始使用Forms包构建表单了。有关更详细的用法和自定义选项,请参阅此文档的其他部分。

Forms 使用文档

Forms 是一个Flutter包,它提供了一种简单且灵活的方式来构建Flutter应用中的表单。它支持多种表单控件,并允许轻松进行定制和验证。

API 参考

Forms

Forms 包中的主要类。用于创建表单。

属性
  • formElements: 由 FormControls 组成的表单列表。
  • onChanged: 表单更改时调用的函数。
  • padding: 表单周围的填充。
  • formMap: 表单值的映射。
  • errorMessages: 错误消息的映射。
  • validations: 验证规则的映射。
  • decorations: 装饰设置的映射。
  • hideSaveBtn: 指示是否隐藏保存按钮的布尔值。
  • buttonSave: 自定义保存按钮小部件。
  • actionSave: 处理表单提交的函数。

FormControls

表示表单控件的类。

属性
  • controlType: 表单控件的类型(例如,文本输入、下拉菜单、切换开关等)。
  • controlConfig: 控件的配置(例如,标签、值、可见性等)。

FormControlTypes

表单控件类型的枚举。

FormControlConfig

定义表单控件配置的类。

属性
  • isVisible: 指示控件是否可见的布尔值。
  • label: 控件的标签。
  • value: 控件的初始值。

请注意,这只是API参考的简化版。实际API可能包含额外的类、方法和属性。

基本用法

要创建表单,您需要实例化 Forms 类并传递必要的参数。这里是一个例子:

Forms(
  formElements: <FormControls>[...], // 表单控件列表
  onChanged: (value) {...}, // 处理表单更改的函数
  padding: 10.0, // 表单周围的填充
  formMap: {...}, // 表单值的映射
  errorMessages: {...}, // 错误消息的映射
  validations: {...}, // 验证规则的映射
  decorations: {...}, // 装饰设置的映射
  hideSaveBtn: false, // 是否隐藏保存按钮
  actionSave: (formKey) {...}, // 处理表单提交的函数
  actionButtonTextStyle: ButtonStyle(...), // 自定义保存按钮样式
);

表单控件

Forms 支持多种表单控件,这些控件在 formElements 参数中定义。每个表单控件都是 FormControls 类的一个实例,它接受 controlTypecontrolConfig

这里是一个文本输入控件的例子:

FormControls(
  controlType: FormControlTypes.textInput,
  controlConfig: FormControlConfig(
    isVisible: true,
    label: '用户名',
    value: '默认值',
    // 其他配置...
  ),
)

controlType 决定了表单控件的类型(例如,文本输入、下拉菜单、切换开关等),而 controlConfig 定义了控件的配置(例如,标签、值、可见性等)。

验证

Forms 通过 validations 参数支持表单验证。这是一个映射,键是表单控件的名称,值是验证规则。

这里是一个验证规则的例子:

validations: {
  'username': (value) {
    if (value.isEmpty) {
      return '请输入您的用户名。';
    }
    return null;
  },
}

保存表单

当用户按下保存按钮时,actionSave 函数会被调用。该函数接收表单键,可以用来验证和保存表单。

这里是一个保存函数的例子:

actionSave: (formKey) {
  if (formKey.currentState!.validate()) {
    formKey.currentState!.save();
    // 处理表单提交...
  }
}

这就是Forms的基本用法。有关更高级的用法和自定义选项,请参阅 forms 包的源代码和注释。

额外信息

更多信息

有关Forms包的更多详细信息,请参阅 forms 包的源代码和注释。您还可以在那里找到更多的使用示例和高级定制选项。

贡献

我们欢迎社区的贡献。如果您想贡献,请先fork仓库并提交pull请求。在提交pull请求之前,请确保彻底测试您的更改。

提交问题

如果您遇到任何问题或有改进建议,请在GitHub仓库上提交issue。提交问题时,请尽可能提供有关问题的详细信息,包括重现步骤和任何错误消息。

作者回应

我们努力尽快响应所有问题和pull请求。但是,请记住,这是一项开源项目,我们是在业余时间完成的。感谢您的耐心等待。

更多

我们一直在寻找改进Forms的方法。如果您有任何想法或建议,请随时与我们分享。我们也开放合作,如果您有兴趣与我们一起在这个项目上工作,请联系我们。

感谢您使用Forms!


完整示例代码

以下是完整的示例代码,展示了如何使用 mengle_forms 插件:

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

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

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<GroupedListSingleSelectItems> getList() {
    var groupedListItems = <GroupedListSingleSelectItems>[];
    var item = GroupedListSingleSelectItems(
      key: '1',
      label: '标题',
      description: '描述',
      value: 1,
      icon: null,
      group: '现有列表',
      isOther: false,
    );

    groupedListItems.add(item);

    var item2 = GroupedListSingleSelectItems(
      key: '2',
      label: '分类名称',
      description: '',
      value: 2,
      icon: null,
      isOther: true,
      group: '现有列表',
    );

    groupedListItems.add(item2);

    return groupedListItems;
  }

  Future<bool> _save(GlobalKey<FormState> form) async {
    if (inputValue.isEmpty) return false;
    return true;
  }

  dynamic response;
  bool? isTextInputValid;
  String inputValue = "Value 1";
  bool? isGroupedListValid;
  dynamic groupedListValue;
  bool switchValue = false;
  String email = 'example@example.com';
  String? username;

  List<FormControls> formElements = [];
  List<FormControls> addFormElements() {
    formElements.clear();

    formElements.add(
      FormControls(
        FormControlTypes.password,
        ControlConfig(
          key: 'secretCode',
          label: '密钥',
          placeholder: '输入密码',
          maxLines: 1,
          isRequired: true,
          value: inputValue,
          isValid: isTextInputValid,
          alreadyExists: ["secret", "Value 1"],
          onChange: (ControlConfig config) => {
            setState(() => {
                  inputValue = config.value.toString().trim(),
                  isTextInputValid = config.isValid,
                }),
          },
        ),
      ),
    );

    formElements.add(
      FormControls(
        FormControlTypes.textInput,
        ControlConfig(
          key: 'email',
          value: email,
          label: '邮箱',
          isRequired: true,
          isValid: isEmailValid(email),
          inputType: TextInputType.emailAddress,
          placeholder: '输入邮箱地址',
          alreadyExists: ["example@example.com"],
          onChange: (ControlConfig config) => {
            setState(() => {
                  email = config.value,
                  config.isValid = isEmailValid(email),
                }),
          },
        ),
      ),
    );

    formElements.add(
      FormControls(
        FormControlTypes.textInput,
        ControlConfig(
          key: 'username',
          label: '姓名',
          placeholder: '输入用户名',
          isRequired: true,
          isValid: username != null,
          value: username,
          alreadyExists: ["user", "user 1"],
          onChange: (ControlConfig config) =>
              {setState(() => username = config.value.toString().trim())},
        ),
      ),
    );

    formElements.add(FormControls(
        FormControlTypes.groupedListSubForm,
        ControlConfig(
          showMainHeader: false,
          label: '列表',
          key: 'list',
          helpText: '从列表中选择',
          value: groupedListValue,
          isRequired: true,
          isValid: isGroupedListValid,
          isGrouped: true,
          isMultiselect: false,
          onChange: (config) {},
          onSave: (config) {
            groupedListValue = config.value;
            config.isValid = isGroupedListValid;
          },
          groupedListItems: getList(),
        )));

    formElements.add(
      FormControls(
        FormControlTypes.question,
        ControlConfig(
          label: '这个表单很棒吗?',
          hideModalTitle: false,
          isRequired: true,
          isValid: true,
          key: 'question1',
          placeholder: '请选择是或非常棒。',
          icon: Icons.question_mark,
          questionConfig: QuestionConfig(
            value: null,
            message: '这里还有更多信息,真是太棒了!',
            cancelButtonText: '非常棒',
            continueButtonText: '是',
            onConfirm: (String value) async {},
          ),
        ),
      ),
    );

    formElements.add(
      FormControls(
        FormControlTypes.toggleSwitch,
        ControlConfig(
          label: '外面在下雨吗?',
          key: 'raningkey',
          value: switchValue,
          onChange: (value) {
            switchValue = value;
          },
        ),
      ),
    );

    return formElements;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Forms(
                formElements: addFormElements(),
                onChanged: (dynamic response) {
                  this.response = response;
                },
                actionSave: (form) async => {await _save(form)},
              ),
            ],
          ),
        ),
      ),
    );
  }
}

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

1 回复

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


mengle_forms 是一个用于 Flutter 应用的表单管理插件,它可以帮助开发者更轻松地处理表单验证、状态管理以及表单提交等操作。以下是如何使用 mengle_forms 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 mengle_forms 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  mengle_forms: ^1.0.0  # 请使用最新版本

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

2. 导入插件

在你的 Dart 文件中导入 mengle_forms 插件:

import 'package:mengle_forms/mengle_forms.dart';

3. 创建表单模型

mengle_forms 使用表单模型来管理表单的状态和验证规则。你可以通过继承 FormModel 类来创建自定义的表单模型。

class LoginFormModel extends FormModel {
  final TextFieldModel email = TextFieldModel(
    validators: [
      RequiredValidator(errorText: 'Email is required'),
      EmailValidator(errorText: 'Invalid email format'),
    ],
  );

  final TextFieldModel password = TextFieldModel(
    validators: [
      RequiredValidator(errorText: 'Password is required'),
      MinLengthValidator(6, errorText: 'Password must be at least 6 characters'),
    ],
  );

  [@override](/user/override)
  List<FieldModel> get fields => [email, password];
}

4. 使用表单模型

在 UI 中使用 FormModel 来管理表单的状态和验证。

class LoginPage extends StatelessWidget {
  final LoginFormModel formModel = LoginFormModel();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(
                labelText: 'Email',
                errorText: formModel.email.errorText,
              ),
              onChanged: (value) {
                formModel.email.value = value;
                formModel.validate();
              },
            ),
            SizedBox(height: 16),
            TextField(
              obscureText: true,
              decoration: InputDecoration(
                labelText: 'Password',
                errorText: formModel.password.errorText,
              ),
              onChanged: (value) {
                formModel.password.value = value;
                formModel.validate();
              },
            ),
            SizedBox(height: 32),
            ElevatedButton(
              onPressed: () {
                if (formModel.isValid) {
                  // 表单验证通过,执行登录操作
                  print('Email: ${formModel.email.value}');
                  print('Password: ${formModel.password.value}');
                } else {
                  // 表单验证失败,显示错误信息
                  formModel.validate();
                }
              },
              child: Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

5. 表单验证

mengle_forms 提供了多种内置的验证器,如 RequiredValidatorEmailValidatorMinLengthValidator 等。你也可以自定义验证器。

6. 表单提交

在表单提交时,你可以通过 formModel.isValid 来检查表单是否通过验证。如果通过验证,可以执行相应的操作,如提交数据到服务器。

7. 表单重置

你可以通过调用 formModel.reset() 方法来重置表单的状态。

ElevatedButton(
  onPressed: () {
    formModel.reset();
  },
  child: Text('Reset'),
);

8. 自定义验证器

你可以通过继承 Validator 类来创建自定义的验证器。

class CustomValidator extends Validator {
  [@override](/user/override)
  String? validate(String? value) {
    if (value == null || value.isEmpty) {
      return 'This field is required';
    }
    if (value.length < 5) {
      return 'Value must be at least 5 characters';
    }
    return null;
  }
}

9. 表单字段的依赖验证

mengle_forms 还支持表单字段之间的依赖验证。例如,你可以根据一个字段的值来验证另一个字段。

class SignUpFormModel extends FormModel {
  final TextFieldModel password = TextFieldModel(
    validators: [
      RequiredValidator(errorText: 'Password is required'),
      MinLengthValidator(6, errorText: 'Password must be at least 6 characters'),
    ],
  );

  final TextFieldModel confirmPassword = TextFieldModel(
    validators: [
      RequiredValidator(errorText: 'Confirm Password is required'),
      CustomValidator(
        errorText: 'Passwords do not match',
        validate: (value) => value == password.value,
      ),
    ],
  );

  [@override](/user/override)
  List<FieldModel> get fields => [password, confirmPassword];
}

10. 表单字段的联动

mengle_forms 还支持表单字段之间的联动。例如,当某个字段的值发生变化时,可以自动更新其他字段的状态。

class ProfileFormModel extends FormModel {
  final TextFieldModel firstName = TextFieldModel(
    validators: [
      RequiredValidator(errorText: 'First Name is required'),
    ],
  );

  final TextFieldModel lastName = TextFieldModel(
    validators: [
      RequiredValidator(errorText: 'Last Name is required'),
    ],
  );

  final TextFieldModel fullName = TextFieldModel();

  [@override](/user/override)
  List<FieldModel> get fields => [firstName, lastName, fullName];

  ProfileFormModel() {
    firstName.addListener(() {
      fullName.value = '${firstName.value} ${lastName.value}';
    });

    lastName.addListener(() {
      fullName.value = '${firstName.value} ${lastName.value}';
    });
  }
}
回到顶部