I have to make one application which take so many user input , that's why i use so many Textfiled in my code for taking user input.
An Textfiled validation time I simply use List of Global keys and it's work perfactly.
But problem is when user give wrong input then textfiled show an error message that time my Textbox UI can change (UI well change in very appropriately).
Pleas help , what can i do so my error message postion will be changed.
TextFiled code :
//this is inside the statfull Widget
GlobalKey<FormState> _formkeySubNumber = new GlobalKey();
Widget SubNumber_Input_Box() {
return Form(
//for form validation
key: _formkeySubNumber,
child: Container(
margin: EdgeInsets.only(top: 7, left: 6),
height: 38,
width: 300,
decoration: BoxDecoration(
color: HexColor("#D9D9D9"),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
//padding
child: Padding(
padding: EdgeInsets.only(left: 12),
//textfiled
child: TextFormField(
//for validation
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Subject Number';
}
return null;
},
//for storing user input && value in string format so we convert into the int formate
onChanged: (value) {
subjectNumber = int.tryParse(value)!;
},
//for only number
keyboardType: TextInputType.number,
decoration: const InputDecoration(
hintText: "Enter Minimum-4 to Maximum-8 Subject",
hintStyle: TextStyle(
fontFamily: "RobotoSlab",
fontSize: 14,
),
//for remove underline from input filed
border: InputBorder.none,
),
//for store only integer value
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
),
),
),
);
}
And this call inside the one Button Like that
[Container(
margin: EdgeInsets.only(top: 5),
child: ElevatedButton(
child: Text("Go"),
style: ElevatedButton.styleFrom(
primary: HexColor("#EE6C4D"),
//this colour set (opacity is low) when button is disable
onSurface: HexColor("#E0FBFC"),
),
//store user value -->subjectNumber
onPressed: isGoButtonActive
? () {
//for Form Validation
if (_formkeySubNumber.currentState!
.validate()) {
//this show the container after prerssed button
showContainer1();
}
setState(() {
// //this is for store subjectnumber value from user input
// subjectNumber =
// subNumber_Controller.text;
// print("Subject Number Is : $subjectNumber");
});
}
: null,
),
),]
You have created a container around the textfield with specific height. For styling a textfield you can use
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
filled: true,
hintStyle: TextStyle(color: Colors.grey),
hintText: "Type in your text",
fillColor: Colors.white),
)
This way the error message appears below the textfield and outside the white area.
You can remove the height from Form> Container. And it will give you flexible height based on error state.
Widget SubNumber_Input_Box() {
return Form(
key: _formkeySubNumber,
child: Container(
width: 300,
color: HexColor("#D9D9D9"),
//padding
child: Padding(
padding: EdgeInsets.only(left: 12),
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction, // you might like this as well
Also I will suggest to look at OutlineInputBorder
Widget SubNumber_Input_Box() {
return Form(
key: _formkeySubNumber,
child: Padding(
padding: EdgeInsets.only(left: 12),
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
//for validation
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Subject Number';
}
return null;
},
//for storing user input && value in string format so we convert into the int formate
onChanged: (value) {
subjectNumber = int.tryParse(value)!;
},
//for only number
keyboardType: TextInputType.number,
decoration: const InputDecoration(
hintText: "Enter Minimum-4 to Maximum-8 Subject",
hintStyle: TextStyle(
fontFamily: "RobotoSlab",
fontSize: 14,
),
enabledBorder: OutlineInputBorder(),
errorBorder: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(),
border: OutlineInputBorder(),
),
//for store only integer value
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
),
),
);
}
Related
I want to build a textFormFeild so that it is like the one in the image below, in addition to that I can control its properties such as default textFormFeild and it is responsive.
In the case of focus, the background color is changed. I want to build a costume.
Empty case:
Fill case:
Code:
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(hintText: 'Enter Your Email'),
)
Try below code hope its help to you, I have try same
Variable Declaration:
TextEditingController textEditingController = TextEditingController();
bool isTextEmpty = false;
Widget:
Container(
padding:const EdgeInsets.only(top: 10, left: 15),
height: 60,
decoration: BoxDecoration(
color: isTextEmpty ? Colors.white : Colors.grey.shade200,
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: isTextEmpty ? Colors.red : Colors.grey.shade300,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Email'),
TextField(
controller: textEditingController,
onChanged: (value) {
setState(() {
if (value.length > 0) {
isTextEmpty = true;
} else {
isTextEmpty = false;
}
});
},
decoration: const InputDecoration(
isDense: true,
border: InputBorder.none,
hintText: 'Enter Email Here',),
),
],
),
),
Result before empty TextField:
Result after fill TextField
You need to check the validation process as follows.
TextFormField(
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
In Flutter, when text is entered that is longer than the field, the text is hidden, as shown in the gif:
The code from first text form field:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
labelFormStyle("Nome do equipamento"),
Container(
height: hasErrorForm && equipmentNameController.text.isEmpty ? 55 : 35,
child: Container(
height: hasErrorForm && equipmentNameController.text.isEmpty ? 55 : 35,
child: TextFormField(
validator: (value){
return validatorEmpty(value);
},
controller: equipmentNameController,
keyboardType: TextInputType.multiline,
maxLines: null,
textInputAction: TextInputAction.next,
style: TextStyle(
fontSize: 14
),
decoration: InputDecoration(
isDense: true,
enabledBorder: enableBorderField(),
focusedBorder: enableBorderField(),
disabledBorder: enableBorderField(),
border: enableBorderField(),
focusedErrorBorder: errorBorderField(equipmentNameController.text.isEmpty),
errorBorder: errorBorderField(equipmentNameController.text.isEmpty)
),
onChanged: (value){
if(hasErrorForm){
setState(() {
_formKey.currentState!.validate();
});
}
},
),
),
],
),
How to solve this?
I managed to solve the problem by removing the height restriction and putting maxLines: 1. The only problem is that it didn't get the size the designer wanted, but I'll talk to him about it
I've often seen where fields are responsive when users are typing, giving realtime feedback. An example is when I'm typing confirm password or email, if the confirm password or email hasn't matched the password while typing it returns error by marking turning the border of the field red until it matches the correct input. I have written this code, how do I improve the code to be responsive as described.
Widget _buildConfirmPasswordTF() {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
// Text('Password', style: kLabelStyle,),
SizedBox(height: 10.0),
Container(alignment: Alignment.centerLeft, decoration: kBoxDecorationStyle, height: 60.0, child: TextFormField(
validator: ( confirmPassword ){
if ( confirmPassword.trim() != _password.isValidPassword ) {
return null;
} else {
return 'Password doesn\'t match';
}
},
obscureText: true, style: TextStyle(color: Colors.white, fontFamily: 'OpenSans',),
decoration: InputDecoration(border: InputBorder.none, contentPadding: EdgeInsets.only(top: 14.0),
prefixIcon: Icon(Icons.lock, color: Colors.white,),
hintText: 'Enter Confirm Password',
hintStyle: kHintTextStyle,
errorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red ) ),
focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.red ) )
),
),
),
],
);
}
This is where I set the hintText
final kHintTextStyle = TextStyle(
color: Colors.white54,
fontFamily: 'OpenSans',
);
This is where I set the labelStyle
final kLabelStyle = TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'OpenSans',
);
This is where I set the border decoration
final kBoxDecorationStyle = BoxDecoration(
color: Color(0xFF6CA8F1),
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 6.0,
offset: Offset(0, 2),
),
],
);
you need autovalidateMode: AutovalidateMode.onUserInteraction, pass this in textformfield.
You can do that with a Form() providing it a key and a autoValidateMode to make sure the fields have value or that the value is something you except, you can add another field to confirm the passwork or email and compare the value of the field in the onChanged with the value of the other email field to make sure they match.
import 'package:email_validator/email_validator.dart';
final formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
bool isValid = false;
_emailController.addListener(
() {
//With this, you can "listen" all the changes on your text while
//you are typing on input
//use setState to rebuild the widget
if (EmailValidator.validate(_emailController.text)) {
setState(() {
isValid = true;
});
} else {
setState(() {
isValid = false;
});
}
},
);
Form(
key: formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(
horizontal: size.width * 0.105),
child: TextFormField(
validator: (value) =>
!EmailValidator.validate(value)
? 'Enter a valid email'
: null,
keyboardType: TextInputType.emailAddress,
textAlign: TextAlign.center,
controller: _emailController,
decoration: kInputDecoration.copyWith(
hintText: 'Enter your email'),
),
),
SizedBox(
height: 18,
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: size.width * 0.105),
child: TextFormField(
obscureText: true,
validator: (value) =>
value.isEmpty ? 'Enter your password' : null,
keyboardType: TextInputType.text,
textAlign: TextAlign.center,
controller: _passwordController,
decoration: kInputDecoration.copyWith(
hintText: 'Enter your password'),
),
),
],
),
),
First, Recently I have started to building desktop app with dart code.
just built some screens and which are responsible for mobile and web too, for that used LayoutBuilder
but going wrong with when trying to set the height according to mine, for that I wrapped TextformField with Container and gave height.
when I put validation on TextformField onClick of login button then something goes wrong with the height of TextformField.
Look at the Screenshot:
before of click the login button:
When I click the login button without inputting any value for checking validation:
Piece of code of TextformField :
Widget _buildEmailTextField() {
return Container(
height: 35,
child: Theme(
data: new ThemeData(
primaryColor: Color(0xFF262C48),
primaryColorDark: Color(0xFF262C48),
),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
validator: (val){
bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(val);
if(!emailValid){
return 'Invalid Email Address';
}else{
return null;
}
},
controller: emailController,
readOnly: isLoading?true:false,
decoration: InputDecoration(
fillColor: Color(0xFFd9d8d8),
filled: true,
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(7.0),
),
borderSide: BorderSide(color:Color(0xFF262C48),width: 2.0)
),
contentPadding: EdgeInsets.only(left: 10),
// prefixIcon: Icon(
// Icons.email,
// color: Color(0xFF008577),
// ),
hintText: 'Email',
),
),
),
);
}
TextFormField inherits size from child. One of solution is to set contentPadding in InputDecoration.
You already use this to pad left side. You can do modification like below:
contentPadding: EdgeInsets.only(left: 10.0, top: 15.0, bottom: 15.0),
Please check it out,
Widget _buildEmailTextField()) {
return Container(
height: 35,
child: Theme(
data: new ThemeData(
primaryColor: Color(0xFF262C48),
primaryColorDark: Color(0xFF262C48),
),
child: Form(
key: _formKey,
child: Column(
children: [
SizedBox(
height: 20,
),
Container(
child: TextFormField(
keyboardType: TextInputType.emailAddress,
validator: (val) {
bool emailValid = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(val);
if (!emailValid) {
return 'Invalid Email Address';
} else {
return null;
}
},
controller: emailController,
readOnly: isLoading ? true : false,
decoration: InputDecoration(
fillColor: Color(0xFFd9d8d8),
filled: true,
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(7.0),
),
borderSide:
BorderSide(color: Color(0xFF262C48), width: 2.0)),
contentPadding: new EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
// prefixIcon: Icon(
// Icons.email,
// color: Color(0xFF008577),
// ),
hintText: 'Email',
),
),
),
RaisedButton(
onPressed: () {
// Validate returns true if the form is valid, otherwise false.
if (_formKey.currentState.validate()) {
// If the form is valid, display a snackbar. In the real world,
// you'd often call a server or save the information in a database.
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Processing Data')));
}
},
child: Text('Submit'),
)
],
),
),
),
);
}
When using TextFormField in Flutter and having the form prefilled with text, when I tap somewhere on it in order to start editing the text, I get the little rain drop pointer right over the text:
I expect it to appear a little bit below the form. Something like this:
Here is the code:
Container(
height: 40.0,
child: TextFormField(
style: TextStyle(
fontSize: 17,
),
controller: serverAddressController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: new BorderRadius.circular(10.0),
),
),
onChanged: (value) {
serverAddress = value;
changesSaved = false;
},
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
FocusScope.of(context)
.requestFocus(daysBackFocusNode);
},
),
),
How do I do it?
you've set Container height to low but didn't reduce content paddings
just add contentPadding property
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 16, right: 16),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.0),
),
),