@@ -119,13 +119,15 @@ class _EmailPasswordLoginPageState extends State<EmailPasswordLoginPage> {
119
119
void _submit () async {
120
120
final context = _emailKey.currentContext! ;
121
121
final realmUrl = widget.serverSettings.realmUri;
122
- final String ? email = _emailKey.currentState! .value;
123
- final String ? password = _passwordKey.currentState! .value;
124
- if (email == null || password == null ) {
125
- // TODO can these FormField values actually be null? when?
122
+ final emailFieldState = _emailKey.currentState! ;
123
+ final passwordFieldState = _passwordKey.currentState! ;
124
+ final emailValid = emailFieldState.validate (); // Side effect: on-field error text
125
+ final passwordValid = passwordFieldState.validate (); // Side effect: on-field error text
126
+ if (! emailValid || ! passwordValid) {
126
127
return ;
127
128
}
128
- // TODO(#35): validate email is in the shape of an email
129
+ final String email = emailFieldState.value! ;
130
+ final String password = passwordFieldState.value! ;
129
131
130
132
final FetchApiKeyResult result;
131
133
setState (() {
@@ -194,6 +196,14 @@ class _EmailPasswordLoginPageState extends State<EmailPasswordLoginPage> {
194
196
key: _emailKey,
195
197
autofillHints: const [AutofillHints .email],
196
198
keyboardType: TextInputType .emailAddress,
199
+ autovalidateMode: AutovalidateMode .onUserInteraction,
200
+ validator: (value) {
201
+ if (value == null || value.trim ().isEmpty) {
202
+ return 'Please enter your email.' ;
203
+ }
204
+ // TODO(#35): validate is in the shape of an email
205
+ return null ;
206
+ },
197
207
decoration: const InputDecoration (
198
208
labelText: 'Email address' )),
199
209
const SizedBox (height: 8 ),
@@ -202,6 +212,13 @@ class _EmailPasswordLoginPageState extends State<EmailPasswordLoginPage> {
202
212
autofillHints: const [AutofillHints .password],
203
213
obscureText: _obscurePassword,
204
214
keyboardType: TextInputType .visiblePassword,
215
+ autovalidateMode: AutovalidateMode .onUserInteraction,
216
+ validator: (value) {
217
+ if (value == null || value.isEmpty) {
218
+ return 'Please enter your password.' ;
219
+ }
220
+ return null ;
221
+ },
205
222
decoration: InputDecoration (
206
223
labelText: 'Password' ,
207
224
suffixIcon: Semantics (label: 'Hide password' , toggled: _obscurePassword,
0 commit comments