搜索插件、代码仓与 APP 分类

插件详情v1.10.0

go_form

一个用于在 Flutter 中管理输入字段状态和验证的通用控制器。支持初始值、验证、错误和焦点。

AndroidiOSWebmacOSWindowsLinux
近 30 天下载
409
喜欢数
5
Pub 分数
150

安装插件

flutter pub add go_form

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

go_form 是一个 Flutter/Dart 包,提供了一个通用控制器,用于管理表单输入状态、验证、错误和焦点。它通过提供初始值、实时验证、错误跟踪和焦点管理,简化了表单字段的处理。该包旨在实现干净、可重用的表单逻辑,减少样板代码并提升开发效率。该包支持所有主要平台,包括 Android、iOS、Web、macOS、Windows 和 Linux,非常适合跨平台应用。其轻量级且直观的 API 可轻松集成到现有表单中。

适合场景

  • 使用多个输入项管理动态表单
  • 实现实时验证
  • 处理表单提交并反馈错误
  • 创建可重用的表单组件
  • 简化跨屏幕的表单状态管理
  • 支持字段间的焦点导航

主要特点

  • 通用输入字段控制器
  • 实时验证支持
  • 错误消息管理
  • 输入字段的焦点控制
  • 初始值配置
  • 跨平台兼容性

适合对象

  • 在 Flutter 中构建复杂表单的开发者
  • 寻求可重用表单逻辑的团队
  • 需要强大输入验证的应用程序
  • 针对多个平台的项目
  • 希望代码量最少的前端开发人员

使用建议

  • 需要理解 Flutter 的状态管理
  • 可能需要额外的样式来定制UI
  • 不适合非常简单的单次表单
  • 依赖于正确的初始化以避免运行时错误
  • 仅限特定表单使用场景,缺乏更广泛的状态管理

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

GoForm

Available Translations:


Pub

GoForm is a powerful library for managing forms in Flutter.
It allows you to dynamically create, validate, and manage form state
without the need to manually handle controllers for each field.

Features of GoForm

  • Smart validation with minimal code
    GoForm automatically validates input using standard validators,
    eliminating the need to manually write validation logic for each field.

  • Flexibility for any field types
    Create any form elements — from simple text fields and checkboxes
    to complex file pickers and dropdown menus.
    GoForm seamlessly adapts to any UI structure.

  • Centralized error management
    Set and reset errors anywhere in your code,
    without needing to use setState().
    Error display is fully automated and updates without unnecessary re-renders.

  • Debounced value changes
    Fields can debounce rapid input changes using debounceDuration, reducing unnecessary processing or validations.

  • Asynchronous validation
    Add asyncValidator to a field to perform validation that requires waiting for server responses or background checks.
    Use formController.validateAsync() to trigger validation across all fields.

  • Advanced focus management
    The FormController provides built-in methods for controlling focus between fields:

    • focus(String name) – focuses the field with the given name.
    • unfocus(String name) – removes focus from the specified field.
    • unfocusAll() – removes focus from all fields.
    • focusNext(String name) – moves focus to the next field.
    • focusPrevious(String name) – moves focus to the previous field.
    • focusFirstError() – focuses the first field that has a validation error.
    • hasFocus(String name) – returns true if the field is currently focused.
    • hasError(String name) – returns true if the field currently has an error.

Comparison of standard Flutter tools and GoForm
Feature GoForm Standard Flutter
Field management Fields are registered automatically Each field requires a TextEditingController
Field flexibility Supports any fields (text, files, checkboxes) Only TextFormField and standard widgets
Error handling Errors are set via FormController.setError() Errors can only be handled in validator
Centralized state management A single FormController manages the entire form Field states must be tracked manually
Retrieving values formController.getValues() returns a Map<String, dynamic> Requires accessing TextEditingController.text
Resetting fields formController.resetAllFields() Controllers must be cleared manually
Handling server-side errors Errors can be set using setError() Errors must be stored in setState()

How to Install

Add the dependency to pubspec.yaml:

dependencies:
  go_form: latest_version

Replace latest_version with the latest version from pub.dev.

Quick Start

Creating a Form with Dynamic Fields

In DynamicForm, simply pass a list of fields and a controller:


final _formController = FormController();

