Form validation with regEx dosn't work in flutter - flutter

I'm Working in login screen and i want t make the basic regEx for it.
I'm using custom UI Elements library from BeautyTextField
this is my email and password input widgets
Widget emailInput(){
return BeautyTextfield(
validator: (value)=>RegExp(r"^[a-zA-Z0-9.]+#[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email)?"Enter Valid Email":null,
decoration: InputDecoration(labelText:"Email"),
cornerRadius: BorderRadius.all(Radius.circular(50)),
width: double.maxFinite,
height: 50,
duration: Duration(milliseconds: 300),
inputType: TextInputType.emailAddress,
keyboardType: TextInputType.emailAddress,
prefixIcon: Icon(Icons.alternate_email),
placeholder: "Email",
onSaved: (value)=> email = value,
fontFamily: "Muli",
); }
Widget passwordInput(){
return BeautyTextfield(
validator: (value)=> value.length == 6 ? "Enter Password of 6 Numbers":null,
cornerRadius: BorderRadius.all(Radius.circular(50)),
width: double.maxFinite,
height: 50,
duration: Duration(milliseconds: 300),
inputType: TextInputType.text,
prefixIcon: Icon(Icons.lock_outline),
obscureText: true,
placeholder: "Password",
onSaved: (value)=> password = value,
);
}
and my form widget:
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
/////////////////////////////////////////////////////////////
/// Form Body
key: signINformKey,
child:
Column(
children: <Widget>[
emailInput(),
passwordInput(),
submitButton(),
signUpButton(),
],
),
);}
I'm using this function on press on login button if the data is match with regEx so it will redirect to another page else it should show up a snack bar with message "Login Error", but it doesn't work and every time i click the login button it redirect to the other page even if the regEx is not matched because signINformKey.currentState.validate() is always return true

Actually, the hasMatch() function will return true if the string satisfies the regex. The code that you have in place for the validator always returns null because the email string doesn't match the regex that's why you get directed to next page instead of showing a Snackbar. You could add ! this before the regex as this will inverse the result.
code:
validator: !RegExp(r"^[a-zA-Z0-9.]+#[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(email)?"Enter Valid Email":null

Using the onChange to assign values inside input fields to variables and check on these variables

Related

Textfields in a Row Not Aligned on Validation

I have a bottom sheet that displays a set of text fields and on there is a row with two textfields. These two textfields have validation and when one field meets the validation and the other doesn't, the textfields in this row get misaligned.
As you can see, 'Expires End' is not aligned with 'CVV' when there is a validation message showing. How can I make sure that the aligns when there is a validation message.
Just Wrap your Row With IntrinsicHeight and set alignment of Row.
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(),
TextField()
],
),
)
You can use the settings in the decoration argument of TextField:
you can set the error text height as below in order to avoid the widget rearrangement on failed validation:
decoration: const InputDecoration(
errorStyle: TextStyle(height: 0),
)
This will keep the widget aligned, but then you have to put a Text widget somewhere, because this will mess up the layout if you return a String from your validator to show an error.
Here's an more complete example: since this was a password field of a login field, I didn't need to show an error to let the user understand that something was wrong, and the red underline that appeared was enough to let the user understand what went wrong
//...at some point in your form
TextFormField(
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
errorStyle: TextStyle(height: 0),
),
controller: pwdTec,
validator: (value) {
if (value == null || value.isEmpty || value.length < 8) {
return ""; //this will just underline the field in red
}
return null;
},
onFieldSubmitted: (_) => _formSubmit(),
),
Text(_errorMessage), //_errorMessage is a field of a StatefulWidget, that gets update by _formSubmit() with a setState() in case of errors that require an explanation
//...rest of the form

Validate a non-visible field in Flutter Form

I have a Flutter Form with many dropdownformfield and textformfield widgets, validating these is trivial using the validate: method. Validation for visual fields is obvious.
However, in many forms a non-visible element may need to be validated. For instance, if taking a picture in a Form, there will only be a button to take the picture which will input the resulting filename into a String var. I would need to validate the String var in this case and return the validation result to the button (i.e. display a "Required field" below the button), but of course the String var is not held in any formfield widget.
This being said, how can I either "wrap" the button in a widget which contains a validator: method, or how can I add a validator to the button itself AND then display the appropriate validation message to the user in the UI?
Thank you!
You could create your own FormField:
class TakePictureFormField extends FormField<String> {
/// Creates a [FormField] that contains an [ElevatedButton] to take a picture
/// with the phone camera.
///
/// The [String] value corresponds to the path of the picture taken.
TakePictureFormField({
Key? key,
String? initialValue,
FormFieldSetter<String>? onSaved,
FormFieldValidator<String>? validator,
bool enabled = true,
AutovalidateMode? autovalidateMode,
ButtonStyle? buttonStyle,
void Function(String)? onChanged,
}) : super(
key: key,
initialValue: initialValue,
onSaved: onSaved,
validator: validator,
enabled: enabled,
autovalidateMode: autovalidateMode,
builder: (FormFieldState<String> field) {
final currentValue = field.value;
return InputDecorator(
decoration: InputDecoration(
border: InputBorder.none,
errorText: field.errorText,
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(field.context).errorColor,
),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
style: buttonStyle,
onPressed: () async {
// Fake implementation to take a picture.
final value = await Future<String>.delayed(
const Duration(microseconds: 300),
() => 'my_path/to/image');
field.didChange(value);
if (onChanged != null) {
onChanged(value);
}
},
child: const Text('Take a Picture'),
),
if (currentValue != null) Text(currentValue),
],
),
);
},
);
}
And then use it inside a Form like you would for any other FormField widget:
TakePictureFormField(
validator: (val) =>
val == null || val.isEmpty ? 'Error invalid picture' : null,
)
Try the complete example on DartPad

