프로그래밍 공부 메모/flutter

Form + TextFormField 유효성 검사

jjs815 2022. 7. 10. 22:46

텍스트를 입력받는 input필드가 몇개 없다면 개별 컨드롤러를 생성하여 관리하면 된다

하지만 사용자로 부터 입력 받아야할 텍스트 필다가 많다면 이것 또한 관리하는게 힘들어 질 수 있다

그래서 Form 위젯과 하위에 TextFormField 위젯을 같이 사용하여

입력받는 상태값과 유효성 검사를 한번에 관리할 수 있는데 아래의 예제를 참고!

그리고 TextFormField 에 접근하기 위해선 GlobalKey를 활용해

CrrentState(텍스트 필드의 상태값)에 접근하는게 가능하다

 

step 1 Global key로 Form key 선언

=> final _formKey = GlobalKey<FormState>();

이렇게 글로벌 키를 생성해 save / validation 레퍼런스로 사용

 

step 2 TextFormField에 validator, onSaved, autovalidateMode(선택사항) 추가

- validator(유효성 검사) : validator(value) 입력 받은 값이 올바른지 조건을 확인함, 조건이 맞지 않을경우

TextFormField에 어떤 에러 메시지를 리턴할지 그리고 마지막에 조건이 맞는경우 null값을 리턴하여 에러처리

- onSaved : onSaved(value) 전달받은 value 값은  fromKey.currentState!.save() 에서 저장된 사용자 입력값을 가져온다

- autovalidateMode : onSaved() 함수 호출시 유효성 검서를 할지, 데이터가 변경할 때마다 항상 유효성 검사를 할지 설정

 

step 3 submit 버튼 생성해서 실행

실질적인 텍스트 필드 값을 검사하고 실행하기

 fromKey.currentState!.save() 함수를 호출하여 onSaved() 함수 실행

 

참고)  https://kibua20.tistory.com/236

 

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    const appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(appTitle),
        ),
        body: const MyCustomForm(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  const MyCustomForm({super.key});

  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>(); //FormState 타입의 글로벌키 생성

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TextFormField(
            // The validator receives the text that the user has entered.
            validator: (value) {
              //입련한 텍스트 유효성 검사
              if (value == null || value.isEmpty) {
                return 'Please enter some text';
              }
              return null;
            },
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 16.0),
            child: ElevatedButton(
              onPressed: () {
                // Validate returns true if the form is valid, or false otherwise.
                if (_formKey.currentState!.validate()) {
                  //글로벌키 _formKey 통해 formfield에 입력된 값의 상태에 접근 가능
                  //validate() 메서드에서 검사후 오류가 없으면 true 반환
                  // If the form is valid, display a snackbar. In the real world,
                  // you'd often call a server or save the information in a database.
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text('Processing Data')),
                  );
                }
              },
              child: const Text('Submit'),
            ),
          ),
        ],
      ),
    );
  }
}
반응형