Reputation: 99
I am working to build an app and I wanted to include password validation. Specifically, I want to have a user's password match the confirmed password they type in, then a circle will turn green when they match. I have gotten it to work for password length and special characters, but I am not able to get it to work for password confirmation matching. Could someone please provide some advice or insight on what I could attempt to do?
I have attached my entire code down below:
class SignUpScreen extends StatefulWidget {
const SignUpScreen({Key? key}) : super(key: key);
@override
_SignUpScreenState createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
TextEditingController _passwordTextController = TextEditingController();
bool showPassword = false;
bool _isPasswordEightLetters = false;
bool _OneNumberPassword = false;
bool _confirmPassword = false;
TextEditingController _emailTextController = TextEditingController();
TextEditingController _confirmPasswordController = TextEditingController();
OnPasswordChanged(String password) {
final numericRegex = RegExp(r'[0-9;]');
setState(() {
_isPasswordEightLetters = false;
if (password.length >= 8) {
_isPasswordEightLetters = true;
}
_OneNumberPassword = false;
if(numericRegex.hasMatch(password)) {
_OneNumberPassword = true;
}
_confirmPassword = false;
if (password == _confirmPasswordController.text) {
_confirmPassword = true;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: SafeArea(
child: ListView(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10,),
Row(
children: [
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
border: Border.all(color: Colors.grey),),
child: const Icon(
Icons.arrow_back_ios_rounded,
size: 15,
color: Color(0xff31708c),
),
),
),
const SizedBox(
width: 20,
),
Text("Create Account",
style: GoogleFonts.montserrat(color: const Color(0xff31708c),
fontWeight: FontWeight.w700,
fontSize: 28),
),
],
),
const SizedBox(
height: 20,
),
const Text("Create an account with one of the following options:",
style: TextStyle(
color: Color(0xff31708c),
fontSize: 15,
fontWeight: FontWeight.w500),
),
const SizedBox(
height: 30,
),
Row(
children: [
Container(
width: 165,
height: 50,
child: Padding(
padding: const EdgeInsets.all(10),
child: Image.asset('assets/images/Google_-G-_Logo.svg.png',
height: 35,
),
),
decoration: BoxDecoration(
color: Colors.blueGrey.withOpacity(0.08),
border: Border.all(color: const Color(0x6630728c)),
borderRadius: BorderRadius.circular(12)
),
),
const SizedBox(
width: 30,
),
Container(
width: 165,
height: 50,
child: Padding(
padding: const EdgeInsets.all(10),
child: Image.asset('assets/images/facebook-logo.png',
height: 35,
),
),
decoration: BoxDecoration(
color: Colors.blueGrey.withOpacity(0.08),
border: Border.all(color: const Color(0x6630728c)),
borderRadius: BorderRadius.circular(12)),
),
],
),
Row(children: <Widget>[
Expanded(
child: Container(
margin: const EdgeInsets.only(left: 15.0, right: 10.0),
child: const Divider(
color: Color(0xff31708c),
height: 60,
thickness: 1.5,
)),
),
const Text("or continue with",
style: TextStyle(
color: Color(0xff31708c),
fontSize: 15,
fontWeight: FontWeight.w500),),
Expanded(child: Container(
margin: const EdgeInsets.only(left: 10.0, right: 15.0),
child: const Divider(
color: Color(0xff31708c),
height: 60,
thickness: 1.5,
),
),
)
],
),
// const SizedBox(
// height: 10,
// ),
Text(
"Email Address",
style: GoogleFonts.montserrat(color: const Color(0xff31708c),
fontWeight: FontWeight.w700,
fontSize: 15),
),
const SizedBox(
height: 10,
),
Container(
child: TextFormField(
controller: _emailTextController,
style: const TextStyle(color: Colors.black),
keyboardType: TextInputType.emailAddress,
// inputFormatters: <TextInputFormatter>[
// FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))
// ],
decoration: InputDecoration(
hintText: "Enter Your Email Address",
hintStyle: const TextStyle(color: Color(0xff31708c),
fontSize: 15.5),
prefixIcon: const Icon(Icons.email_sharp,
color: Color(0xff31708c)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Color(0x6630728c))),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Color(0x6630728c),
),
),
),
autofillHints: const [AutofillHints.email]
),
decoration: BoxDecoration(color: Colors.blueGrey.withOpacity(0.08),
borderRadius: BorderRadius.circular(10)),
),
const SizedBox(
height: 20,
),
Text("Create a Password",
style: GoogleFonts.montserrat(
color: const Color(0xff31708c),
fontWeight: FontWeight.w700,
fontSize: 15),),
const SizedBox(
height: 10,
),
Container(
child: TextFormField
(onChanged: (password) => OnPasswordChanged(password),
controller: _passwordTextController,
obscureText: !showPassword,
style: const TextStyle(
color: Colors.black),
decoration: InputDecoration(
hintText: "Please Create a Password",
suffixIcon: InkWell(
onTap: () {
setState(() {
showPassword = !showPassword;
});
},
child: Icon(
showPassword
? Icons.visibility
: Icons.visibility_off,
color: const Color(0xff31708c)
),
),
hintStyle: const TextStyle(
color: Color(0xff31708c),
fontSize: 15.5),
prefixIcon: const Icon(Icons.password_sharp,
color: Color(0xff31708c),),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Color(0x6630728c))),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Color(0x6630728c))
)
),
),
decoration: BoxDecoration(color: Colors.blueGrey.withOpacity(0.08),
borderRadius: BorderRadius.circular(10)),
),
const SizedBox(
height: 20,
),
Text("Confirm Password",
style: GoogleFonts.montserrat(
color: const Color(0xff31708c),
fontWeight: FontWeight.w700,
fontSize: 15)),
const SizedBox(
height: 10,
),
Container(
child: TextFormField
(controller: _confirmPasswordController,
onChanged: (value) => _confirmPasswordController,
obscureText: !showPassword,
style: const TextStyle(
color: Colors.black),
decoration: InputDecoration(
hintText: "Confirm Your Password",
suffixIcon: InkWell(
onTap: () {
setState(() {
showPassword = !showPassword;
});
},
child: Icon(
showPassword
? Icons.visibility
: Icons.visibility_off,
color: const Color(0xff31708c)
),
),
hintStyle: const TextStyle(
color: Color(0xff31708c),
fontSize: 15.5),
prefixIcon: const Icon(Icons.password_sharp,
color: Color(0xff31708c)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Color(0x6630728c))),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Color(0x6630728c))
)
),
),
decoration: BoxDecoration(color: Colors.blueGrey.withOpacity(0.08),
borderRadius: BorderRadius.circular(10)),
),
const SizedBox(height: 18,),
Row(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: 20,
height: 20,
decoration: BoxDecoration(
color: _isPasswordEightLetters ? Colors.green : Colors.transparent,
border: _isPasswordEightLetters ? Border.all(color: Colors.transparent) :
Border.all(color: const Color(0x6630728c)),
borderRadius: BorderRadius.circular(50)
),
child: const Center(
child: Icon(Icons.check, color: Colors.white, size: 15,),
),
),
const SizedBox(width: 10,),
const Text("Contains at least 8 characters",
style: TextStyle(color: Color(0xff31708c),
fontWeight: FontWeight.bold),)
],
),
const SizedBox(height: 10,),
Row(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: 20,
height: 20,
decoration: BoxDecoration(
color: _OneNumberPassword ? Colors.green : Colors.transparent,
border: _OneNumberPassword ? Border.all(color: Colors.transparent) :
Border.all(color: const Color(0x6630728c)),
borderRadius: BorderRadius.circular(50)
),
child: const Center(
child: Icon(Icons.check, color: Colors.white, size: 15),
),
),
const SizedBox(width: 10,),
const Text("Contains at least 1 number",
style: TextStyle(color: Color(0xff31708c),
fontWeight: FontWeight.bold),)
],
),
const SizedBox(height: 10,),
Row(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: 20,
height: 20,
decoration: BoxDecoration(
color: _confirmPassword ? Colors.green : Colors.transparent,
border: Border.all(color: const Color(0x6630728c)),
borderRadius: BorderRadius.circular(50)
),
child: const Center(
child: Icon(Icons.check, color: Colors.white, size: 15),
),
),
const SizedBox(width: 10,),
const Text("Passwords match",
style: TextStyle(color: Color(0xff31708c),
fontWeight: FontWeight.bold),)
],
),
const SizedBox(
height: 25),
ButtonTheme(
minWidth: MediaQuery.of(context).size.width,
height: 55,
buttonColor: const Color(0xff31708c),
child: RaisedButton(
onPressed: () {
FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailTextController.text,
password: _passwordTextController.text).then((_) {
print('New Account Created');
Navigator.of(context).
pushReplacement(MaterialPageRoute(builder: (context) => AccountOnboarding())); //CHANGE TO ACCOUNT SETUP
}
).onError((error, stackTrace) {
print('Error');
});
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: const Text("Sign Up",
style: TextStyle(color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold),
),
),
),
const SizedBox(
height: 10,
),
Row(
children: [
const SizedBox(
width: 70,
),
const Text("Already have an account?",
style: TextStyle(color: Color(0xff31708c),
fontSize: 15),
),
InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) => const LoginScreen2()));
},
child: const Text(
" Login here",
style: TextStyle(color: Color(0xff31708c),
fontSize: 15,
fontWeight: FontWeight.bold),
),
)
],
)
],
),
)
],
),
),
);
}
}
Upvotes: 0
Views: 2552
Reputation: 624
replace
onChanged: (value) => _confirmPasswordController,
with
onChanged: (confirmPassword) => OnPasswordChanged(_passwordTextController.text),
Note:
here passing _passwordTextController.text because in this method you are using parameter as password and accessing confirmpassword via controller, and before you were wrongly updating confirm password controller with string
Upvotes: 1