How can I make FormBuilderTextField validators reusable? - flutter

So I am making a sign up page in Flutter. I'm gonna use this "flutter_form_builder" and "form_builder_validators" packages. I will make the textfields reusable to save time, and everything works, except the validators.
This is my reusable widget:
class MyFormBuilderTextField extends StatelessWidget {
final String name;
final Color inputTextColor;
final String labelText;
final Color labelColor;
final bool filled;
final Color fillColor;
final double borderRadius;
final Color enabledBorderColor;
final Color focusedBorderColor;
final FormFieldValidator<String> validators;
MyFormBuilderTextField({
required this.name,
this.inputTextColor = const Color(0xFFFFFFFF),
required this.labelText,
this.labelColor = Colors.white54,
this.filled = true,
this.fillColor = const Color(0xFF131313),
this.borderRadius = 10.0,
this.enabledBorderColor = Colors.white12,
this.focusedBorderColor = const Color(0xFFF57B3B),
required this.validators,
});
#override
Widget build(BuildContext context) {
return FormBuilderTextField(
name: name,
style: TextStyle(color: inputTextColor),
decoration: InputDecoration(
labelText: labelText,
labelStyle: TextStyle(color: labelColor),
filled: filled,
fillColor: fillColor,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: enabledBorderColor),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: focusedBorderColor),
),
),
validator:validators,
);
}
}
This is how I tried implementing it:
class MyFormBuilder extends StatefulWidget {
#override
State<MyFormBuilder> createState() => _MyFormBuilderState();
}
class _MyFormBuilderState extends State<MyFormBuilder> {
final _formKey = GlobalKey<FormBuilderState>();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF070707),
body: _buildContent(),
);
}
Widget _buildContent() {
return SingleChildScrollView(
padding: EdgeInsets.all(24.0),
child: FormBuilder(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 30.0),
MyFormBuilderTextField(
name: 'password',
labelText: 'Password',
validators: [
FormBuilderValidators.min(8),
FormBuilderValidators.required(),
],
),
],
),
)
);
}
}
I am getting this error:
The argument type 'String? Function(String?)' can't be assigned to the parameter type 'List<String? Function(String?)>'.dartargument_type_not_assignable
How can I make the validators reusable?

Related

Change textfield value with firebase realtime database value

I want to change two textfields value via firebase realtime database value in Flutter not sure how to do it
this is my code I am using Getx controller that is why a little confused
i am a beginner so ignore bad code
for Firebase :
static void readData() async
{
DatabaseReference dataRef = FirebaseDatabase.instance
.ref()
.child("test");
dataRef.once().then((snap)
{
if(snap.snapshot.value != null)
{
dataModelInfo = DataModel.fromSnapshot(snap.snapshot);
BlockController().fheight = dataModelInfo!.height.toString();
BlockController().flength = dataModelInfo!.length.toString();
print("height ="+ dataModelInfo!.height.toString());
print("length ="+ dataModelInfo!.length.toString());
}
});
}
For Textfields :
class BlockController extends GetxController{
final WallheightController = TextEditingController();
final WalllengthController = TextEditingController();
}
want to update text field data after retrieving from firebase
class SidesField extends StatelessWidget {
SidesField({
Key? key,
required this.labelText,
required this.controller, required Map Function(dynamic text) onChanged,
}) : super(key: key);
final String labelText;
final TextEditingController controller;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
keyboardType: const TextInputType.numberWithOptions(decimal: true),
controller: controller,
decoration: InputDecoration(
labelText: labelText,
labelStyle: const TextStyle(color: kPurpleColor),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: kPurpleColor,
width: 3,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
color: Colors.grey,
),
),
),
validator:(value){
if(value!.isEmpty){
return "Enter This Field";
}
return null;
},
),
);
}
}
Please tell my how to change value of text field after taking data from firebase realtime database

passing a widget that has setState to another page without stateful/stateless widget

