Form + TextFormField 유효성 검사
텍스트를 입력받는 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'),
),
),
],
),
);
}
}