I want to insert a border to my text field as image showing. how can I do this. here's my code I have implemented so far with no borders.
TextFormField(
controller: emailEditingController,
enabled: typing,
decoration: const InputDecoration(
hintText: "Email",
hintStyle: TextStyle(
color: textGrey, fontFamily: "Dubai", fontSize: 14),
),
validator: (String? UserName) {
if (UserName != null && UserName.isEmpty) {
return "Email can't be empty";
}
return null;
},
onChanged: (String? text) {
email = text!;
// print(email);
},
onSaved: (value) {
loginUserData['email'] = value!;
},
),
you can edit the border by adding a border to the decoration of your field:
TextFormField(
controller: emailEditingController,
enabled: true,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText: "Email",
hintStyle:
TextStyle(color: Colors.grey, fontFamily: "Dubai", fontSize: 14),
),
validator: (String? UserName) {
if (UserName != null && UserName.isEmpty) {
return "Email can't be empty";
}
return null;
},
onChanged: (String? text) {
email = text!;
// print(email);
},
onSaved: (value) {
// loginUserData['email'] = value!;
},
),
the output would look like:
please add Containers padding property and contentPadding property to this code so you can achieve the layout
Container(
padding:
EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 20),
child: TextFormField(
contentPadding: EdgeInsets.fromLTRB(20, 5, 10, 5),
this is my full code
Container(
padding:
EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 20),
child: TextFormField(
controller: emailEditingController,
decoration: InputDecoration(
alignLabelWithHint: true,
floatingLabelBehavior:FloatingLabelBehavior.never,
contentPadding: EdgeInsets.fromLTRB(20, 5, 10, 5),
labelText: "Email/User name",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintStyle: TextStyle(
color: textGrey, fontFamily: "Dubai", fontSize: 14),
),
validator: (String? UserName) {
if (UserName != null && UserName.isEmpty) {
return "Email can't be empty";
}
return null;
},
onChanged: (String? text) {
// email = text!;
// print(email);
},
onSaved: (value) {
// loginUserData['email'] = value!;
},
)),
out put will be
Related
Still a newbie with flutter and was wondering if someone could help me with a problem I'm having. I am trying to create a registeration form with email, password, password confirmation, a county and a zip code. (County and zip code forms are the drop down button form fields) I have successfully coded all else except for the zip code drop down. I would need it to be conditional on the county selection. (In a way that if I select a specific county in cali, it would only display that selected county's zip codes and nothing else). Also if someone would know a quick fix to make the dropdown button form fields empty unless clicked on. My current adaptation on it isn't very functional, since you can just leave the option unanswered, when it's supposed to be mandatory. Thank you in advance :)
Existing code below
(I only have the string for one county zip codes) (Also deleted the irrelevant firebase related code for this post)
class RegisterPage extends StatefulWidget {
const RegisterPage({Key? key}) : super(key: key);
#override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
// dropdown area
_MyFormStateArea(){
selectedArea = dropdownListArea[0];
}
var selectedArea = '';
final dropdownListArea = <String>['', 'LA', 'San Francisco'...'Santa Barbara'];
// dropdown zipcode
_MyFormStateZip(){
selectedZip = dropdownListZip[0];
}
var selectedZip = '';
final dropdownListZip = <String>['', '90001', '90002', '90003',..., '91609'];
// editing Controller
final emailEditingController = new TextEditingController();
final passwordEditingController = new TextEditingController();
final confirmPasswordEditingController = new TextEditingController();
#override
Widget build(BuildContext context) {
// email field
final emailField = TextFormField(
autofocus: false,
controller: emailEditingController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return ("Please enter email.");
}
// reg expression for email validation
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Please enter a working email.");
}
return null;
},
onSaved: (value) {
emailEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.mail_outline_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// password field
final passwordField = TextFormField(
autofocus: false,
controller: passwordEditingController,
obscureText: true,
validator: (value) {
RegExp regex = new RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return ("A password required.");
}
if(!regex.hasMatch(value)) {
return ("Please enter other password (Min. 6 characters)");
}
},
onSaved: (value) {
passwordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
));
// confirm password field
final confirmPasswordField = TextFormField(
autofocus: false,
controller: confirmPasswordEditingController,
obscureText: true,
validator: (value)
{
if(confirmPasswordEditingController.text != passwordEditingController.text)
{
return "Passwords don't match";
}
return null;
},
onSaved: (value) {
confirmPasswordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password again",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// area dropdown
final areaField = DropdownButtonFormField(
value: selectedArea,
items: dropdownListArea.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: dropdownListZip.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// sign up button
final signUpButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.white,
child: MaterialButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
signUp(emailEditingController.text, passwordEditingController.text);
},
child: Text("Sign Up", textAlign: TextAlign.center,
style: TextStyle(fontSize: 20,
color: Colors.lightBlue[900],
fontWeight: FontWeight.bold)
),
),
);
return Scaffold(
backgroundColor: Color(0xFFAED8E6),
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => FrontPage()));
},
icon: Icon(Icons.arrow_back),
color: Colors.lightBlue[900],
),
),
body: Center(
child: SingleChildScrollView(
child: Container(
color: Color(0xFFAED8E6),
child: Padding(
padding: const EdgeInsets.fromLTRB(36, 20, 36, 30),
child: Form(
key: _formKey,
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 170,
child: Image.asset("assets/AR_logoBold.png",
fit: BoxFit.contain
)),
SizedBox(height: 40,),
emailField,
SizedBox(height: 25,),
passwordField,
SizedBox(height: 25,),
confirmPasswordField,
SizedBox(height: 25,),
areaField,
SizedBox(height: 25,),
zipCodeField,
SizedBox(height: 35,),
signUpButton,
SizedBox(height: 15,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("You already own an account? "),
GestureDetector(onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage()));
},
child: Text("Login",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.lightBlue[900])
),)
],
)
],
)),
),
),
),
),
);
}
}
First you should initalize the selectedArea and selectedZip with the first Entry of your List: = dropdownListZip.first and the first entry should not be an empty String
To get only zips that belong to the choosen area you need to know them. At the moment you have two independent lists.
Better you use a map like:
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
Than you can only display zips that belong to the area quite easy.
Take a look at: Flutter Documentation for Map
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
final areaField = DropdownButtonFormField(
value: selectedArea,
items: zipmap.keys.toList().map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: zipmap[selectedArea].map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
I have a TextFormField. This widget validation is empty show error text. However, the error text fill looks like the picture. How can i solve it.
SizedBox(
height: 50,
child: TextFormField(
validator: (val) {
if (val!.isEmpty) {
return "Boş Geçilemez";
}
if (val.length > 100) {
return "Karakter Sınırı Hatası";
}
return null;
},
obscureText: true,
decoration: InputDecoration(
suffixIcon: const Icon(
Icons.lock_outline_rounded,
color: Color(0xffBDBDBD),
),
hintText: AppLocalizations.getString("sifre"),
contentPadding:
const EdgeInsets.only(top: 14, left: 10, bottom: 10)),
controller: passwordController,
),
),
It would be better if you use same content padding for top and bottom, and try increasing the height of TextFiled like 64.
And use autovalidateMode: AutovalidateMode.onUserInteraction,
SizedBox(
height: 64,
child: TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (val) {
if (val != null && val.isEmpty) {
return "Boş Geçilemez";
}
if (val!.length > 10) {
return "Karakter Sınırı Hatası";
}
return null;
},
decoration: InputDecoration(
suffixIcon: const Icon(
Icons.lock_outline_rounded,
color: Color(0xffBDBDBD),
),
hintText: "sifre",
contentPadding: const EdgeInsets.only(
top: 14,
left: 10,
bottom: 14,
)),
),
),
is there any way to make the prefix is aligned with the input field and not floating like that?
This is my code for it
TextFormField(
autovalidateMode: AutovalidateMode.always,
keyboardType: TextInputType.phone,
controller: noHpField,
decoration: const InputDecoration(
isDense: true,
prefixIcon:Text("+62", style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold)),
prefixIconConstraints: BoxConstraints(minWidth: 0, minHeight: 0),
icon: Icon(Icons.phone_android),
labelText: 'No HP',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
TextFormField(
autovalidateMode: AutovalidateMode.always,
keyboardType: TextInputType.phone,
controller: noHpField,
decoration: const InputDecoration(
border: OutlineInputBorder(),
isDense: true,
prefixIcon: Text("+62",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold)),
prefixIconConstraints:
BoxConstraints(
[![enter image description here][1]][1] minWidth: 0, minHeight: 0),
icon: Icon(Icons.phone_android),
labelText: 'No HP',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
You can use Padding property in the prefixIcon to make it look more neat.
Try below code hope its help to you and use OutlineInputBorder() as border
TextFormField(
autovalidateMode: AutovalidateMode.always,
keyboardType: TextInputType.phone,
controller: noHpField,
decoration: InputDecoration(
border: OutlineInputBorder(),
isDense: true,
prefixIcon: Padding(
padding: EdgeInsets.all(8.0),
child: Text(
"+62",
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
prefixIconConstraints: BoxConstraints(
minWidth: 0,
minHeight: 0,
),
icon: Icon(Icons.phone_android),
labelText: 'No HP',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
Your Screen result without input data like ->
Your Screen reult with input data like ->
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'),
),
),
],
),
),
How I can put the icon while typing the email to verifying from email regex and the strength of the password?
TextFormField(
controller: _emailController,
textAlign: TextAlign.end,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "example#gmail.com",
fillColor: Colors.grey[200],
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
borderRadius: BorderRadius.circular(14))),
onSaved: (String value) {
email = value;
},
validator: _validateEmail,
keyboardType: TextInputType.emailAddress,
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 20, 0),
child: Text(
"كلمة المرور",
textAlign: TextAlign.right,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16),
),
),
new TextFormField(
controller: _passwordController,
textAlign: TextAlign.end,
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
prefixIcon: new GestureDetector(
onTap: () {
setState(() {
_obscureText = !_obscureText;
});
},
child: Padding(
padding:
const EdgeInsets.fromLTRB(20, 10, 0, 0),
child: Icon(
_obscureText
? Icons.visibility
: Icons.visibility_off,
color: visi),
)),
hintStyle: TextStyle(fontSize: 16),
hintText: "",
fillColor: Colors.grey[200],
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
borderRadius: BorderRadius.circular(14))),
onSaved: (String value) {
password = value;
},
validator: _validatePassword,
obscureText: !_obscureText,
),
For email, you can add a listener to your _emailController like:
var _myIcon = Icon.cancel;
void initState() {
super.initState();
// Start listening to changes.
_emailController.addListener(_checkEmail);
}
And then:
_checkEmail() {
bool emailValid = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(_emailController.text);
if(emailValid)
setState(() {
_myIcon=Icons.ok;
});
}
Now add a prefixIcon to your email field with _myIcon value.
For a password with :
Minimum 1 Upper case
Minimum 1 lowercase
Minimum 1 Numeric Number
Minimum 1 Special Character
Common Allow Character ( ! # # $ & * ~ )
and based on this answer you can use a Regex like this:
RegExp(r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$').hasMatch(_passwordController.text);