Is Any Way How to pass a widget function to another page that is without any stateless/stateful? The file only includes widgets such as textfields, buttons and etc. I am trying not to cluster every fields in one page. Any helps/ideas would be appreciated!
Main.dart
class MainPage extends StatefulWidget {
const MainPage({super.key});
#override
State<Main Page> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
// bool for toggling password
bool isSecuredPasswordField = true;
#override
Widget build(BuildContext context) {
return Container();
}
// widget function that I need to pass on widget_fields.dart
Widget togglePassword() {
return IconButton(
onPressed: () {
setState(() {
isSecuredPasswordField = !isSecuredPasswordField;
});
},
icon: isSecuredPasswordField
? const Icon(Icons.visibility)
: const Icon(Icons.visibility_off),
);
}
}
widget_fields.dart
Widget userPasswordField(_passwordUserCtrlr) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: TextFormField(
obscureText: true,
controller: _passwordUserCtrlr,
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
isDense: true,
suffixIcon: togglePassword(), //<-- I wanna call that function here
prefixIcon: const Icon(Icons.lock),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xFFCECECE)),
borderRadius: BorderRadius.circular(12),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: Color(0xFFCECECE)),
),
hintText: 'Password',
hintStyle: const TextStyle(
fontFamily: 'Poppins',
fontSize: 14,
),
fillColor: const Color(0xFFFEFEFE),
filled: true,
),
validator: (value) {
if (value!.isEmpty) {
return "Please enter your password.";
} else if (value.length < 8) {
return "Password should be min. 8 characters.";
} else {
return null;
}
},
),
);
}
You can pass functions like any other variable. I made a full working example that's different than yours to show a more minimal example but you can apply the same logic for your code
main.dart
import 'package:flutter/material.dart';
import 'column.dart';
void main() {
runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
Widget returnSomeText() {
return const Text("test");
}
#override
Widget build(BuildContext context) {
return Scaffold(body: createColumn(returnSomeText));
}
}
column.dart
import 'package:flutter/material.dart';
Widget createColumn(Function widgetFunction) {
return Column(
children: [widgetFunction(), widgetFunction()],
);
}
As you can see the togglePassword from your code corresponds to returnSomeText in mine. and userPasswordField is like createColumn. But it must be said that it's not recommended to use helper functions like createColumn here but to turn it into a StatelessWidget, like this for example:
import 'package:flutter/material.dart';
class CreateColumn extends StatelessWidget {
final Function widgetFunction;
const CreateColumn({Key? key, required this.widgetFunction}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: [widgetFunction(), widgetFunction()],
);
}
}
And then in main.dart:
return Scaffold(body: CreateColumn(widgetFunction: returnSomeText));
See also this YouTube video: Widgets vs helper methods
This is Example that how you call Widget in another class:
class MainApge extends StatefulWidget {
const MainApge({Key? key}) : super(key: key);
#override
State<MainApge> createState() => _MainApgeState();
}
class _MainApgeState extends State<MainApge> {
#override
Widget build(BuildContext context) {
return Column(
children: [
ContainerTextFields.customsTextField(
"User Name",
'enter name',
userNameController,
),
],
);
}
}
This is Custom Widget Class:
class ContainerTextFields {
static Widget customsTextField(
String label, String cusHintText, TextEditingController _controller) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(
padding: EdgeInsets.only(
left: SizeConfig.screenHeight! * 0.05,
top: SizeConfig.screenHeight! * 0.03),
child: Text(
label,
style: AppStyle.kUnSyncedDialogeText.copyWith(
color: AppColors.kTextFieldLabelColorGrey,
fontWeight: FontWeight.bold),
)),
Padding(
padding: EdgeInsets.only(
top: SizeConfig.screenHeight! * 0.02,
left: SizeConfig.screenHeight! * 0.042,
right: SizeConfig.screenWidth! * 0.042),
child: SingleChildScrollView(
child: Container(
height: SizeConfig.screenHeight! * 0.065,
child: TextFormField(
controller: _controller,
decoration: InputDecoration(
hintText: cusHintText,
hintStyle: TextStyle(
color: AppColors.kLoginPopUpColor,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
),
)
]);
}
}
You can pass the widget as parameter to child widget:
class MyTextField extends StatelessWidget {
const MyTextField({Key? key,
this.togglePassword,
this.passwordUserCtrlr
})
: super(key: key);
final Widget? togglePassword;
final TextEditingController? passwordUserCtrlr;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: TextFormField(
obscureText: true,
controller: passwordUserCtrlr,
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
isDense: true,
suffixIcon: togglePassword, //<-- I wanna call that function here
prefixIcon: const Icon(Icons.lock),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Color(0xFFCECECE)),
borderRadius: BorderRadius.circular(12),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: Color(0xFFCECECE)),
),
hintText: 'Password',
hintStyle: const TextStyle(
fontFamily: 'Poppins',
fontSize: 14,
),
fillColor: const Color(0xFFFEFEFE),
filled: true,
),
validator: (value) {
if (value!.isEmpty) {
return "Please enter your password.";
} else if (value.length < 8) {
return "Password should be min. 8 characters.";
} else {
return null;
}
},
),
);
}
}
And can easily call from main widget:
class MainPage extends StatefulWidget {
const MainPage({super.key});
#override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
// bool for toggling password
bool isSecuredPasswordField = true;
TextEditingController? passwordUserCtrlr = TextEditingController();
#override
Widget build(BuildContext context) {
return MyTextField(
togglePassword: togglePassword(),
passwordUserCtrlr: passwordUserCtrlr,
);
}
// widget function that I need to pass on widget_fields.dart
Widget togglePassword() {
return IconButton(
onPressed: () {
setState(() {
isSecuredPasswordField = !isSecuredPasswordField;
});
},
icon: isSecuredPasswordField
? const Icon(Icons.visibility)
: const Icon(Icons.visibility_off),
);
}
}
You can create class like GlobalWidget for example, like this:
class GlobalWidget {
// widget function that I need to pass on widget_fields.dart
Widget togglePassword(Function()? onPressed, bool value) {
return IconButton(
onPressed: onPressed,
icon: value
? const Icon(Icons.visibility)
: const Icon(Icons.visibility_off),
);
}
}
And You can call the Widget like that :
GlobalWidget().togglePassword(() => setState(() {
isSecuredPasswordField = !isSecuredPasswordField;
}), isSecuredPasswordField)
What you are trying to do is impossible in the Flutter framework. You cannot call methods belonging to other widgets
Also, it is discouraged to use function to return widgets as this impacts the framework's ability to optimize the build process.
One possible solution is to package your complete password entry in a set of custom (statefull) widgets. You can collect those into a single source file if you like. Be sure to create a class for every widget.

