Flutter

[Flutter] 플러터 기본기 다지기 - 3 (Form 위젯)

미로910 2024. 11. 11. 12:30

Form 위젯

  • TextField는 단순히 하나의 텍스트 입력을 다루는데 반해서, Form은 그 자체로 입력 필드를 가지고 있지 않지만, FormField 위젯들을 그룹화하여 관리하며, 복잡한 유효성 검사와 보다 쉽게 할 수 있는 위젯
  • 다른 위젯과 달리 Form 위젯은 자체적인 화면을 제공하지는 않으며, 사용자가 입력한 데이터의 유효성 검증, 데이터 관리 관련 기능을 제공함
  • Form 위젯 내에서 TextFormField 위젯을 사용하여 각 데이터 입력을 받는 것이 일반적임
  • Form 위젯 작성 방법은 다음과 같음

 

1. Form 위젯을 위한 GlobalKey를 만들어야 함. GlobalKey는 FormState 전체에 액세스하는 데 사용되며, 이 객체는 폼 데이터의 유효성을 검사하고 저장하는 데 사용됨

final _formKey = GlobalKey<FormState>();

 

2. TextFormField 위젯들의 폼 컨트롤을 위젯을 Form 위젯으로 래핑하고, _formKey를 Form 위젯의 key 속성으로 설정

Form(
     key: _formKey,
     child: Column(
          children: [
               // 폼 컨트롤들
          ],
        ),
     );

 

3. TextFormField 위젯 또는 다른 폼 컨트롤을 Form 위젯에 추가합니다. 각 폼 컨트롤은 validator 함수와 선택적인 onSaved 함수를 가져야 함

  • validator 함수는 사용자가 폼을 제출할 때 호출되며, 입력이 유효한지 확인.
  • 입력이 유효하지 않으면 validator는 오류 메시지를 포함하는 문자열을 반환해야 함.
  • 입력이 유효하면 validator는 null을 반환해야 함.
  • onSaved 함수는 폼이 저장될 때 호출되며 사용자가 입력한 값을 변수나 데이터 모델에 저장해야 함.
TextFormField(
     decoration: InputDecoration(
          labelText: 'Email',
     ),
     validator: (value) {
          if (value == null || value.isEmpty) {
               return '이메일을 입력하세요';
          }
          return null;
        },
        onSaved: (value) {
           _email = value;
        },
  ),

 

4. 폼에 제출 버튼을 추가하고 폼 제출을 처리할 함수를 정의

  • _submitForm 함수는 FormState 객체의 validate 메서드(_formKey.currentState!.validate())를 사용하여 폼 유효성을 검사하고
  • FormState 객체의 save 메서드(_formKey.currentState!.save())를 사용하여 폼 데이터를 저장해야 함
  • _formKey.currentState!에서 _formKey는 GlobalKey 객체이고, 여기에서 currentState는 FormState 객체임
    • 해당 객체가 없지 않다는 것을 명시적으로 알려주기 위해 !(Exclamation mark)를 기재한 것임
  • 폼 데이터가 유효하면 _submitForm 함수는 데이터를 의도한대로 처리하게 됨

 

Form을 사용해 사용자의 이름, 이메일, 비밀번호를 입력받고, 입력된 데이터를 확인하여 오류 메시지를 출력하는 예제
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp8());
}

class MyApp8 extends StatefulWidget {
  const MyApp8({super.key});

  @override
  State<MyApp8> createState() => _MyApp8State();
} // end of class

class _MyApp8State extends State<MyApp8> {
  // Form 위젯 만들어 보기
  // Form 위젯의 상태를 식별하고 관리하기 위해 사용
  // 폼의 유효성 검사 및 저장 상태를 추적할 수 있음
  final _formKey = GlobalKey<FormState>();
  String _name = '';
  String _email = '';
  String _password = '';
  String _errorMessage = '';

  // 멤버 함수 만들어보기
  // 폼 제출 시 호출되는 함수
  void _submitForm() {
    print(
        '_formKey.currentState!.validate() : ${_formKey.currentState!.validate()}');
    if (_formKey.currentState!.validate()) {
      // TextFormField --> validator 호출 --> 모두 통과 하면 true 를 반환한다.

      // 다음 단계 --> onSaved 메서드를 실행 시킨다.
      _formKey.currentState!.save(); // 각각에 formfield onSaved 메서드 호출 됨
      setState(() {
        _errorMessage = ''; // 상태 변경 처리
        // 변수 안에 값 확인 -->
        print('_name : $_name');
        print('_email : $_email');
        print('_password : $_password');

        // 통신 요청
        // http.get(~);
        // http.post(~);
        // 응답 받아서 화면 이동 처리, 메세지 던져 주기
      });
    } else {
      setState(() {
        _errorMessage = '필수 값들을 입력하시오';
      });
    }
  }

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Form Example'),
        ),
        body: Container(
          padding: const EdgeInsets.all(16.0),
          // form 위젯은 위젯들을 구분할 수 있는 키가 필요하다.
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                TextFormField(
                  decoration: InputDecoration(
                    labelText: 'name',
                    errorStyle: TextStyle(color: Colors.blue, fontSize: 10),
                  ),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return '이름을 입력하세요';
                    }
                    return null;
                  },
                  // value 매개변수 값이 null 이 될 수 있다.
                  onSaved: (value) {
                    // value! 강제 null 아니라고 명시 함
                    _name = value!;
                  },
                ),
                TextFormField(
                  // TextFormField --> validator와 onSaved 콜백을 사용
                  decoration: InputDecoration(
                    labelText: 'email',
                    errorStyle: TextStyle(color: Colors.blue, fontSize: 10),
                  ),
                  validator: (value) {
                    // 유효성 검사
                    if (value == null || value.isEmpty) {
                      return '이메일을 입력하세요';
                    }
                    return null;
                  },
                  // value 매개변수 값이 null 이 될 수 있다.
                  // 저장
                  onSaved: (value) {
                    // value! 강제 null 아니라고 명시 함
                    _email = value!;
                  },
                ),
                TextFormField(
                  decoration: InputDecoration(
                    labelText: 'password',
                    errorStyle: TextStyle(color: Colors.blue, fontSize: 10),
                  ),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return '비밀번호를 입력하세요';
                    }
                    return null;
                  },
                  // value 매개변수 값이 null 이 될 수 있다.
                  onSaved: (value) {
                    // value! 강제 null 아니라고 명시 함
                    _password = value!;
                  },
                ),
                const SizedBox(height: 20),
                ElevatedButton(
                  onPressed: _submitForm, // 코드 축약 // 버튼을 누를 때 제출
                  child: Text('Submit'),
                ),
                const SizedBox(height: 20),
                Text(
                  _errorMessage,
                  style: TextStyle(color: Colors.red),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}// end of class
Form 위젯의 상태를 식별하고 관리하기 위해 사용 , 폼의 유효성 검사 및 저장 상태를 추적할 수 있음
_submitForm() --> 폼 제출 시 호출되는 함수 
1. TextFormField --> validator 호출 --> 모두 통과 하면 true 를 반환한다.
2. onSaved 메서드를 실행 시킨다.
form 위젯은 위젯들을 구분할 수 있는 키가 필요하다.
TextFormField --> validator와 onSaved 콜백을 사용
validator --> 유효성 검사
onSaved --> 저장

 

실행 화면_____