Flutter TextFormField validation

Raon·2023년 1월 19일
0

앱이든 웹이든 입력필드를 만들다보면 validation을 통해 입력값을 프론트엔드에서 1차적으로 필터링해주는 작업을 하게된다.

플러터는 이러한 validation작업을 위해 TextFormField 위젯에 validator프로퍼티를 통해 손쉽게 validation을 수행할 수 있도록 해준다.

이번 글에서는 이를 구현하는 방식을 소개하려고한다.

우선 첫 번째로, 아래의 코드처럼 GlobalKey<FormState>변수를 선언 한뒤 Form위젯에 key로 지정한다.
이 때, Form위젯의 child는 validation을 수행할 입력 필드를 TextFormField를 이용해 넣어준다.

GlobalKey<FormState> formKey = GlobalKey<FormState>();

Form(
  key: formKey,
  child: Column(
    children: [
      TextFormField(
        decoration: const InputDecoration(labelText: 'Name'),
      ),
      TextFormField(
        decoration: const InputDecoration(labelText: 'Age'),
      ),
      TextFormField(
        decoration: const InputDecoration(labelText: 'City'),
      ),
    ],
  ),
),





그 다음 각각의 TextFormField가 가진 validator에 수행할 validation 코드를 작성한다.

Form(
  key: formKey,
  child: Column(
    children: [
      TextFormField(
        decoration: const InputDecoration(labelText: 'Name'),
        validator: (String? value) {
          if (value?.isEmpty ?? true) return 'Empty!';
          if (value!.contains(RegExp(r'[0-9]'))) return 'Number is not allowed!';
          return null;
        },
      ),
      TextFormField(
        decoration: const InputDecoration(labelText: 'Age'),
        validator: (String? value) {
          if (value?.isEmpty ?? true) return 'Empty!';
          if (value!.contains(RegExp(r'[^0-9]'))) return 'Not Number!';
          return null;
        },
      ),
      TextFormField(
        decoration: const InputDecoration(labelText: 'City'),
        validator: (String? value) {
          if (value?.isEmpty ?? true) return 'Empty!';
          return null;
        },
      ),
    ],
  ),
),





마지막으로 validation의 트리거가 될 액션을 넣어준다. 이때 formKey.currentState!.validate()를 통해 위젯트리에서 Form위젯 하위에 존재하는 모든 validator를 검증한다.

Text(validationResult ? 'Success' : 'Failed'),
const SizedBox(height: 24.0),
ElevatedButton(
  onPressed: () => setState(
    () {
      //validation의 결과를 true/false로 반환한다.
      validationResult = formKey.currentState?.validate() ?? false;
    },
  ),
  child: const Text('Validation'),
),





전체 코드는 다음과 같다.


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

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

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Home(),
    );
  }
}

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

  
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  GlobalKey<FormState> formKey = GlobalKey<FormState>();
  late bool validationResult;

  
  void initState() {
    validationResult = false;
    super.initState();
  }

  
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => FocusScope.of(context).unfocus(),
      child: Scaffold(
        appBar: AppBar(title: const Text('Test')),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: Column(
              children: [
                Form(
                  key: formKey,
                  child: Column(
                    children: [
                      TextFormField(
                        decoration: const InputDecoration(
                          labelText: 'Name',
                        ),
                        validator: (value) {
                          if (value?.isEmpty ?? true) return 'Empty!';
                          if (value!.contains(RegExp(r'[0-9]'))) return 'Number is not allowed!';
                          return null;
                        },
                      ),
                      TextFormField(
                        decoration: const InputDecoration(
                          labelText: 'Age',
                        ),
                        validator: (value) {
                          if (value?.isEmpty ?? true) return 'Empty!';
                          if (value!.contains(RegExp(r'[^0-9]'))) return 'Not Number!';
                          return null;
                        },
                      ),
                      TextFormField(
                        decoration: const InputDecoration(
                          labelText: 'City',
                        ),
                        validator: (value) {
                          if (value?.isEmpty ?? true) return 'Empty!';
                          return null;
                        },
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 24.0),
                Text(validationResult ? 'Success' : 'Failed'),
                const SizedBox(height: 24.0),
                ElevatedButton(
                    onPressed: () => setState(
                          () {
                            validationResult = formKey.currentState?.validate() ?? false;
                          },
                        ),
                    child: const Text('Validation')),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
profile
Flutter 개발자

0개의 댓글