@override
Widget build(BuildContext context) {
  return DynamicForm(
    controller: _formController,
    fields: [
      GoTextInput(
        name: 'email',
        label: 'Email',
        validator: (val) => val == null || val.isEmpty ? 'Enter your email' : null,
      ),
      GoTextInput(
        name: 'password',
        label: 'Password',
        validator: (val) => val == null || val.length < 6 ? 'Minimum 6 characters' : null,
      ),
    ],
  );
}
Validation Check Before Submission
void onSubmit() {
  if (_formController.validate()) {
    print(_formController.getValues()); // Retrieving form data  
  } else {
    print(_formController.errors); // Displaying errors 
  }
}
Focus and Scrolling Example

GoForm allows you to programmatically manage focus and scroll behavior:

GoTextInput(
  name: 'email',
  label: 'Email',
),
GoTextInput(
  name: 'password',
  label: 'Password',
),

To move focus to the next field:

ElevatedButton(
  onPressed: () {
    _formController.focusNext('email');
  },
  child: Text('Go to Password'),
);

To focus the first field with a validation error:

ElevatedButton(
  onPressed: () async {
    final isValid = await _formController.validateAsync();
    if (!isValid) {
      _formController.focusFirstError();
    }
  },
  child: Text('Validate and Focus Error'),
);

To scroll to the first field with an error:

ElevatedButton(
  onPressed: () async {
    final isValid = await _formController.validateAsync();
    if (!isValid) {
      _formController.scrollToFirstErrorField();
    }
  },
  child: Text('Validate and Scroll to Error'),
);

scrollToFirstErrorField() works with DynamicForm and assumes the form is wrapped in a scrollable container (e.g. SingleChildScrollView).

Adding Errors
void onLogin() async {
  final response = await AuthAPI.login(
    email: _formController.getFieldValue<String>('email'),
    password: _formController.getFieldValue<String>('password'),
  );

  if (response.hasError) {
    _formController.setError('email', response.errors['email']);
    _formController.setError('password', response.errors['password']);
  }
}
Resetting the Form
_formController.resetAllFields
(); // Очистка значений  
_formController.resetAllErrors
(); // Очистка ошибок  

Validation Triggers

GoForm provides fine-grained control over when validation occurs through ValidationTrigger enum:

Trigger When it fires Best for
onSubmit Only when validate() is called Non-critical fields, confirmation fields
onValueChange Every time the field value changes Password strength, real-time feedback
onFocusLost When field loses focus (blur) Email format, most standard fields
onFocusGained When field gains focus Special cases, clearing errors
onDebounceComplete After debounce period ends Search fields, API calls
manual Only when explicitly called Custom validation logic
Recommended Patterns
1. User-Friendly Form (Recommended for most cases)
2. Strict Real-Time Validation
3. Conservative Approach
FormController(
  defaultValidationTriggers: {ValidationTrigger.onSubmit},
  // Validate only when user tries to submit
);
4. Mixed Strategy (Advanced)
final controller = FormController(
defaultValidationTriggers: {ValidationTrigger.onFocusLost},
validateOnlyAfterFirstSubmit: true,
);

// Email: standard behavior
controller.addTextField<String>(name: 'email', validator: emailValidator);

// Password: real-time validation for security
controller.addTextField<String>(
name: 'password',
validator: passwordValidator,
validationTriggers: {ValidationTrigger.onValueChange},
);

// Terms: only on submit (avoid annoyance)
controller.addTextField<bool>(
name: 'acceptTerms',
validator: termsValidator,
validationTriggers: {ValidationTrigger.onSubmit},
);

How to Create a Custom Field?

Simply extend FormFieldModelBase<T> and implement build():

class GoTextInput extends FormFieldModelBase<String> {
  final String label;

  GoTextInput({required super.name, super.validator, required this.label});

  @override
  Widget build(BuildContext context, FieldController controller) {
    return TextField(
      onChanged: controller.onChange,
      controller: controller.textController,
      decoration: InputDecoration(
        labelText: label,
        errorText: controller.error,
      ),
    );
  }
}
One-Time Initialization (onInit)

You can override the onInit method inside your custom field to perform one-time setup logic.
This is useful for asynchronous operations, such as fetching initial data or triggering a service.

class MyCustomField extends FormFieldModelBase<String> {
  @override
  void onInit(FieldController<String> controller) {
    controller.setValue('initial_value');
  }

  @override
  Widget build(BuildContext context, FieldController<String> controller) {
    // widget build logic here
  }
}

About the author

My telegram channel - @kotelnikoff_dev

Contributions

Contributions are welcome! Feel free to open issues or create pull requests on the GitHub repository.

所属分类

源码仓库

使用此插件的项目

暂无相关数据。