0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutter】項目バリデーションで、項目名を埋め込んだメッセージを表示する

Posted at

やりたいこと

テキスト入力の項目で、以下のように必須エラーなどのバリデーションメッセージを出しているが、メッセージを項目ごとに定義せずに、「〜は必須です」の1種類だけを登録し、「〜」部分に項目名を埋め込みたい。
Screenshot_1699525584.png

バリデーションで固定のメッセージを表示すること自体は、すでに以下を参考にさせていただき、「form_field_validator」を利用して、できている状態です。

自分で、元のValidatorを継承したValidatorをつくる

ChatGPTさんに相談しながら解決した方法です。もしかするともっと良い方法があるのかもしれないですが・・・。
例えば、RequiredValidatorのエラーメッセージに項目名を埋め込みたい場合は、RequiredValidatorを継承して、コンストラクタの引数に項目名を取る、自作のValidatorを作成しました。

///必須バリデータ(項目名をエラーメッセージに埋め込む)
class CustomRequiredValidator extends RequiredValidator {
  final String filedName;

  CustomRequiredValidator(
      {String errorText = 'この項目は必須です', required this.filedName})
      : super(errorText: '$filedName は必須です');
}

「form_field_validator」のライブラリで定義されている「RequiredValidator」のソースを見ると、isValidでない場合は、以下のようにerrorTextを返しているので、errorTextに項目名を埋め込んだメッセージを渡すことで、うまく埋め込まれているようです。
※RequiredValidatorのソース

class RequiredValidator extends TextFieldValidator {
  RequiredValidator({required String errorText}) : super(errorText);

  @override
  bool get ignoreEmptyValues => false;

  @override
  bool isValid(String? value) {
    return value!.isNotEmpty;
  }

  @override
  String? call(String? value) {
    return isValid(value) ? null : errorText;
  }
}

他のバリデータと組み合わせる

本来は、必須かつ200文字以内というバリデーションをかけたかったため、同様にMaxLengthValidatorを継承して、CustomMaxLengthValidatorというものも作り、
これらを囲んだMultiValidatorを返すメソッドを新しいクラスの中に作りました。(今思うと、customMultiValidatorではなく、normalTextValidatorのような名前の方がよかったかもしれません。)

///通常の必須テキスト項目用バリデータ(必須、200文字以内)
class CustomValidators {
  static MultiValidator customMultiValidator({required String fieldName}) {
    return MultiValidator([
      CustomRequiredValidator(filedName: fieldName),
      CustomMaxLengthValidator(filedName: fieldName, max: 200)
    ]);
  }
}

呼び出す

この新しく作ったcustomMultiValidatorを、TextFormFieldのvalidatorの値として呼び出します。「fieldName」にメッセージに埋め込みたい項目名を設定します。

 TextFormField(
                      decoration:
                          const InputDecoration(labelText: 'メールで受信した「共有ID」を入力'),
                      onChanged: (String value) {
                        setState(() {
                          listId = value;
                        });
                      },
                      validator: CustomValidators.customMultiValidator(
                          fieldName: '共有ID'),
                    ),
                  )
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?