パッケージ、リポジトリ、アプリカテゴリを検索

form_model のカバー
パッケージ詳細v1.0.2+2

form_model

Flutterアプリケーション向けの強力で柔軟なフォーム検証パッケージ。

AndroidiOSWebmacOSWindowsLinux
30日間ダウンロード
11
いいね数
8
Pub ポイント
160

パッケージをインストール

flutter pub add form_model

パッケージ概要

公開情報に基づく選定ガイドです。参考としてご利用ください。

form_model は、フォームの作成、検証、状態管理を簡素化する強力なFlutterパッケージです。リアルタイムでの検証、自動フォーマット、マスキングを内蔵した柔軟なフレームワークを提供し、動的なフォームの構築を可能にします。開発者は、フォームフィールドを簡単に定義し、バリデーターを適用し、最小限のボイラープレートで変更に反応できます。このパッケージはすべての主要プラットフォームとシームレスに統合され、一貫したフォーム動作を必要とするクロスプラットフォームアプリケーションに最適です。

用途

  • 動的フォーム生成
  • リアルタイム入力検証
  • ユーザー入力の自動フォーマット
  • クロスプラットフォーム形式の一貫性
  • 複雑なフォーム状態の管理

主な機能

  • 組み込みの検証ルール
  • 自動フォーマットとマスキング
  • リアクティブフォームの状態更新
  • 拡張可能なフィールドタイプ
  • 最小限のボイラープレート設定

適している対象

  • 複雑なフォームを構築する開発者
  • 厳密な入力検証を必要とするアプリ
  • クロスプラットフォーム Flutter プロジェクト
  • 保守可能なフォームコードを優先するチーム

注意事項

  • リアクティブプログラミングの理解が必要です
  • 高度な機能の習得曲線
  • 人気のある代替品と比べてドキュメントが限られている

元の README

関連するソースリポジトリの README 原文のスナップショットです。最新の内容はリポジトリをご覧ください。

form_model

A powerful and flexible form validation package for Flutter applications.

flutter platform pub package BSD-2-Clause

Features

  • 🚀 Easy-to-use form validation
  • 🎯 Single-responsibility validators for clear, maintainable code
  • 🌐 Built-in internationalization support with fallback locales
  • 🧩 Extensible with custom validators and translations
  • 🔄 Immutable state management
  • 🔗 Integrates seamlessly with Flutter widgets
  • 🎛️ Advanced form controls (date pickers, multi-select, etc.)
  • 🧬 Works great with state management solutions like BLoC
  • 🧪 Comprehensive test coverage

Screenshots

Here are some screenshots of form_model in action:

Screenshot 1 Screenshot 2 Screenshot 3 Screenshot 4 Screenshot 5 Screenshot 6 Screenshot 7

Installation

Add form_model to your pubspec.yaml file:

dependencies:
  form_model: ^1.0.2+2

Then run:

flutter pub get

Basic Usage

Here's a simple example of how to use form_model:

import 'package:form_model/form_model.dart';

// Create a FormModel for an email field
final emailModel = FormModel<String>(
  validators: [RequiredValidator(), EmailValidator()],
);

// Set a value and validate
final validatedModel = emailModel.setValue('user@example.com').validate();

if (validatedModel.isValid) {
  print('Email is valid: ${validatedModel.value}');
} else {
  print('Validation error: ${validatedModel.error?.translatedMessage}');
}

Note: Each validator is responsible for checking one specific aspect of the input and returns only one type of error. This principle should be followed when creating custom validators for your application.

Advanced Usage

For more complex forms, you can combine multiple FormModel instances. Here's an example with a password confirmation field:

class RegistrationForm {
  final FormModel<String> username;
  final FormModel<String> email;
  final FormModel<String> password;
  late final FormModel<String> confirmPassword;

  RegistrationForm({
    required this.username,
    required this.email,
    required this.password,
  }) {
    confirmPassword = FormModel<String>(
      validators: [
        RequiredValidator(),
        StringConfirmPasswordMatchValidator(matchingValue: password.value),
      ],
    );
  }

  bool get isValid => 
    username.isValid && 
    email.isValid && 
    password.isValid && 
    confirmPassword.isValid;

  void validate() {
    username.validate();
    email.validate();
    password.validate();
    confirmPassword = confirmPassword
      .replaceValidator(
        predicate: (validator) => validator is StringConfirmPasswordMatchValidator,
        newValidator: StringConfirmPasswordMatchValidator(matchingValue: password.value),
      )
      .validate();
  }

  void updatePassword(String newPassword) {
    password.setValue(newPassword);
    // Update confirm password validator
    confirmPassword = confirmPassword
      .replaceValidator(
        predicate: (validator) => validator is StringConfirmPasswordMatchValidator,
        newValidator: StringConfirmPasswordMatchValidator(matchingValue: newPassword),
      );
  }
}

This example demonstrates how to properly set up and update a password match validator.

Validators

form_model includes a wide range of built-in validators, each responsible for a single aspect of validation:

  • RequiredValidator
  • EmailValidator
  • StringMinLengthValidator
  • StringMaxLengthValidator
  • PasswordLengthValidator
  • PasswordUppercaseValidator
  • PasswordLowercaseValidator
  • PasswordNumberValidator
  • PasswordSpecialCharValidator
  • DateTimeValidator
  • StringDateTimeAgeMinValidator
  • StringDateTimeAgeMaxValidator
  • StringPhoneNumberValidator
  • StringNumbersOnlyValidator
  • StringTextOnlyValidator
  • StringUrlValidator
  • StringWordsCountMinValidator
  • StringWordsCountMaxValidator
  • StringCreditCardValidator
  • CustomEqualValidator
  • StringCustomPatternValidator
  • IpAddressValidator
  • Ipv6AddressValidator
  • StringNumMinValidator
  • StringNumMaxValidator
  • StringContainsValidator
  • StringNotContainsValidator
  • FileTypeValidator
  • FileSizeValidator
  • BoolTrueValidator
  • BoolFalseValidator
  • BoolAgreeToTermsAndConditionsValidator

