我正在尝试验证我的登录按钮按下的形式。当所有字段都为空时,它在客户端工作得非常好,但是对于我的switch/case,它似乎不起作用。我相信这可能与我的验证功能有关,但我无法确定它。我相信MySOAPRequest中的布尔值设置是正确的,因为当我按下登录按钮然后更新公司或PIN字段时,错误消息显示在用户名字段上,但它应该显示在登录按钮上。
带有文本字段和登录按钮的登录页面
CustomTextField(
key: _customTextFieldKey,
companyController: _companyController,
usernameController: _usernameController,
pinController: _pinController,
),
const SizedBox(height: 20),
OutlinedButton(
onPressed: () {
FocusManager.instance.primaryFocus?.unfocus();
String lcomp = Globals().lcomp =
_companyController.text.trim();
String luser = Globals().luser =
_usernameController.text.trim();
String lpin =
Globals().lpin = _pinController.text.trim();
if (lcomp.isNotEmpty &&
luser.isNotEmpty &&
lpin.isNotEmpty &&
!_customTextFieldKey.currentState!
.hasError()) {
MySOAPRequest(
lcomp: lcomp,
luser: luser,
lpin: lpin,
onLoginSuccess: _saveCredentials,
).makeSOAPRequest(context);
} else {
_customTextFieldKey.currentState?.validate();
}
},
child: const Text('Login'),
),
MySOAPRequest页面编码
final String lcomp;
final String luser;
final String lpin;
final Function(bool) onLoginSuccess; // define the onLoginSuccess parameter
MySOAPRequest({
required this.lcomp,
required this.luser,
required this.lpin,
required this.onLoginSuccess,
});
switch (logonState) {
case '1':
// Navigate to the Landing page if the logon state is 1
// ignore: use_build_context_synchronously
loginFlushbar(context);
// ignore: use_build_context_synchronously
navigateToSubPages(context);
onLoginSuccess(true);
break;
case '3':
// ignore: use_build_context_synchronously
flushbar(context, 'Incorrect User Name',
'Please try again or contact your administrator if this issue persists.');
onLoginSuccess(false);
break;
default:
// ignore: use_build_context_synchronously
flushbar(context, 'Unknown Error',
'An unknown error occurred. Please try again or contact your administrator.');
Globals().usernameHasError = true;
Globals().errorText = 'Incorrect User Name';
Globals().customTextFieldKey.currentState?.validate();
onLoginSuccess(false);
break;
}
用户名字段文本
class CustomTextFieldState extends State<CustomTextField> {
final _formKey = GlobalKey<FormState>();
//final _usernameKey = Globals().customTextFieldKey;
String _company = '';
String _username = '';
String _pin = '';
bool _companyHasError = false;
bool _usernameHasError = false;
bool _pinHasError = false;
bool hasError() {
return _usernameHasError || _companyHasError || _pinHasError;
}
void validate() {
setState(() {
if (_formKey.currentState != null) {
_companyHasError =
!_formKey.currentState!.validate() || _company.isEmpty;
_usernameHasError =
!_formKey.currentState!.validate() || _username.isEmpty;
_pinHasError = !_formKey.currentState!.validate() || _pin.isEmpty;
}
});
}
@override
Widget build(BuildContext context) {
String lcomp = widget.companyController.text.trim();
return Form(
key: _formKey,
autovalidateMode: AutovalidateMode.disabled,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
//!--- COMPANY TEXT FIELD --- //
child: TextFormField(
controller: widget.companyController,
decoration: InputDecoration(
contentPadding: const EdgeInsets.only(left: 20),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: Color(0xff185C91),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: ThemeClass.primaryColor,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: Color(0xff185C91),
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Colors.red),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Color(0x00232323)),
),
suffixIcon: const Icon(Icons.corporate_fare_outlined,
color: ThemeClass.primaryColor),
labelText: "Company Name",
labelStyle: const TextStyle(
fontSize: 14.0,
decoration: TextDecoration.none,
),
hintText: 'Enter Company Name',
hintStyle: const TextStyle(
fontSize: 14.0,
),
errorText: _companyHasError
? 'Please enter a valid company name!'
: ((_company.isNotEmpty &&
!Globals().resultList.contains(lcomp))
? 'Please enter a valid company name!'
: null),
),
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your company name!';
}
return null;
},
onChanged: (value) {
setState(() {
_company = value;
_companyHasError = false;
});
},
onFieldSubmitted: (value) {
setState(() {
_companyHasError = !_formKey.currentState!.validate();
});
},
),
),
//!--- END COMPANY TEXT FIELD --- //
//!--- USERNAME TEXT FIELD --- //
TextFormField(
controller: widget.usernameController,
//key: _usernameKey,
decoration: InputDecoration(
contentPadding: const EdgeInsets.only(left: 20),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: Color(0xff185C91),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: ThemeClass.primaryColor,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: Color(0xff185C91),
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Colors.red),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Color(0x00232323)),
),
suffixIcon: const Icon(Icons.person_outlined,
color: ThemeClass.primaryColor),
labelText: "Username",
labelStyle: const TextStyle(
fontSize: 14.0,
decoration: TextDecoration.none,
),
hintText: 'Enter username',
hintStyle: const TextStyle(
fontSize: 14.0,
),
errorText: _usernameHasError
? 'Please enter a valid username!'
: Globals().usernameHasError
? Globals().errorText
: null,
),
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your username!';
}
return null;
},
onChanged: (value) {
setState(() {
_username = value;
_usernameHasError = false;
Globals().usernameHasError = false;
});
},
onFieldSubmitted: (value) {
setState(() {
_usernameHasError = !_formKey.currentState!.validate();
});
},
),
//!--- END USERNAME TEXT FIELD --- //
const SizedBox(height: 20),
//!--- PIN TEXT FIELD --- //
TextFormField(
controller: widget.pinController,
inputFormatters: [
LengthLimitingTextInputFormatter(6),
FilteringTextInputFormatter.digitsOnly
],
obscureText: true,
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: const EdgeInsets.only(left: 20),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: Color(0xff185C91),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: ThemeClass.primaryColor,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(
color: Color(0xff185C91),
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Colors.red),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Color(0x00232323)),
),
suffixIcon: const Icon(Icons.pin_outlined,
color: ThemeClass.primaryColor),
labelText: "PIN",
labelStyle: const TextStyle(
fontSize: 14.0,
decoration: TextDecoration.none,
),
hintText: 'Enter PIN',
hintStyle: const TextStyle(
fontSize: 14.0,
),
errorText: _pinHasError
? 'Please enter a valid PIN!'
: _pin.length < 4 && _pin.isNotEmpty
? 'PIN is too short!'
: null,
),
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your PIN!';
}
return null;
},
onChanged: (value) {
setState(() {
_pin = value;
_pinHasError = false;
});
},
onFieldSubmitted: (value) {
setState(() {
_pinHasError = !_formKey.currentState!.validate();
});
},
),
//!--- END PIN TEXT FIELD --- //
],
),
);
}
}
2条答案
按热度按时间tf7tbtn21#
我刚看到你在开关箱上做了些坏事
不应该异步调用构建上下文是有原因的,因为它可能在您传递后已被卸载。
如果您使用的是有状态小部件(看起来是这样),则可以在构建小部件外部定义上下文相关函数,如下所示
jaql4c8m2#
将
TextFormField
Package 在Form
小部件中,并向Form
提供GlobalKey<FormState>
作为其键。然后,您可以使用_formKey.currentState!.validate()
验证它。