I made a custom form and when I want to use the validation. My issue is that the error message is not appearing as I wanted. Here's the screenshot of it.
So I want to change the position of the error message to be below my container. Does anyone have any idea how to do it ?
Here's the code of the form:
class AuthForm extends StatefulWidget {
final bool isPassword;
final IconData prefixIcon;
final String hintText;
late bool isPasswordVisible = isPassword;
final bool isCalendar;
final TextEditingController controller;
final bool isDropDown;
final bool isPhone;
final String? Function(String?)? validator;
AuthForm({Key? key, this.isPassword = false, required this.prefixIcon, required this.hintText,
this.isCalendar = false, required this.controller, this.isDropDown = false, this.isPhone = false, required this.validator}) : super(key: key);
@override
State<AuthForm> createState() => _AuthFormState();
}
class _AuthFormState extends State<AuthForm> {
@override
void initState() {
super.initState();
if (widget.isPhone){
getCountryCode();
}
}
start () async {
await CountryCodes.init();
}
Locale? getCountryCode () {
start();
final Locale? deviceLocale = CountryCodes.getDeviceLocale();
final CountryDetails details = CountryCodes.detailsForLocale();
return deviceLocale;
}
DateTime selectedDate = DateTime(2000,1);
Future<void> _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1950, 1),
lastDate: DateTime.now());
if (picked != null && picked != selectedDate) {
setState(() {
selectedDate = picked;
});
}
}
@override
Widget build(BuildContext context) {
return Container(
width: 70.w,
height: 5.h,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 0.13.w,
color: Theme.of(context).splashColor,
),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(
widget.prefixIcon,
color: Theme.of(context).primaryColor,
size: 6.w,
),
widget.isDropDown ? const DropDownBar() :
Expanded(
child: TextFormField(
//autovalidateMode: AutovalidateMode.onUserInteraction,
validator: widget.validator,
keyboardType: widget.isPhone ? TextInputType.phone : TextInputType.text,
inputFormatters: [DialCodeFormatter()],
controller: widget.controller,
textAlign: TextAlign.center,
obscureText: widget.isPasswordVisible,
style: Theme.of(context).textTheme.bodyText2,
decoration: InputDecoration(
hintText : widget.hintText,
hintStyle: Theme.of(context).textTheme.bodyText1,
border: InputBorder.none,
),
onTap: () async {
if (widget.isCalendar){
//Dismiss the keyboard
FocusScope.of(context).requestFocus(FocusNode());
//Call the calendar
await _selectDate(context);
widget.controller.text = DateFormat('dd-MM-yyyy').format(selectedDate);
}
}
),
),
//Show Icon only if the form is for a Password
Visibility(
visible: widget.isPassword,
//Maintain the space where the widget is even if it is hid
maintainAnimation: true,
maintainState: true,
maintainSize: true,
child: InkWell(
highlightColor : Colors.transparent,
splashColor: Colors.transparent,
child: Icon(
widget.isPasswordVisible ? Icons.visibility : Icons.visibility_off,
color: Theme.of(context).primaryColor,
size: 6.w,
),
onTap: () {
setState(() {
widget.isPasswordVisible = !widget.isPasswordVisible;
});
},
),
),
],
),
);
}
}
Thanks for your suggestion,
Chris
CodePudding user response:
You should try below piece of code for TextFormField
TextFormField(
textInputAction: TextInputAction.next,
style: TextStyle(fontSize: 16, height: 1),
inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(10)],
keyboardType: TextInputType.phone,
validator: (val) {
if (val!.isEmpty) {
return 'Please enter your mobile number';
} else if (val.length < 10) {
return 'Mobile number should be 10 digits only';
}
},
controller: bloc.mobileNumberLoginController,
decoration: InputDecoration(
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide(
color: code != null ? HexColor(code!) : Colors.pink,
)),
contentPadding: EdgeInsets.only(top: 5, bottom: 5, left: 10, right: 10),
),
),