How to show a text along textfield data like this in flutter

How to show a constant text in textfield in Flutter along with typed data like in this picture.
You can use String Interpolation. Using $ to access variable in Text Widget.
#override
Widget build(BuildContext context) {
double quantity = 1;
return Row(
children: [
Icon(Icons.production_quantity_limits_outlined),
SizedBox(
width: 20,
),
Text("$quantity (qty)"),
],
);
}
class Example extends StatelessWidget {
const Example({super.key});
#override
Widget build(BuildContext context) {
double quantity = 1;
return TextField(
decoration: InputDecoration(
label: Text("$quantity (qty)"),
border: OutlineInputBorder()
),
);
}
}
you can use like this:
class TextFieldExample extends StatelessWidget {
const TextFieldExample({Key? key}) : super(key: key);
Widget build(BuildContext context) {
TextEditingController? controller;
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20),
child: TextField(
controller: controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15.0),
),
filled: true,
hintText: '1(qty)',
prefixIcon: Icon(Icons.watch),
),
),
),
);
}
}

Working With Seperate Files in Flutter/Dart

I am newbie at Dart and OOP.I have one input.dart file for Text Form Fields and login.dart file to conduct login.My problem is I want to acces text controller (located in input.dart) from login.dart.
I created getter method to obtain, (controller.text) data but I have encountered with Initilazation Error.
How Can I acces controller text(which is basically user input) from another file?
input.dart
class InputAlanState extends State<InputAlan> {
late TextEditingController _emailKontroller;
late TextEditingController _sifreKontroller;
#override
void initState() {
super.initState();
_emailKontroller = TextEditingController();
_sifreKontroller = TextEditingController();
}
#override
void dispose() {
_emailKontroller.dispose();
_sifreKontroller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
if (widget.tur == "email") {
return Padding(
padding: const EdgeInsets.only(top: 50, left: 20, right: 20),
child: TextFormField(
controller: _emailKontroller,
autofocus: true,
decoration: const InputDecoration(
labelText: "E - Mail",
hintText: "E-Mail",
prefixIcon: Icon(Icons.email_outlined),
suffixIcon: Icon(Icons.lock),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)))),
),
);
} else if (widget.tur == "sifre") {
return Padding(
padding:
const EdgeInsets.only(top: 40, left: 20, right: 20, bottom: 15),
child: TextFormField(
controller: _sifreKontroller,
obscureText: true,
decoration: const InputDecoration(
labelText: "Password",
hintText: "Password",
prefixIcon: Icon(Icons.password_sharp),
suffixIcon: Icon(Icons.lock),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)))),
),
);
} else {
return Padding(
padding: const EdgeInsets.only(top: 50, left: 20, right: 20),
child: TextFormField(
decoration: const InputDecoration(
labelText: "E - Mail",
hintText: "E-Mail",
prefixIcon: Icon(Icons.email_outlined),
suffixIcon: Icon(Icons.lock),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)))),
),
);
}
}
}
login.py
Widget build(BuildContext context) {
return OutlinedButton(
onPressed: () {
InputAlan inputAlan = InputAlan("email");
String email = inputAlan.email;
String password = inputAlan.sifre;
Login login = login(email, sifre);
girisYap.girisYap(context);
},
child: const Text("SIGN IN"),
style: OutlinedButton.styleFrom(
primary: const Color(0xFF166FC0),
side: const BorderSide(color: Color(0xFF0FA9EA), width: 2),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)))),
);
}
}
to access variables from another state (in your case from InputAlanState) in flutter you have multiple options, the simplest way would be to use a GlobalKey, so in your code you can access InputAlanState's controllers from your login you can use this code in your OutlinedButton:
GlobalKey<InputAlanState> myKey = GlobalKey();
myKey.currentState!._emailKontroller; //here
You're putting a widget in a function parameter. In this way the widget cannot be rendered and it just can't work. I suggest you take a look at how to build flutter layouts to grasp the basics.
You probably want to build something like this:
enum Field { mail, password }
class MyApp extends StatelessWidget {
final TextEditingController mailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: [
InputAlan(fieldType: Field.mail, textEditingController: mailController,),
InputAlan(fieldType: Field.password, textEditingController: passwordController,),
OutlinedButton(
onPressed: () {
String email = mailController.text;
String sifre = passwordController.text;
// Login login = login(email, sifre);
// girisYap.girisYap(context);
},
child: const Text("SIGN IN"),
style: OutlinedButton.styleFrom(
primary: const Color(0xFF166FC0),
side: const BorderSide(color: Color(0xFF0FA9EA), width: 2),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)))),
),
],
)
),
);
}
}
TextField widget
class InputAlan extends StatefulWidget {
const InputAlan({
Key? key,
required this.fieldType,
required this.textEditingController,
}) : super(key: key);
final Field fieldType;
final TextEditingController textEditingController;
#override
State<InputAlan> createState() => _InputAlanState();
}
class _InputAlanState extends State<InputAlan> {
#override
Widget build(BuildContext context) {
final isMailField = widget.fieldType == Field.mail;
return Padding(
padding: const EdgeInsets.only(top: 50, left: 20, right: 20),
child: TextFormField(
controller: widget.textEditingController,
autofocus: widget.fieldType == Field.mail,
obscureText: !isMailField,
decoration: InputDecoration(
labelText: isMailField ? "E - Mail" : "Password",
hintText: isMailField ? "E-Mail" : "Password",
prefixIcon:
Icon(isMailField ? Icons.email_outlined : Icons.password_sharp),
suffixIcon: const Icon(Icons.lock),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
)),
),
);
}
}

