📱

Flutter:バリデーション付きForm作成

2024/05/25に公開

1:GlobalKey作成

  • StatefulWidgetと対になるStateを例として,作成する.

State側に以下のようなプロパティ値を設定する.

final _formKey = GlobalKey<FormState>();

2:入力フォームを作成する

全体像


  Widget build(BuildContext context) {
    return SingleChildScrollView(
        child: Column(
      children: [
        // 入力リセットボタン&入力形式の変更
        Container(
            ・・・(省略)
        )
        // 横線
        const Divider(
          color: CommonColors.primaryColor,
          thickness: 5,
        ),
        // 入力フォームとボタン
        Container(
            padding: const EdgeInsets.all(24),
            child: Form(
                key: _formKey,
                child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                    //ここにフィールドとボタンを入力する.
                    ]
            )
        )
      ]
    );               

2.1:フォームの設定

  • Formインスタンスの作成
  • 1で定義した_formKeyを,Formのkeyに設定する.
Form(
    key: _formKey,
    child: Column(
    mainAxisAlignment: MainAxisAlignment.start,
    children: <Widget>[
        //ここにフィールドとボタンを入力する.
    ]
)

2.2:入力フォームを加える

AutoSizeTextFormField(
    minLines: 1,
    maxLines: 20,
    controller: ingredientsController,
    decoration: const InputDecoration(
        labelText: 'example',
        isDense: true,
        border: OutlineInputBorder()),
    validator: (value) {
        return _validateInputHasText(value: value); // この関数については下記に示す.
    },
)

2.3:バリデーション処理の設定

公式ドキュメントのように,TextFormFieldにバリデーション処理を直書きしても良いが,
複数入力欄が存在する場合,バリデーション関数を記述し,それを用いるのが良いでしょう.

バリデーション関数は,null許容型で返り値がString型の関数にする
入力値に異常があれば何かしらのString値を,異常がなければnullを返す

String? _validateInputHasText({required value}) {
    if (value == null || value.isEmpty) {
      return 'テキストを入力してください';
    }
    return null;
}

2.4:form提出ボタンの設定

  • onPressed内に,フォーム有効かどうかの判別処理を記入する.
// フォーム内容が有効である場合
if (_formKey.currentState!.validate()) {
    ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('データを処理中')));
    // ここに,提出の処理を書く
}
  • 全体像
ElevatedButton(
    style: RecipeAddPageButton.style,
    child: _buttonPressed
        ? const CircularProgressIndicator(
            strokeWidth: 2.0, color: CommonColors.textColor)
        : const Text('このレシピを追加する',
            style: elevatedButtonTextStyle),
        onPressed: () {
          // フォームが有効な場合
          if (_formKey.currentState!.validate()) {
            ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('データを処理中')));
            _addRecipeToFirestore();
          }
        },
)

参考資料

  • (公式ドキュメント)

https://docs.flutter.dev/cookbook/forms/validation

Discussion