Reputation: 1838
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
Upvotes: 3
Views: 22705
Reputation: 1838
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()));
}
},
),
],
),
),
);
}
}
Upvotes: 0
Reputation: 729
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,
),
);
}
}
Upvotes: 3
Reputation: 158
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()),
Upvotes: 1