在reactjs中对Input Change格式化DD/MM/YYYY



我想添加"/"当用户在dd/mm/yyyy之后输入输入字段时,基本上用户正在尝试输入DOB,并希望在输入dd然后mm然后yyyy后自动添加'/'。此外,用户不能在dd &12毫米和年份需要检查DOB是否无效,如果是闰年(例如29/02/2024),并且不超过4位。

我尝试过,但当用户在输入2个字符'/'后输入文本时,输入不知何故丢失了。例如,当用户输入'22'然后输入'2'时,只显示'22/'而不是2。

我也尝试了闰年的逻辑,但不知怎的,在单个输入字段中管理整体状态不起作用。

这是我试过的。

import { useCallback, useState } from "react";
import moment from "moment";
import "./styles.css";
export default function App() {
const [dob, setDob] = useState("");
const [day, setDay] = useState("");
const [month, setMonth] = useState("");
const [year, setYear] = useState("");
const m = moment();
const [errors, setErrors] = useState();
const onchange = (e) => {
setDob(e.target.value);
checkAndAdd();
};
const handleDate = async () => {
let dayOfDob, monthOfDob, yearOfDob;
yearOfDob = dob.substring(6, 10);
if (dob.length === 2) {
dayOfDob = dob.substring(0, 2);
if (dayOfDob > 31) {
setErrors({ ...errors, dayO: "Day is greater" });
}
setDay(dayOfDob);
} else if (dob.length === 5) {
monthOfDob = dob.substring(3, 5);
if (monthOfDob > 12) {
setErrors({ ...errors, monthO: "Month is greater" });
}
setMonth(monthOfDob);
}
if (yearOfDob.length <= 4) {
let res = await isValidDate(dayOfDob, monthOfDob, yearOfDob);
console.log("validateDate", res);
}
};
const isValidDate = async (dayValue, monthValue, yearValue) => {
if (dayValue && monthValue && yearValue) {
let dayVal = dayValue.trim();
let monthVal = monthValue.trim();
const yearVal = yearValue.trim();
let leapYear = false;
if (dayVal != "" && monthVal != "" && yearVal != "") {
dayVal = dayVal <= 9 ? "0" + Number(dayVal) : dayVal;
monthVal = monthVal <= 9 ? "0" + Number(monthVal) : monthVal;
const d = new Date(yearVal + "-" + monthVal + "-" + dayVal);
if (yearVal % 4 !== 0 && monthVal == 2 && dayVal > 28) {
leapYear = true;
}
if (monthVal == 2 && dayVal > 29) {
leapYear = true;
}
if (yearVal.length === 4) {
if (!isNaN(d.getTime()) && !leapYear) {
setErrors("");
return d;
} else {
setErrors("DOB format is invalid");
return false;
}
}
} else {
return false;
}
}
};

const checkAndAdd = useCallback(() => {
if (dob.length === 2 || dob.length === 5) {
setDob(`${dob}/`);
handleDate();
}
}, [dob]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<input type="text" value={dob} onChange={onchange} />
</div>
);
}

请告诉我解释是否正确。也工作沙箱在这里

谢谢。

解决数字被"/"您可以简单地对onchange()checkAndAdd()方法执行如下操作:

const onchange = (e) => {
const value = e.target.value;
setDob(value);
checkAndAdd(value);
};
const checkAndAdd = useCallback((value) => {
if (dob.length === 2 || dob.length === 5) {
const last = value.charAt(value.length - 1);
setDob(`${dob}/${last}`);
handleDate();
}
}, [dob]);

所以我只需要为使用jQuery的非react遗留站点这样做,但这种方法很容易适应。下面是如何在jQuery中做到这一点(我现在没有时间重写它,但它主要是普通的JavaScript):

$("#dob").bind("keyup", function(event) {
var value = event.target.value.replace(/[^0-9/]/g, "").replace(///+/g, '/').trim();
if (priorValue !== null && priorValue.length < event.target.value.length && value.length > 1) {
const parts = value.split("/");
const month = parts[0];
const day = parts[1];
const year = parts[2];
if (value.length === 2 && value.indexOf("/") === -1) {
// "10" -> "10/"
event.target.value = value + "/";
} else if (value.length === 5 && parts.length !== 3) {
// "12/34" -> "12/34/"
event.target.value = value + "/";
} else if (value.length === 4 && value.charAt(1) === "/" && !value.charAt(3) === "/") {
// "1/15" -> "1/15/"
// but not "1/1/" -> "1/1//"
event.target.value = value + "/";
} else if (parts.length > 3 && value[value.length - 1] === "/") {
// "1/15/1950/" -> "1/15/1950"
event.target.value = value.slice(0, -1);
} else if (parts.length === 3 && year.length > 4) {
// "1/15/19501" -> "1/15/1950"
// avoiding slicing month and day w/ .slice(0, 2) for now...
event.target.value = month + "/" + day + "/" + year.slice(0, 4);
} else if (value !== event.target.value) {
event.target.value = value;
}
}
priorValue = event.target.value;
});

有很多问题,比如一些事件类型不能在Android上工作(尽管React中的合成事件可能会为你解决这个问题)。另外,我建议在inputmode="numeric"字段上设置HTML5输入提示为数字,这将默认移动为数字输入。

我检查长度,如果它比之前的长度短,以便处理退格/删除。

它不是完美的,但它工作得相当好。我认为可能有更好的方法,比如在桌面上默认日期输入,并做一个ios风格的日期微调器,但这是相当多的工作(或者你可以为它付费,实际上有商业解决方案似乎过多,但你去)。

最新更新