말랑한 하루
[Flutter] (Project) MapleApp: 23. 예외 처리 작업-2 본문
🥕 TextFieldForm
아이디에 영문, 숫자, 한글을 제외하고 입력되지 않기 때문에, 정규 표현식 조건을 걸어주려 한다. 하지만 기존 TextFiled의 경우, controller에 들어오는 값에 대해 실시간으로 감지하고 오류 텍스트를 띄워주어야 했기 때문에, 예외 처리를 진행하는 동안에는 개발 비용이 비싸다고 생각했다. 그래서 TextFiled Widget을 FormFiled로 Wrapping하는 TextFiledForm Widget을 활용했다. 사용 방법은 다음과 같다.
TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
hintText: 'What do people call you?',
labelText: 'Name *',
),
onSaved: (String? value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
validator: (String? value) {
return (value != null && value.contains('@')) ? 'Do not use the @ char.' : null;
},
)
기존의 TextFiled의 Widget이름만 바꿔도 충분히 사용 가능했다. 그 곳에 onSaved/validator 등의 원하는 속성을 추가 설정해주면 됐다.
※ reference : https://api.dart.dev/stable/3.2.4/dart-core/RegExp-class.html
이제 validator에 우리가 하고 싶었던 정규 표현식 조건을 걸어주자. 일단 Dart의 정규 표현식에 대해 알아가기 위해 reference를 참고했다.
Dart의 정규 표현식은 Javscript의 정규 표현식과 동일한 구문과 의미를 갖는다. 특수문자가 존재하는 경우를 찾기 위한 방법을 찾았다.
🍒 key 설정
대부분의 예제가 Form과 TextFormField 그리고 Submit button을 예시로 들었다. 하지만 나는 Form이라는 필요 없는 위젯을 사용하고 싶지 않았고, 공식 문서에서 해답을 찾을 수 있었다.
※ reference : https://api.flutter.dev/flutter/material/TextFormField-class.html
Form을 사용하고 싶지 않다면, GlobalKey<FormFieldState>를 생성자에 전달하고, GlobalKey.currentState를 사용하여 양식을 저장하거나 재 설정 하라고 한다. 즉, Form에 key를 전달하는 것이 아닌 TextFormField에 직접 key를 전달하여 활용할 수 있다는 이야기다. 설정은 다음과 같다
@override
Widget build(BuildContext context) {
late GlobalKey<FormFieldState> textFormFieldKey =
GlobalKey<FormFieldState>();
TextFormField(
key: textFormFieldKey,
decoration: const InputDecoration(),
),
),
),
위 코드처럼 key를 직접 할당할 수 있다. 그렇다면 기존 TextFormField의 validator를 어떻게 활용해야 하는가?
🍒 key.currentState.validate()
위에서 언급했던 GlobalKey.currentState를 통해 TextFormField에 접근할 수 있고, 내부의 validate를 실행할 수 있다. 이 validate method는 다음과 같은 특징을 가지고 있다.
🍇 [FormField.validator]를 호출하여 [errorText]를 설정합니다. 오류가 없는 경우 true를 반환합니다.
즉 내가 설정 해 놓은 유효성 검사를 통과하면 true를 반환하고, 오류가 생기면 false를 반환하면서 validator에서는 반환된 문자열을 자동으로 errorText에 할당해준다. 결과 코드는 다음과 같다.
@override
Widget build(BuildContext context) {
late GlobalKey<FormFieldState> textFormFieldKey =
GlobalKey<FormFieldState>();
return Row(
children: [
TextFormField(
key: textFormFieldKey,
autofocus: true,
focusNode: _focusNode,
controller: _textFieldController,
decoration: const InputDecoration(),
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () =>
textFormFieldKey.currentState?.validate() ?? false
? trueAction()
: _focusNode.requestFocus(),
child: Container(
child: Text('검색'),
),
),
],
),
...
}
focusNode의 requestFocus method는 할당해 놓은 focusNode개체(지금은 TextFormField)에 사용자 포커싱을 진행해준다. 웹 앱 모두 유용하게 작동할 수 있다. 하위에 버튼에서 validate method를 호출하면 유효성 검사 결과에 따라 다음 행동을 정해 놓을 수 있다.
'개발 > Flutter' 카테고리의 다른 글
[Flutter] (Project) MapleApp: 25. 예외 처리 작업-4 (0) | 2024.01.20 |
---|---|
[Flutter] (Project) MapleApp: 24. 예외 처리 작업-3 (0) | 2024.01.19 |
[Flutter] (Project) MapleApp: 22. 예외 처리 작업-1 (0) | 2024.01.17 |
[Flutter] (Project) MapleApp: 21. Stat Page 제작-2 (0) | 2024.01.16 |
[Flutter] (Project) MapleApp: 20. Stat Page 제작-1 (0) | 2024.01.15 |