信用卡到期日输入框输入2位后自动添加斜杠的实现方法
信用卡到期日输入自动斜杠格式化实现方案
问题背景
现有信用卡信息录入组件需实现到期日输入交互:
- 用户输入时自动在月份、年份之间插入斜杠
- 连续输入4位数字(如
0614)时,自动格式化为06/14的标准MM/YY格式
原有代码仅实现了基础校验,未加入值格式化逻辑,无法满足自动加斜杠的需求,原有代码如下:
原有React逻辑代码
const [expDateValidationState, setExpDateValidationState] = useState({ error: false, helperText: '', }); const expDateOnChange = (event) => { if (expDateValidator(event.target.value)) { setExpDateValidationState({ error: false, helperText: '' }); setPaymentInfo({ ...paymentInfo, expDate: event.target.value === '' ? null : event.target.value, }); } else { setExpDateValidationState({ error: true, helperText: 'Please enter your expire date.', }); setPaymentInfo({ ...paymentInfo, expDate: null, }); } const handleExpDateChange = (event) => { expDateOnChange(event); handleInputChange(event); };
注:原有
expDateOnChange函数缺少闭合大括号,会直接报语法错误,后续修复时需要补上。
原有校验规则代码
export const expDateValidator = (expDate) => { const expDateRegex = /^(0[1-9]|1[0-2])\/?([0-9]{4}|[0-9]{2})$/; return expDateRegex.test(expDate); };
原有组件代码
<AS.TextField placeholder="MM/YY" inputProps={{ maxLength: 5 }} onChange={handleExpDateChange} error={expDateValidationState.error} helperText={expDateValidationState.helperText} name="expDate" value={paymentInfo.expDate} />
注:原有placeholder写的
aa/YY属于笔误,应为MM/YY。
实现步骤
1. 新增输入值格式化函数
核心逻辑是先过滤所有非数字字符,再根据长度自动插入斜杠,兼容连续输数字、手动删改等各种输入场景:
const formatExpDate = (inputVal) => { // 移除所有非数字字符,避免非法字符、重复斜杠问题 const digits = inputVal.replace(/\D/g, ''); if (digits.length <= 2) return digits; // 超过2位时自动插入斜杠,最多取4位数字(对应MM/YY共5位长度) return `${digits.slice(0, 2)}/${digits.slice(2, 4)}`; };
2. 修改输入变更逻辑,先格式化再校验存值
在原有逻辑前加入格式化步骤,同时优化校验触发时机,避免用户输入中途就弹出错误提示:
const [expDateValidationState, setExpDateValidationState] = useState({ error: false, helperText: '', }); const expDateOnChange = (event) => { const rawVal = event.target.value; // 先格式化输入值 const formattedVal = formatExpDate(rawVal); event.target.value = formattedVal; // 校验逻辑:输入过程中(长度不足5位)不触发错误提示,输满5位不合法才提示 const isFullValid = /^(0[1-9]|1[0-2])\/[0-9]{2}$/.test(formattedVal); if (formattedVal.length < 5 || isFullValid) { setExpDateValidationState({ error: false, helperText: '' }); setPaymentInfo(prev => ({ ...prev, expDate: formattedVal === '' ? null : formattedVal, })); } else { setExpDateValidationState({ error: true, helperText: 'Please enter your expire date.', }); setPaymentInfo(prev => ({ ...prev, expDate: null, })); } }; // 补上原有代码缺失的闭合大括号 const handleExpDateChange = (event) => { expDateOnChange(event); handleInputChange(event); };
3. (可选)优化光标体验
部分浏览器下修改input值会导致光标自动跳到末尾,可以加入光标位置修正逻辑,在格式化后把光标放回正确位置:
// 加在 event.target.value = formattedVal 之后 const cursorPos = event.target.selectionStart; window.requestAnimationFrame(() => { // 插入斜杠后光标位置自动后移1位,避免光标跑到斜杠前面 event.target.selectionStart = event.target.selectionEnd = cursorPos > 2 ? cursorPos + 1 : cursorPos; });
效果说明
- 输入
0→显示0,输入6→显示06,再输入1→自动变成06/1,再输入4→自动变成06/14 - 直接连续输入
0614→自动格式化为06/14 - 手动删除字符、输入斜杠等操作都会被自动规整,不会出现重复斜杠、非法字符等问题
内容的提问来源于stack exchange,提问作者onjr
相关产品推荐
相关产品推荐

