I have a TextFormField with validation on Empty.
In order to control height, TextFormField was nested inside Container widget.
Which cause unexpected side effect of displaying error message overlap as attached pictures.
to test sample code, press "Submit" to see error.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SimpleForm(),
);
}
}
class SimpleForm extends StatelessWidget {
#override
Widget build(BuildContext context) {
final formKey = GlobalKey<FormState>();
return SafeArea(
child: Scaffold(
// primary: true,
body: Form(
key: formKey,
child: Column(
children: [
SizedBox(
height: 0,
),
// Container(height: 0,),
Container(
height: 38,
margin: EdgeInsets.all(6),
child: TextFormField(
maxLines: 1,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Name',
// errorStyle: TextStyle(fontSize: 0, height: 0),
),
validator: (value) => (value.isEmpty) ? '**' : null,
),
),
FlatButton(
child: Text('Submit'),
onPressed: () {
formKey.currentState.validate();
},
)
],
),
)),
);
}
}
Solution 1. You can set helperText for the TextField's decoration and increase the Container's height:
Container(
height: 60,
child: TextFormField(
maxLines: 1,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Name',
helperText: ' ', // this is new
),
validator: (value) => (value.isEmpty) ? '**' : null,
),
),
Solution 2. You can set the line height of the error message to 0 (it will be displayed above the text field):
Container(
height: 38,
child: TextFormField(
maxLines: 1,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Name',
errorStyle: TextStyle(height: 0), // this is new
),
validator: (value) => (value.isEmpty) ? '**' : null,
),
),
You can use this
TextFormField(
decoration: new InputDecoration(
enabledBorder: OutlineInputBorder( //change border of enable textfield
borderRadius: BorderRadius.all(Radius.circular(40.0)),
borderSide: BorderSide(color: colorValue),),
focusedBorder: OutlineInputBorder( //focus boarder
borderRadius: BorderRadius.all(Radius.circular(40.0)),
borderSide: BorderSide(color: colorValue),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(width: 1,color: Colors.red),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(width: 1,color: Colors.orange),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(width: 1,color: Colors.green),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(width: 1,)
),
errorBorder: OutlineInputBorder(. //error boarder
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(width: 1,color: Colors.black)
),
isDense: true,
counterText: "",
contentPadding: EdgeInsets.fromLTRB(10, 20, 10, 0), //padding according to your need
hintText: "create new",
hintStyle: TextStyle(color: colorValue, fontSize: 13)),
)),
Thanks for the answer Mobina,
Seem like issues is flutter limitation. For time being..
with border I decide to display error message on top. (Your solution :1)
without border I can display err msg as usual. (Your solution : 2)
// with border
Container(
height: 38,
margin: EdgeInsets.all(6),
child: TextFormField(
textAlignVertical: TextAlignVertical.bottom,
style: TextStyle(fontSize: 14),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Name',
errorStyle: TextStyle(height: 0),
),
validator: (value) => (value.isEmpty) ? 'hide overlap' : null,
),
),
// without border
Container(
height: 38,
margin: EdgeInsets.all(6),
child: TextFormField(
textAlignVertical: TextAlignVertical.bottom,
style: TextStyle(fontSize: 14),
decoration: InputDecoration(
hintText: 'Name',
helperText: ' ', isDense: true,
counterText: "",
contentPadding: EdgeInsets.fromLTRB(10, 30, 10, 0),
),
validator: (value) => (value.isEmpty) ? 'hide overlap' : null,
),
),
Related
i have textFeilds i put empty feild validation but i don't know how to put another validation(Multiple validation) like "Email is invalid" or whatever i want. This is just important code, all code is a lill lengthy
final TextEditingController _emailControl = new TextEditingController();
bool _validateEmail = false;
child: TextField(
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(color: Colors.white,),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white,),
borderRadius: BorderRadius.circular(5.0),
),
hintText: "Email",
prefixIcon: Icon(
Icons.mail_outline,
color: Colors.black,
),
hintStyle: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
labelText: 'Email',
errorText: _validateEmail ? 'Email Can\'t Be Empty' : null,
),
maxLines: 1,
controller: _emailControl,
),
My registration button press is below
onPressed: () {
setState(() {
_emailControl.text.isEmpty ? _validateEmail = true : _validateEmail = false;
if ( _validateEmail == false ){
_isLoading = true;
khan();
}
});
Use TextFormField.
TextFormField(
validator(val):{
if(val.isEmpty){
return "This field cannot be empty",
}
else if(next conditon){
return ....
}
}
style: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(color: Colors.white,),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white,),
borderRadius: BorderRadius.circular(5.0),
),
hintText: "Email",
prefixIcon: Icon(
Icons.mail_outline,
color: Colors.black,
),
hintStyle: TextStyle(
fontSize: 15.0,
color: Colors.black,
),
labelText: 'Email',
errorText: _validateEmail ? 'Email Can\'t Be Empty' : null,
),
maxLines: 1,
controller: _emailControl,
),
And finally use form to validate the textfield.
I want to make my textfield go up when the keyboard appears. The keyboard is in front of textfield so I can't see what I write, I didn't found many solution to my problem or there were not very clean.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
conseil(text),
Spacer(),
InkWell(
onTap: () => [
pic.getImage().then((a) {
setState(() {
myimg = myimage;
});
})
],
child: Container(
decoration: BoxDecoration(
border: Border.all(width: 2.0, color: mygreen),
boxShadow: <BoxShadow>[
BoxShadow(
color: mygreen, blurRadius: 0, offset: Offset(7, 3))
],
shape: BoxShape.circle),
child: ClipOval(
child: SizedBox(
width: 140,
height: 140,
child: (myimg != null)
? Image.file(myimg, fit: BoxFit.fill)
: Image(
image: AssetImage('assets/images/others/add.png'),
fit: BoxFit.fill,
),
),
),
),
),
(myimage == null)?
Text("Choisir une photo"): SizedBox(height: 1),
Spacer(),
SizedBox(
width: 250,
child: TextField(
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Color(0xFF37cd41), width: 2)),
hintText: 'TON PRENOM',
hintStyle: TextStyle(color: Colors.white)),
controller: name,
),
),
Spacer(),
button(mypink, 'CONTINUER', widget.admin, context, name),
Spacer(),
],
),
),
);
}
}
Try using SingleChildScrollView and ConstrainedBox.
Scaffold(
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
child: yourWidget()
Checkout following answer: https://stackoverflow.com/a/59783374/12709039
Try out this one
Column(
children: <Widget>[
Expanded(
child: SingleChildScrollView(
child: Column(
(Your other Widgets)
import 'dart:async';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import '../weight/boostrap/flutter_bootstrap.dart';
import '../weight/boostrap/bootstrap_widgets.dart';
/*
TextEditingController txtname = TextEditingController();
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
builder: (context) => SingleChildScrollView(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom),
child: new AddItem(
tektk: 'Category',
tektd: 'Add',
txtname: txtname,
ismultik:false,
onPressed: () {}),
),
);
*/
class AddItem extends StatelessWidget {
const AddItem(
{Key? key,
required this.ismultik,
required this.tektd,
required this.tektk,
required this.txtname,
required this.onPressed})
: super(key: key);
final bool ismultik;
final String tektk;
final String tektd;
final VoidCallback? onPressed;
final TextEditingController txtname;
#override
Widget build(BuildContext context) {
final MediaQueryData mediaQueryData = MediaQuery.of(context);
bootstrapGridParameters(gutterSize: 10);
return Padding(
padding: mediaQueryData.viewInsets,
child: Container(
padding: EdgeInsets.only(bottom: 90.0, left: 10.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListTile(
trailing: SizedBox.fromSize(
size: Size(35, 35),
child: ClipOval(
child: Material(
color: Colors.indigo,
child: InkWell(
splashColor: Colors.white,
onTap: () {
Navigator.pop(context);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.close, color: Colors.white),
],
),
),
),
),
),
),
BootstrapRow(height: 0, children: [
BootstrapCol(
sizes: 'col-md-12',
child: TextField(
style: TextStyle(color: Colors.black),
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderSide: new BorderSide(color: Colors.white)),
labelText: tektk,
),
keyboardType: ismultik == true
? TextInputType.multiline
: TextInputType.text,
maxLines: null,
minLines: 1,
controller: txtname,
),
),
BootstrapCol(
sizes: 'col-md-12',
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green, // background
onPrimary: Colors.white, // foreground
),
onPressed: onPressed,
child: Text(tektd)),
),
]),
],
),
),
);
}
}
try to add scroll padding from Bottom for textfield
TextField(
scrollPadding: const EdgeInsets.only(bottom: 50), //add this line replace 50 with your required padding
),
import 'package:awwapp/Auth/registration.dart';
import 'package:flutter/material.dart';
// import 'package:flutter/services.dart';
class LoginPage extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
final emailField = TextField(
obscureText: false,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Email",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
);
final passwordField = TextField(
obscureText: true,
style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
hintText: "Password",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
);
final loginButon = Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: Color(0xff01A0C7),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {},
child: Text("Login",
textAlign: TextAlign.center,
style: style.copyWith(
color: Colors.white, fontWeight: FontWeight.bold)),
),
);
final registrationButton = Material(
elevation: 5.0,
borderRadius: BorderRadius.circular(30.0),
color: Color(0xff01A0C7),
child: MaterialButton(
minWidth: MediaQuery.of(context).size.width,
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => RegistrationPage()),
);
},
child: Text("Register",
textAlign: TextAlign.center,
style: style.copyWith(
color: Colors.white, fontWeight: FontWeight.bold)),
),
);
return Scaffold(
body: Form(
key: _formKey,
child: Center(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 155.0,
child: Image.asset(
"assets/logo/logo.png",
fit: BoxFit.contain,
),
),
SizedBox(height: 45.0),
emailField,
SizedBox(height: 25.0),
passwordField,
SizedBox(
height: 35.0,
),
loginButon,
SizedBox(
height: 15.0,
),
registrationButton,
],
),
),
),
),
),
);
}
}
"TextFormField(
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
); "
here is the my whole code
i am creating login for my project and i want to validate these fields that is mention at above and i want to add code that i mentioned in double qoutes how i can add these code in my above mention code
i Want to validate these fields but i am facing errors plz help me how can i add
how i can add code mention in double quotes in my above code
You already have a form. What you need to change the TextField to TextFormField.
TextFormField supports the validator method.
See the complete sample at bottom of this link
https://flutter.dev/docs/cookbook/forms/validation
I need the textfield should expand vertically up to 5 enter key pressed
after the 5th enter other lines are should enclose within the scrollbar
how can I achieve the textfield I need using flutter
now I set the maxlines: null in the textfield
thank you guys for your suggestions but I have found the actual textfield by the below code
Flexible(
child: new ConstrainedBox(
constraints: new BoxConstraints(
minWidth: size.width,
maxWidth: size.width,
minHeight: 25.0,
maxHeight: 135.0,
),
child: new Scrollbar(
child: new TextField(
cursorColor: Colors.red,
keyboardType: TextInputType.multiline,
maxLines: null,
controller: tc,
_handleSubmitted : null,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(
top: 2.0,
left: 13.0,
right: 13.0,
bottom: 2.0),
hintText: "Type your message",
hintStyle: TextStyle(
color:Colors.grey,
),
),
),
),
),
),
You can achieve by adding maxLine and minLine in TextField
new TextField(
minLines: 1,
maxLines: 5,
decoration: new InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 5.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 5.0),
),
hintText: 'Mobile Number',
),
)
The title sums up the question pretty well. I have a TextField with a maxLength: 250 and this is what it looks like:
Is there a way to put the counter somewhere else? Optimally to the left of the send button, but otherwise maybe just above and on the left of the TextField. Any ideas? Thanks!
Probably not necessary, but here's my code:
TextField(
controller: inputTextEditingController,
focusNode: inputFocusNode,
style: TextStyle(color: Platform.isAndroid ? Colors.green : Colors.blue, height: 0.8),
maxLength: 250,
maxLines: null,
decoration: InputDecoration(
contentPadding: const EdgeInsets.fromLTRB(20, 15, 0, 15),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(28)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Platform.isAndroid ? Colors.green : Colors.blue),
borderRadius: BorderRadius.circular(28)),
suffixIcon: IconButton(
onPressed: _handleSubmitted,
icon: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 20, 0),
child: Icon(Icons.send,
color: inputFocusNode.hasFocus
? Platform.isAndroid ? Colors.green : Colors.blue
: Colors.black54),
),
),
hintText: "Say something!",
hintStyle: inputFocusNode.hasFocus
? TextStyle(color: Platform.isAndroid ? Colors.green : Colors.blue, fontSize: 16)
: TextStyle(color: Colors.black54)),
You need to build and pass your own counter as a buildCounter parameter of a TextField Widget.
TextField(
maxLength: 250,
buildCounter: (_, {currentLength, maxLength, isFocused}) => Padding(
padding: const EdgeInsets.only(left: 16.0),
child: Container(
alignment: Alignment.centerLeft,
child: Text(currentLength.toString() + "/" + maxLength.toString())),
),
)
child: new TextField(
style: BurmeseUtil.textStyle(context),
controller: txtController,
maxLength: 1500,
maxLines: null,
decoration: new InputDecoration(
counterText: '',
border: OutlineInputBorder(),
),
),
Use decoration in TextField.Add counterText:' '
Good luck