how to display validation error message out from the textfield in flutter

how to display "this field is required" message out from the box. this message will display on button click.
here is the textfield code
-------------------EDITED QUESTION-------------------
Here is your code and modified it by adding one more textformfield
import 'package:flutter/material.dart';
class ExperimentApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
scaffoldBackgroundColor: Colors.white,
),
home: ExperimentHome(),
);
}
}
class ExperimentHome extends StatelessWidget {
final GlobalKey<FormFieldState> formFieldKey = GlobalKey();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RoundedInputField(
formFieldKey: formFieldKey,
icon: Icons.edit,
labelText: 'Label',
validate: (value) {
if (value == null || value.isEmpty) {
return "This field is required";
}
return null;
},
),
),
),
//this is one more TextFormField
RoundedInputField(
formFieldKey: formFieldKey,
icon: Icons.edit,
labelText: 'Label1',
validate: (value) {
if (value == null || value.isEmpty) {
return "This field is required";
}
return null;
},
),
IconButton(
icon: Icon(Icons.check),
onPressed: () {
// you need to call `.validate` to actually validate the field.
formFieldKey.currentState.validate();
},
)
],
),
),
);
}
}
class RoundedInputField extends StatelessWidget {
final IconData icon;
final FormFieldValidator<String> validate;
final String labelText;
final GlobalKey<FormFieldState> formFieldKey;
// (before flutter 2.0) drop `required`
const RoundedInputField({
Key key,
#required this.formFieldKey,
#required this.labelText,
#required this.icon,
#required this.validate,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return TextFormField(
key: formFieldKey,
validator: validate,
decoration: InputDecoration(
icon: Icon(
icon,
color: Colors.blue,
),
labelText: labelText,
),
);
}
}
this is error
════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderTransform#3842d NEEDS-LAYOUT NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'
The relevant error-causing widget was
TextFormField-[LabeledGlobalKey<FormFieldState<dynamic>>#a4b32]
lib\abc.dart:87
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════
Multiple widgets used the same GlobalKey.
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════
Multiple widgets used the same GlobalKey.
════════════════════════════════════════════════════════════════════════════════
and it shows a plain white screen as output
You need to use a GlobalKey<FormFieldState> and actually call .validate on the field to validate the field.
When you call .validate, the TextFormField will validate the field and show the error message if the validate method returns a String.
More on TextFormField: https://api.flutter.dev/flutter/material/TextFormField-class.html
Code Sample (there are some syntatic differences as you seem to be using an older version of dart):
import 'package:flutter/material.dart';
void main() async {
runApp(ExperimentApp());
}
class ExperimentApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
scaffoldBackgroundColor: Colors.white,
),
home: ExperimentHome(),
);
}
}
class ExperimentHome extends StatelessWidget {
final GlobalKey<FormFieldState> formFieldKey = GlobalKey();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: RoundedInputField(
formFieldKey: formFieldKey,
icon: Icons.edit,
labelText: 'Label',
validate: (value) {
if (value == null || value.isEmpty) {
return "This field is required";
}
return null;
},
),
),
),
IconButton(
icon: Icon(Icons.check),
onPressed: () {
// you need to call `.validate` to actually validate the field.
formFieldKey.currentState!.validate();
},
)
],
),
),
);
}
}
class RoundedInputField extends StatelessWidget {
final IconData icon;
final FormFieldValidator<String> validate;
final String labelText;
final GlobalKey<FormFieldState> formFieldKey;
// (before flutter 2.0) drop `required`
const RoundedInputField({
Key? key,
required this.formFieldKey,
required this.labelText,
required this.icon,
required this.validate,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return TextFormField(
key: formFieldKey,
validator: validate,
decoration: InputDecoration(
icon: Icon(
icon,
color: Colors.blue,
),
labelText: labelText,
),
);
}
}
This will work for you.
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.anyColor,
width: 2),
),
focusedErrorBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.anyColor,
width: 2),
),
errorBorder:
(value.isEmpty)
? UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.anyColor),
)
: InputBorder.none,
errorText:
(value.isEmpty)
? "Minimum 3 characters required"
: null,
errorStyle: anyTextStyle(),
hintText: "Name",
hintStyle:
anyTextStyle()),
Finally I got the solution! Here it works perfectly.
TextFormField widget:
import 'package:attendance_system_app/text_field_container.dart';
import 'package:flutter/material.dart';
class RoundedInputField extends StatelessWidget {
final String hintText;
final IconData icon;
final ValueChanged<String> onChanged;
final TextEditingController controller;
final double fontsize;
final FormFieldValidator<String> validate;
final String errortext;
final String labelText;
final GlobalKey<FormFieldState> formFieldKey;
//final onsaved;
const RoundedInputField(
{Key key,
this.labelText,
this.formFieldKey,
this.errortext,
this.hintText,
this.icon,
this.validate,
this.onChanged,
this.controller,
this.fontsize})
: super(key: key);
#override
Widget build(BuildContext context) {
return TextFormField(
decoration: InputDecoration(
labelText: labelText,
fillColor: Colors.blue[50],
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(29.0),
),
),
validator: validate,
controller: controller,
maxLength: 5,
);
}
}
And here you can call the widget.
class JafPersonals extends StatefulWidget {
#override
_JafPersonalState createState() => _JafPersonalState();
}
class _JafPersonalState extends State<JafPersonals> {
TextEditingController _applicantName = new TextEditingController();
TextEditingController _fatherName = new TextEditingController();
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return new Scaffold(
drawer: new AdminDrawerCode(),
appBar: AppBar(
title: Image.asset(
"assets/image/company_logo.png",
height: 140,
width: 280,
),
//automaticallyImplyLeading: false,
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue, size: 20),
//leading: new Icon(Icons.menu,color: Colors.blue,),
actions: <Widget>[
IconButton(
icon: Icon(Icons.notifications, color: Colors.blue, size: 26),
onPressed: () {
// do something
},
)
],
),
body: Form(
key: _formkey,
child: ListView(
padding: EdgeInsets.all(16),
children: [
Text(" Employee Bio Data",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: Colors.blue[900])),
SizedBox(
height: 20,
),
Text(" Personal data",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.blue[900])),
SizedBox(
height: 20,
),
RoundedInputField(
labelText: 'Applicant name',
controller: _applicantName,
validate: (value) {
if (value.length < 4) {
return 'Enter at least 4 characters';
} else {
return null;
}
},
),
SizedBox(height: 10),
RoundedInputField(
labelText: 'Father name',
controller: _applicantName,
validate: (value) {
if (value.length < 4) {
return 'Enter at least 4 characters';
} else {
return null;
}
},
),
RoundedButton(
text: 'Submit',
press: () {
final isvalid = _formkey.currentState.validate();
if (isvalid) {
_formkey.currentState.save();
Navigator.push(context,
MaterialPageRoute(builder: (context) => JafFamily()));
}
},
),
],
),
),
);
}
}