Card Details Form Validator
Medium · React, Controlled Components, Form Validation, Cross-Field Dependencies · Cohere · Hints: Re‑validate the card number and security code whenever the selected profile changes. Compare expiry against the props currentMonth and currentYear at the moment of validation; do not store past‑validity in state.
Create a controlled React component named CardForm. It renders inputs for cardholder name, a profile selector (A or B), card number, expiry date (MM/YY), and security code. The component receives three props: currentYear, currentMonth, and an onSubmit callback.
Validation rules depend on the selected profile. Profile A demands a card number of exactly 16 numeric digits and a security code of 3 digits. Profile B requires a 15‑digit number and a 4‑digit security code. Spaces that the user may type into the card number must be stripped before checking its length. The expiry date must represent the current month or a future month, relative to the currentMonth and currentYear props. No actual payment processing is required.
All inputs are controlled. Validation errors should appear inline and update as the user interacts. Because the number and security‑code rules depend on the selected profile, changing the profile must immediately re‑validate those two fields. When the user submits the form and every field is valid, call onSubmit with an object { cardholderName, profile, number, expiry, securityCode }. If any field is invalid, prevent submission and display the appropriate errors.
Example 1:
Input:
props = { currentYear: 2031, currentMonth: 5, onSubmit: handler }
User: name = "Maria Chen", profile = A,
number = "1234 5678 9012 3456",
expiry = "06/31", security = "123"
→ click submit
Output:
handler is called with {
cardholderName: "Maria Chen",
profile: "A",
number: "1234567890123456",
expiry: "06/31",
securityCode: "123"
}
Explanation: spaces are removed from the number; expiry June 2031 is not earlier than the given May 2031; 16 digits and 3‑digit code match Profile A.
Example 2:
Input:
props = { currentYear: 2026, currentMonth: 11, onSubmit: handler }
User: name = "Alex Lee", profile = B (initially),
number = "3782 822463 10005",
expiry = "11/26", security = "7890"
→ clicks submit
Output:
handler is called with {
cardholderName: "Alex Lee",
profile: "B",
number: "378282246310005",
expiry: "11/26",
securityCode: "7890"
}
Explanation: Expiry is exactly the current month (November 2026), which is valid. The stripped number has 15 digits and the security code 4 digits, satisfying Profile B.
Example 3 (profile change re‑validates):
Input:
props = { currentYear: 2025, currentMonth: 12, onSubmit: handler }
User: profile = A, number = "4111111111111111", security = "123",
then switches profile to B
Output:
Error messages for number (requires 15 digits) and security (requires 4 digits)
appear immediately. After correcting number to "5500000000000004"
and security to "5678", the errors clear.
Constraints:
onSubmit callback must not be invoked while any validation error is present.currentMonth/currentYear is considered valid.profile field is always "A" or "B"; the component does not need to infer the profile from the number.