I am trying to determine which credit card is it? and render Image Widget accordingly. but somehow its not working, I don't know If I miss something or is my approach is wrong
Here's the code snippet
Its always render the last else part.
Input Suffix Icon part where I am rendering container based on number
VxState.watch(context, on: [HandleInputChanges]);
TextField(
maxLength: 16,
decoration: InputDecoration(
counter: const Offstage(),
suffixIcon: getCreditCardType(store.moniPay.cardNo) // Here I am rendering image,
hintText: "Input card number",
onChanged: (String? value) {
HandleInputChanges(value.toString(), 'cardno');
})
And here's the getCreditCardType method
Widget getCreditCardType(String creditCardNumber) {
if (RegExp(r"^4[0-9]{12}(?:[0-9]{3})?$").hasMatch(creditCardNumber)) {
// visa card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/visa.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^5[1-5][0-9]{14}$").hasMatch(creditCardNumber)) {
// master card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/master.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^3[47][0-9]{13}$").hasMatch(creditCardNumber)) {
// AExpress card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/american-express.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^3(?:0[0-5]|[68][0-9])[0-9]{11}$")
.hasMatch(creditCardNumber)) {
// diner card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/dinners-club.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^6(?:011|5[0-9]{2})[0-9]{12}$")
.hasMatch(creditCardNumber)) {
// discover card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/discover.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^(?:2131|1800|35\\d{3})\\d{11}$")
.hasMatch(creditCardNumber)) {
// JCB card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/jcb.png"),
fit: BoxFit.contain,
),
));
} else {
return const Icon(Icons.credit_card);
}
}
CodePudding user response:
I've tried the function you wrote down, and it appears that the regex pattern only recognize the full/complete format of the credit card. So it is a "validation regex" instead of "classification regex".
It doesn't recognize incomplete credit card numbers, so it will always return the last else part.
CodePudding user response:
For live validation, you need to make sure that each subsequent digit can only be entered if the current substring is valid.
You can use
^5(?:[1-5][0-9]{0,14})?$ # VISA
^5(?:[1-5][0-9]{0,14})?$ # MASTER CARD
^3(?:[47][0-9]{0,13})?$ # AEXPRESS CARD
^3(?:(?:0[0-5]?|[68][0-9]?)[0-9]{0,11})?$ # DINER CARD
^6(?:(?:01{0,2}|5[0-9]{0,2})[0-9]{0,12})?$ # DISCOVER CARD
The updated code will look like:
Widget getCreditCardType(String creditCardNumber) {
if (RegExp(r"^4[0-9]{0,15}$").hasMatch(creditCardNumber)) {
// visa card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/visa.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^5(?:[1-5][0-9]{0,14})?$").hasMatch(creditCardNumber)) {
// master card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/master.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^3(?:[47][0-9]{0,13})?$").hasMatch(creditCardNumber)) {
// AExpress card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/american-express.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^3(?:(?:0[0-5]?|[68][0-9]?)[0-9]{0,11})?$")
.hasMatch(creditCardNumber)) {
// diner card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/dinners-club.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^6(?:(?:01{0,2}|5[0-9]{0,2})[0-9]{0,12})?$")
.hasMatch(creditCardNumber)) {
// discover card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/discover.png"),
fit: BoxFit.contain,
),
));
} else if (RegExp(r"^(?:2(?:1(?:31?)?)?|1(?:80{0,2})?|3(?:5\d{0,3})?)\d{0,11}$")
.hasMatch(creditCardNumber)) {
// JCB card
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/jcb.png"),
fit: BoxFit.contain,
),
));
} else {
return const Icon(Icons.credit_card);
}
}