So I have a registration form with some fields and 1 submit button.
I created the UI of the form by separating it into a widget named custom_text_form_field.dart
because the structure is all the same, only some widgets are dynamic to change, so I can use it multiple times
Following the original tutorial straight from Flutter, the validation works fine as it should, but the problem is that the implemented logic is applied to all the fields in the form - which I don't want that.
I want, for example like this
validator: (value) {
if (forms == "name") {
if (max > 32 && value.isEmpty) {
return 'Enter valid value on Name';
}
} else if (forms == "email") {
if (value == null || value.isEmpty) {
return 'Enter valid value on Email';
}
} else if (forms == "phone") {
if (max > 12 || value.isEmpty) {
return 'Enter valid value on Phone';
}
}
}
How to pass dynamic if-else logic into Widgets parameter?
Is this possible?
Or should I not use a separate form widget?
Here's my code:
custom_text_form_field.dart
part of 'widgets.dart';
class CustomTextFormField extends StatelessWidget {
final String title;
final String hintText;
final TextInputType type;
final bool obscureText;
final TextEditingController controller;
const CustomTextFormField({
Key? key,
required this.title,
required this.type,
required this.hintText,
this.obscureText = false,
required this.controller,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: blackTextStyle.copyWith(
fontSize: 16,
fontWeight: semiBold,
),
),
SizedBox(height: 8),
TextFormField(
cursorColor: kBlackColor,
keyboardType: type,
obscureText: obscureText,
controller: controller,
decoration: InputDecoration(
hintText: hintText,
hintStyle: greyTextStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
defaultRadius,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
defaultRadius,
),
borderSide: BorderSide(
color: kPrimaryColor,
),
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
],
),
);
}
}
signup_page.dart
part of 'pages.dart';
class SignUp extends StatefulWidget {
SignUp({super.key});
@override
State<SignUp> createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final TextEditingController nameController = TextEditingController(text: '');
final TextEditingController emailController = TextEditingController(text: '');
final TextEditingController phoneController = TextEditingController(text: '');
final TextEditingController passwordController =
TextEditingController(text: '');
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
AppBar header() {
return AppBar(
backgroundColor: kPrimaryColor,
centerTitle: true,
title: Text(
'Sign Up',
style: whiteTextStyle,
),
);
}
Widget body() {
return SafeArea(
child: ListView(
padding: EdgeInsets.all(margin16),
children: [
CustomTextFormField(
title: "Name",
type: TextInputType.name,
hintText: 'Your full name',
controller: phoneController,
),
CustomTextFormField(
title: "E-Mail",
type: TextInputType.emailAddress,
hintText: 'Your e-mail address',
controller: emailController,
),
CustomTextFormField(
title: "Mobile Number",
type: TextInputType.phone,
hintText: 'Your mobile number',
controller: phoneController,
),
CustomButton(
title: 'Sign Up',
margin: EdgeInsets.only(top: 32),
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('True')),
);
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("False")));
}
},
),
],
),
);
}
return Form(
key: _formKey,
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: kBackgroundColor,
appBar: header(),
body: body(),
),
);
}
}
Thank you, please help or advice..
CodePudding user response:
define one more property in customtextformfield as FormFieldValidator<String>? validator
and pass dynamic validator to all the textfields.
modify your custom_text_form_field.dart like this.
part of 'widgets.dart';
class CustomTextFormField extends StatelessWidget {
final String title;
final String hintText;
final TextInputType type;
final bool obscureText;
final TextEditingController controller;
FormFieldValidator<String>? validator;
const CustomTextFormField({
Key? key,
required this.title,
required this.type,
required this.hintText,
this.obscureText = false,
required this.controller,
this.validator,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: blackTextStyle.copyWith(
fontSize: 16,
fontWeight: semiBold,
),
),
SizedBox(height: 8),
TextFormField(
cursorColor: kBlackColor,
keyboardType: type,
obscureText: obscureText,
controller: controller,
validator:validator,
decoration: InputDecoration(
hintText: hintText,
hintStyle: greyTextStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
defaultRadius,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(
defaultRadius,
),
borderSide: BorderSide(
color: kPrimaryColor,
),
),
),
validator: validator,
),
],
),
);
}
}
and then pass validators for every textfield individually like this.
CustomTextFormField(
title: "Mobile Number",
type: TextInputType.phone,
hintText: 'Your mobile number',
controller: phoneController,
validator: (value) {
if (forms == "name") {
if (max > 32 && value.isEmpty) {
return 'Enter valid value on Name';
}
} else if (forms == "email") {
if (value == null || value.isEmpty) {
return 'Enter valid value on Email';
}
} else if (forms == "phone") {
if (max > 12 || value.isEmpty) {
return 'Enter valid value on Phone';
}
}
}
),