Each validator focuses on a single validation rule, adhering to the single-responsibility principle.

Internationalization

form_model supports multiple languages out of the box:

// Set the current locale
FormModelLocalizations().setCurrentLocale(const Locale('es'));

// Get a translated error message
final errorMessage = emailModel.error?.translatedMessage;
Supported Languages

form_model supports the following languages:

  • English (en)
  • Spanish (es)
  • French (fr)
  • German (de)
  • Arabic (ar)
  • Chinese (Simplified) (zh_CN)
  • Hindi (hi)
  • Italian (it)
  • Japanese (ja)
  • Korean (ko)
  • Dutch (nl)
  • Portuguese (pt)
  • Russian (ru)
  • Turkish (tr)
  • Ukrainian (uk)
  • Vietnamese (vi)
  • Polish (pl)
  • Swedish (sv)

Integration with BLoC and Freezed

form_model integrates seamlessly with the BLoC pattern. Here's an example of a Flutter BLoC state using Freezed:

@freezed
class RegistrationState with _$RegistrationState {
  const factory RegistrationState({
    @Default(FormModel<String>(validators: [RequiredValidator()]))
    FormModel<String> username,
    
    @Default(FormModel<String>(validators: [RequiredValidator(), EmailValidator()]))
    FormModel<String> email,
    
    @Default(FormModel<String>(validators: [
      RequiredValidator(),
      PasswordLengthValidator(minLength: 8),
      PasswordUppercaseValidator(),
      PasswordLowercaseValidator(),
      PasswordNumberValidator(),
      PasswordSpecialCharValidator(),
    ]))
    FormModel<String> password,
    
    @Default(false) bool isSubmitting,
    @Default(false) bool isSuccess,
    String? errorMessage,
  }) = _RegistrationState;
}

Custom Validators

Custom validators allow you to create specific validation rules not covered by built-in validators. Here's a simple example of a custom validator that checks if a string starts with a specific prefix:

String? validatePrefix(String? value) {
  const requiredPrefix = 'USER_';
  if (value == null || !value.startsWith(requiredPrefix)) {
    return 'Value must start with $requiredPrefix';
  }
  return null;
}

final userIdModel = FormModel<String>(
  validators: [
    RequiredValidator(),
    CustomValidator(validator: validatePrefix),
  ],
);

// Usage
void validateUserId(String userId) {
  final validatedModel = userIdModel.setValue(userId).validate();
  if (validatedModel.isValid) {
    print('Valid User ID: ${validatedModel.value}');
  } else {
    print('Invalid User ID: ${validatedModel.error?.translatedMessage}');
  }
}

// Example
validateUserId('USER_123'); // Valid
validateUserId('ADMIN_456'); // Invalid

This custom validator checks if the input string starts with the prefix 'USER_'. It demonstrates how you can easily create application-specific validation logic using custom validators.

Custom validation functions should return a string with an error message if validation fails, or null if it passes. This approach allows you to extend form_model's capabilities to suit your specific needs while maintaining clean and modular code.

Working with Custom Objects

form_model can handle complex custom objects as well. Here's an example using an Address class:

class Address {
  final String street;
  final String city;

  Address({required this.street, required this.city});
}

String? validateStreet(Address? value) {
  if (value == null || value.street.isEmpty) return 'Street is required';
  return null;
}

String? validateCity(Address? value) {
  if (value == null || value.city.isEmpty) return 'City is required';
  return null;
}

final addressModel = FormModel<Address>(
  validators: [
    CustomValidator(validator: validateStreet),
    CustomValidator(validator: validateCity),
  ],
);

// Usage
void updateAddress(String street, String city) {
  final newAddress = Address(street: street, city: city);
  addressModel.setValue(newAddress).validate();
}

This approach allows you to validate complex objects while keeping individual validation rules separate and focused.

Custom Translations

You can set custom translations for both custom and predefined error messages:

void setCustomTranslations() {
  // Set custom translation for a custom error
  FormModelLocalizations().setCustomErrorTranslations(
    'en',
    const CustomFormErrorKey('password_no_exclamation'),
    'Password must contain an exclamation mark',
  );

  // Override translation for a predefined error
  FormModelLocalizations().setCustomErrorTranslations(
    'en',
    const PredefinedFormErrorKey(PredefinedFormErrorType.required),
    'This field cannot be left empty',
  );

  // Set translations for other languages
  FormModelLocalizations().setCustomErrorTranslations(
    'es',
    const CustomFormErrorKey('password_no_exclamation'),
    'La contraseña debe contener un signo de exclamación',
  );

  FormModelLocalizations().setCustomErrorTranslations(
    'es',
    const PredefinedFormErrorKey(PredefinedFormErrorType.required),
    'Este campo no puede estar vacío',
  );
}

Call this function early in your app's lifecycle to set up custom translations.

Contributing

Contributions are welcome! Please read our contributing guidelines to get started. The package already has comprehensive test coverage, but additional tests for new features are always appreciated.

License

This project is licensed under the 3-Clause BSD License - see the LICENSE file for details.

カテゴリー

ソースリポジトリ

このパッケージを使用しているプロジェクト

データはまだありません。