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 ->
Related
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]')),
],
),
),
);
}
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
is there anyway to make TextFormField with prefix have same size with normal TextFormField? Tried to wrap it with container, but I'm afraid if using different device with different width will affect it. Thank you.
This is my code
TextFormField(
textInputAction: TextInputAction.next,
controller: namaField,
focusNode: _namaFocus,
autovalidateMode: AutovalidateMode.always,
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: Icon(Icons.person),
labelText: 'Nama Lengkap',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
SizedBox(height: 5),
TextFormField(
textInputAction: TextInputAction.done,
autovalidateMode: AutovalidateMode.always,
keyboardType: TextInputType.phone,
controller: noHpField,
focusNode: _noHpFocus,
decoration: const InputDecoration(
border: OutlineInputBorder(),
isDense: true,
prefixIcon: Padding(
padding: EdgeInsets.fromLTRB(4, 6, 4, 7),
child: Text("+62",
style: TextStyle(
fontSize: 16,
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;
},
),
Remove isDense: true.
Full Code :
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Welcome Flutter'),
),
body: new SafeArea(
top: true,
bottom: true,
child: Column(
children: [
SizedBox(
height: 20,
),
TextFormField(
textInputAction: TextInputAction.next,
controller: namaField,
focusNode: _namaFocus,
autovalidateMode: AutovalidateMode.always,
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: Icon(Icons.person),
labelText: 'Nama Lengkap',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
SizedBox(height: 5),
TextFormField(
textInputAction: TextInputAction.done,
autovalidateMode: AutovalidateMode.always,
keyboardType: TextInputType.phone,
controller: noHpField,
focusNode: _noHpFocus,
decoration: const InputDecoration(
border: OutlineInputBorder(),
// isDense: true, <-- Comment this.
prefixIcon: Padding(
padding: EdgeInsets.fromLTRB(4, 6, 4, 7),
child: Text("+62", style: TextStyle(fontSize: 16, 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;
},
),
],
)));
}
}
Try this:
Container(
width:MediaQuery.of(context).size.width*0.90,
child: TextFormField(
textInputAction: TextInputAction.next,
controller: namaField,
focusNode: _namaFocus,
autovalidateMode: AutovalidateMode.always,
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: Icon(Icons.person),
labelText: 'Nama Lengkap',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),),
Not sure what I'm missing. When selecting the value of drop-down, form onVaidate() fired which hence my other fields are showing the error. How can I stop it? Here is the code
Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(title: Text("Registration")),
// body: Center(child: Text(widget.user.displayName)),
// );
FirebaseUser user = widget.user;
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("Registration"),
),
body: SafeArea(
top: false,
bottom: false,
child: Form(
key: _formKey,
autovalidate: true,
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
TextFormField(
validator: (value) => value.isEmpty ? 'Name is Required' : null,
decoration: const InputDecoration(
icon: const Icon(Icons.person),
hintText: 'Enter your first and last name',
labelText: 'Name',
),
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.phone),
hintText: 'Enter a phone number',
labelText: 'Phone',
),
initialValue: user.phoneNumber,
enabled: user.phoneNumber == null,
keyboardType: TextInputType.phone,
validator: (value) => value.isEmpty ? 'Phone number is Required' : null
// inputFormatters: [
// WhitelistingTextInputFormatter.digitsOnly,
// ],
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.email),
hintText: 'Enter a email address',
labelText: 'Email',
),
initialValue: user.email,
enabled: user.email == null,
validator: (value) => value.isEmpty ? 'Email is Required' : null,
keyboardType: TextInputType.emailAddress,
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.remove_red_eye),
hintText: 'Enter the Password',
labelText: 'Password',
),
keyboardType: TextInputType.text,
obscureText: true,
validator: (value) => value.isEmpty ? 'Password is Required' : null
),
FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.card_membership),
labelText: 'ID Type',
),
isEmpty: _profile.govId == null,
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: _profile.govId,
isDense: true,
onChanged: (String newValue) {
setState(() {
_profile.govId = newValue;
state.didChange(newValue);
});
},
items: _govtIds.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
),
);
},
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.confirmation_number),
hintText: 'Enter your Governmenr ID number',
labelText: 'ID Number',
),
keyboardType: TextInputType.datetime,
validator: (value) => value.isEmpty ? 'ID Number is Required' : null
),
FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.business),
labelText: 'Block Info',
),
isEmpty: _profile.block == null,
child:
// Column(children: [RadioListTile(title: Text("A")),RadioListTile(title: Text("B"))]),
// Radio(
// value: 0,
// groupValue: _blocks,
// onChanged: (value){}),
DropdownButtonHideUnderline(
child:
DropdownButton(
value: _profile.block,
isDense: true,
onChanged: (String newValue) {
setState(() {
_profile.block = newValue;
state.didChange(newValue);
});
},
items: _blocks.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
),
);
},
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.home),
hintText: 'Enter your Flat number',
labelText: 'Flat number',
),
inputFormatters: [LengthLimitingTextInputFormatter(3)],
validator: (value) {
if (value.isEmpty) {
return 'Flat number is Required';
} else if (_profile.isValidHouseNumber() == false) {
return 'Invalid flat number';
} else {
return null;
}
},
keyboardType: TextInputType.number,
onChanged:(value) {
_profile.houseNo = value;
},
),
Padding(
padding: EdgeInsets.fromLTRB(38.0, 30.0, 0.0, 0.0),
child: SizedBox(
height: 50.0,
child: FlatButton(
// elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Colors.green,
child: Text('Submit',
style: TextStyle(fontSize: 20.0, color: Colors.white)),
onPressed: _validateAndSubmit,
),
))
],
))),
);
}
Call a method to return null in the validate fucntion all the other fields. That will clear the validation. It's a fix, but doesn't solve the problem.
There seems to be nothing wrong with the code above, can you add the code for the other fields too?
EDIT:
The reason all the other fields validate is because of the autovalidate: true property of the parent Form widget. Remove it and wrap each TextFormField with a Form with different keys.
For example, your TextFormField should look as follows:
Form(
key: _formKey[0],
child: TextFormField(
validator: (value) => value.isEmpty ? 'Name is Required' : null,
decoration: const InputDecoration(
icon: const Icon(Icons.person),
hintText: 'Enter your first and last name',
labelText: 'Name',
),
),
),
Wrap it with a Form, _formKey is declared as
List<GlobalObjectKey<FormState>> _formKey = new List(number_of_keys);
Call the respective setState like so:
_formKey[position].currentState.setState((){});
And don't forget to remove the parent Form widget.
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);