How to make TextField which has 2 hintText?

I have ui of text field from Figma.
There are 2 hint texts where 1st hintText is located at the beginning of textfield and other one is at the end.
As can be seen, trailing is hint text which is disappearing when user inputs number.
If you have any idea please share how to make this kind of text field)
Try this:
TextField(
textAlign: TextAlign.end,
decoration: InputDecoration(
prefixIcon: Padding(
padding: EdgeInsets.all(15), child: Text('Prefix')),
border: OutlineInputBorder(),
hintText: "Cym",
),
),
You can just use the trailing for the hint and can you onChanged method to handle changes.. Like you will be managing your text on the behavior of input. For example if the input is empty then you text will be something like "A" if you input something text will be changed.
TextFormField(
decoration: InputDecoration(
suffix: Text(text)
),
onChanged: (value) {
// handle or change your text here
if(value.isEmpty){
setState(() { text = "A"});
}
else{
setState(() { myState = "any text"});
}
},
)

Flutter - Textfield reaction when focus changes

I've made a program where the user can create an account, but I've placed some restrictions on the textfields (like for the First Name, it can only accept a string made of A-Z or a-z).
I want an "error text" to show under the textfield if the input is wrong (like if the user types "John1"), but I don't know how to do this. The simple way would be to use the onEditingComplete but this only works if the user taps on the keyboard the "done" key.
Is there a way to make the "error text" appear when the focus changes from one textfield to another?
You can use the validator property of the textfield to do this. It is recommended to encapsulate your fields in a Form() widget and then use the FormTextField() widget to implement your validations, this will enable an error to be shown at the bottom of the text field, if focus changes, or submission is attempted.
Example:
TextFormField(
onSaved: (String value) {},
validator: (String value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
)
The error will appear below in red fonts.
If you want to show error text whenever text/value changed you can do this.
In TextField 'onChanged' validate the user input using some regex and check for error ,if there is an error using TextField decoration 'errorText' property you can show required error.
Widget phoneNumberTextField() {
return Padding(
padding: EdgeInsets.fromLTRB(25, 10, 25, 10),
child: TextField(
style: TextStyle(color: Colors.white),
controller: _phoneNumberController,
maxLength: Constants.PhoneNumberTextFieldMaxLength,
onChanged: (value) {
_phoneNumberErrorText =
validatePhoneNumberTextField(_phoneNumberController.text);
_hasPhoneNumberError = _phoneNumberErrorText.isNotEmpty;
setState(() {});
},
keyboardType: TextInputType.number,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green, width: 1.0),
),
errorText: _hasPhoneNumberError ? _phoneNumberErrorText : null),
),
);
}
String validatePhoneNumberTextField(String text) {
String errorText = '';
if (text.length < 1) {
errorText = 'Phone Number should not be empty';
} else if (text.length != 10) {
errorText = 'Please enter valid phone number.';
}
return errorText;
}

Show error text of widget on button click

I have below code which needs to be get called on button click to show error Text, as condition failed on button click.
Error Text:
final confirmPassword = TextFormField(
controller: widget.confirmPasswordController,
obscureText: true,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_open, color: Colors.grey),
hintText: 'Confirm Password',
errorText: validatePassword(widget.confirmPasswordController.text)
? "Password should contains more then 5 character"
: null,
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
),
);
Button Click:
onPressed: () {
if (validateEmail(widget.emailController.text) &&
validatePassword(widget.passwordController.text) &&
validatePassword(widget.confirmPasswordController.text)) {
// launch new screen
} else {
// show the error text as above checks failed
}
}
How we can achive this? will setState() help us?
You can achieve it by use Form widget with key. Like
Declare
GlobalKey<FormState> _globalFormKey = GlobalKey();
and set it to
Form(
key: _globalFormKey,
.
.
.
child:
)
Here you can use child as TextFormField and write on button click failure.
_globalFormKey.currentState.validate()
For more info Form widget
~PS: Instead of check validation out of TextFormField, It has own property validator. Search and use it.
Using a Form widget.
Flutter has a good topic about it with complete examples: Build a form with validation