Reputation: 389
I have 2 form fields,I want to validate the second form field to match the password from the first one,I tried but no success..thanks for answering.
Updated : I already have submit button and its working,I want Validator in the second field to validate the first field text to match the second field.
new TextFormField(
controller: _registerPassController,
decoration: new InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) =>
value.isEmpty ? 'Password can\'t be empty' : null,
onSaved: (value) => _password = value,
),
],
),
new Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
new TextFormField(
controller: _registerPassController2,
decoration: new InputDecoration(labelText: 'Retype Password'),
obscureText: true,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
},),
Upvotes: 18
Views: 14552
Reputation: 1
You can use a validator.
Define the validator:
class TwoFieldsMatchValidator extends TextFieldValidator {
String checkField;
TwoFieldsMatchValidator({required this.checkField, required String errorText}) : super(errorText);
@override
bool get ignoreEmptyValues => true;
@override
bool isValid(String? v) {
return checkField == v;
}
}
Use the validator:
final _controller = TextEditingController();
TextFormField(
...
validator: MultiValidator(
[
TwoFieldsMatchValidator(
checkField: _controller.text,
errorText: "<Error>",
),
],
),
),
Hope this helps anyone in future.
Upvotes: 0
Reputation: 301
To have the operation done in the TextField's validator, we can use the onChanged event to capture the value of the password field and use it later in the validator of the confirm password field.
String _password;
Widget _passwordField() {
return new TextFormField(
autocorrect: false,
obscureText: true,
decoration: InputDecoration(labelText: 'Password'),
onChanged: (value) => _password = value,
validator: (value) =>
value.isEmpty ? "Password can't be empty" : null,
}
Widget _passwordConfirmField() {
return new TextFormField(
autocorrect: false,
obscureText: true,
decoration: InputDecoration(labelText: 'Retype Password'),
validator: (value) =>
value != _password ? "Passwords do not match!" : null,
}
final formKey = new GlobalKey<FormState>();
Widget _buildForm() {
return new Form(
autovalidate: true,
key: formKey,
child: new Column(children: <Widget>[
_passwordField(),
_passwordConfirmField(),
new RaisedButton(
child: Text('Sign Up'),
onPressed: () => submit()
)
]
}
void submit() {
final form = formKey.currentState;
if (form.validate()) {
form.save(); //this will cause the onSaved method to get called
}
}
Upvotes: 0
Reputation: 2034
This is my method, big thanks to Suhair. It is based on Suhair's but his didn't work for me...
(First Password)
TextFormField(
key: passKey,
obscureText: true,
decoration: InputDecoration(labelText: "Password"),
validator: (password) {
var result = password.length < 4
? "Password should have at least 4 characters"
: null;
return result;
},
),
(Second)
TextFormField(
obscureText: true,
decoration: InputDecoration(labelText: "Confirm Password"),
validator: (confirmation) {
if (confirmation != passKey.currentState.value) {
return 'Passwords do not match';
} else {
return null;
}
},
),
and you also need to declare you variable
var passKey = GlobalKey<FormFieldState>();
Upvotes: 0
Reputation: 389
I finally find the answer,its so simple actually.
new TextFormField(
controller: _registerPassController2,
decoration: new InputDecoration(labelText: 'Retype Password'),
obscureText: true,
validator: (value) {
if (value != _registerPassController.text) {
return 'Password is not matching';
}
},
),
Upvotes: 20
Reputation: 10929
Since you are using formfield it will be appropriate to use the key to access the value of other field. You can declare the global key like this
var passKey = GlobalKey<FormFieldState>();
Then pass it to the password field to retrieve its value during validation.
TextFormField(
key: passKey,
obscureText: true,
decoration: InputDecoration(
labelText: "Password"
),
validator: (password){
var result = password.length < 4 ? "Password should have at least 4 characters" : null;
return result;
},
);
Then you can use the password inside the confirmation validator like this
TextFormField(
obscureText: true,
decoration: InputDecoration(
labelText: "Confirm Password"
),
validator: (confirmation){
var password = passKey.currentState.value;
return equals(confirmation, password) ? null : "Confirm Password should match password";
},
);
Upvotes: 19
Reputation: 10789
The way I do this is to validate on a submit button and then show a message.
String _password;
Widget _passwordField() {
return new TextFormField(
autocorrect: false,
obscureText: true,
decoration: InputDecoration(labelText: 'Password'),
validator: (value) =>
value.isEmpty ? "Password can't be empty" : null,
onSaved: (val) => _password = val;
}
String _passwordConfirm;
Widget _passwordConfirmField() {
return new TextFormField(
autocorrect: false,
obscureText: true,
decoration: InputDecoration(labelText: 'Retype Password'),
validator: (value) =>
value.isEmpty ? "Password can't be empty" : null,
onSaved: (val) => _passwordConfirm = val;
}
final formKey = new GlobalKey<FormState>();
Widget _buildForm() {
return new Form(
autovalidate: true,
key: formKey,
child: new Column(children: <Widget>[
_passwordField(),
_passwordConfirmField(),
new RaisedButton(
child: Text('Sign Up'),
onPressed: () => submit()
)
]
}
void submit() {
final form = formKey.currentState;
if (form.validate()) {
form.save(); //this will cause the onSaved method to get called
//you will need to do some additional validation here like matching passwords
if(_password != _passwordConfirm) {
showDialog(....)
} else {
//complete
}
}
}
Note: This is a StatefulWidget
Upvotes: 0