はじめに
Flutterでのフォームバリデーションの基盤を作成してみました。
バリデーションルール(ValidationRule)とバリデーター(Validator)を定義し、
各入力に対してルールを通じて検証(validate)する仕組みを実装しています。
見出し
- Validationの基盤を作成する流れ
- Validation rulesを作成
- 基盤となるValidatorを作成
- 作成したValidation rulesを使用し、TextField専用のValidatorを作成
参考コード
Validationの基盤を作成する流れ
Validation rulesを作成
core/validation/rules
配下にバリデーションルールを作成していきます。
※ 今回の例として、2つのValidation ruleを作成します。
※ 新たにルールが必要な場合は、core/validation/rules
配下に追加してください。
abstract
を使用して、Validation ruleで共通となるインターフェイスを作成します。
abstract class ValidationRule {
String? validate(String value);
String get errorMessage;
}
「必須」ルールとして、RequiredRuleを実装します。
ValidationRule
インターフェースをimplements
して、RequiredRule
クラスを作成します。
class RequiredRule implements ValidationRule {
@override
String? validate(String value) {
return value.trim().isEmpty ? errorMessage : null;
}
@override
String get errorMessage => '入力してください';
}
文字数制限ルールとして、LengthRuleを実装します。
RequiredRuleと同様に、ValidationRule
インターフェースをimplements
して、LengthRule
クラスを作成します。
class LengthRule implements ValidationRule {
final int? maxLength;
final int? minLength;
const LengthRule({this.maxLength, this.minLength});
@override
String? validate(String value) {
final trimmed = value.trim();
if (maxLength != null && trimmed.length > maxLength!) {
return '$maxLength文字以内で入力してください';
}
if (minLength != null && trimmed.length < minLength!) {
return '$minLength文字以上で入力してください';
}
return null;
}
@override
String get errorMessage => '文字数制限を超えています';
}
基礎のValidatorを作成
class Validator<T> {
final List<ValidationRule> rules;
const Validator(this.rules);
String? validate(T value) {
for (final rule in rules) {
final error = rule.validate(value.toString());
if (error != null) return error;
}
return null;
}
/// 指定された型のルールを取得
R? getRule<R extends ValidationRule>() {
for (final rule in rules) {
if (rule is R) {
return rule;
}
}
return null;
}
}
作成したValidation rulesを使用し、TextField専用のValidatorを作成
Validator
クラスを継承してTextFieldValidator
を作成します。
Validation rulesは、TextFieldValidator
のコンストラクタ時に、super([...])
を使用して親クラスのValidator
に渡します。
class TextFieldValidator extends Validator<String> {
TextFieldValidator({int? maxLength, int? minLength, bool required = true})
: super([
if (required) RequiredRule(),
if (maxLength != null || minLength != null)
LengthRule(maxLength: maxLength, minLength: minLength),
]);
int? get maxLength => getRule<LengthRule>()?.maxLength;
int? get minLength => getRule<LengthRule>()?.minLength;
@override
String? validate(String value) {
final trimmed = value.trim();
return super.validate(trimmed);
}
}
最後に
汎用的なValidationを作成してみました。
まだまだ改善が必要ようそうなので、更新していきたいです。