#javascript #reactjs #validation #formik #yup
#javascript #reactjs #проверка #formik #да
Вопрос:
Я создал многоступенчатую форму в «react»: «^ 17.0.1», «yup»: «^ 0.29.3» и «formik»: «^ 2.2.3».
Я хочу проверить, что, когда пользователь вводит свой день рождения (dobD), он действителен на основе месяца рождения (dobM) и года рождения (doBy).
У меня есть 3 отдельных входа. dobM, dobD, doBy
Первая проверка на dobD работает (т.Е. Пользователь может ввести значение только от 1 до 31), однако она не проверяется правильно, если в месяце меньше 31 дня (например, июнь или сентябрь) ИЛИ, если месяц февраль (в котором всего 28 дней, за исключением високосных лет).
Я попытался использовать Yup.ref для ссылки на поля года и месяца внутри проверки поля дня, однако, если я введу для месяца 04, пользователь все равно может ввести 31, что неверно (поскольку в апреле (04) всего 30 дней).).
Есть идеи, как я могу это исправить? Спасибо!
Вот проверка в Yup, которую я сейчас использую:
// Step 3: Date of Birth
Yup.object().shape({
dobM: Yup.string()
.test(
'dobM',
'Invalid Month',
value => {
if (value < 1 || value > 12) {
return false;
}
return true;
}
)
.min(2, 'Invalid')
.max(2, 'Invalid')
.required('Required'),
dobY: Yup.string()
.test(
'dobY',
'Valid Year required',
value => {
const today = new Date();
const adultYear = today.getFullYear() - 17;
if (value < 1900 || value > adultYear) {
return false;
}
return true;
}
)
.min(4, 'Must be 4 digits')
.max(4, 'Must be 4 digits')
.required('Valid Year required'),
dobD: Yup.string()
.test(
'dobD',
'Invalid Day',
value => {
if (value < 1 || value > 31) {
return false;
}
// Check months with less than 31 days - DOESNT WORK
// 4. April
// 6. June
// 9. September
// 11. November
if ((Yup.ref('dobM') == 4 || Yup.ref('dobM') == 6 || Yup.ref('dobM') == 9 || Yup.ref('dobM') == 11) amp;amp; value == 31) {
return false;
}
// If February - DOESNT WORK
if (Yup.ref('dobM') == 2) {
const isLeapYear = Yup.ref('dobY') % 4 == 0 amp;amp; (Yup.ref('dobY') % 100 != 0 || Yup.ref('dobY') % 400 == 0);
if (day > 29 || (day == 29 amp;amp; !isLeapYear)) {
return false;
}
}
return true;
}
)
.min(2, 'Invalid')
.max(2, 'Invalid')
.required('Required'),
}),
Ответ №1:
Публикую свое решение в надежде, что это поможет кому-то еще.
Я неправильно использовал Yup.ref (Yup.ref(‘fieldname’) — это объект, а не отдельное значение).
** Чтобы иметь возможность доступа к другому полю в Yup, я преобразовал функцию со стрелкой в обычную функцию в своем тесте, а затем смог получить доступ к значениям полей с помощью
это.параметры.родительский.ИМЯ_ПОЛЯ
видно из этого примера:
function(day) {
const month = this.options.parent.dobM;
const year = this.options.parent.dobY;
// check whatever you want with the value of month and year
}
Полная проверка DOB:
// Step 3: Date of Birth
Yup.object().shape({
dobM: Yup.string()
.matches(/^(0[1-9]|1[012])$/, 'Invalid Month')
.test(
'dobM',
'Invalid Month',
value => {
if (value < 1 || value > 12) {
return false;
}
return true;
}
)
.min(2, 'Invalid')
.max(2, 'Invalid')
.required('Required'),
dobY: Yup.string()
.test(
'dobY',
'Valid Year required',
value => {
const today = new Date();
const adultYear = today.getFullYear() - 17;
if (value < 1900 || value > adultYear) {
return false;
}
return true;
}
)
.matches(/^[0-9] $/, 'Must be only digits')
.min(4, 'Must be 4 digits')
.max(4, 'Must be 4 digits')
.required('Valid Year required'),
dobD: Yup.string()
.test(
'dobD',
'Invalid Day',
function(day) {
const month = this.options.parent.dobM;
const year = this.options.parent.dobY;
// February
if (month == 2) {
const isLeapYear = year % 4 == 0 amp;amp; (year % 100 != 0 || year % 400 == 0);
if (day > 29 || (day == 29 amp;amp; !isLeapYear)) {
return false;
}
}
return true;
}
)
.test(
'dobD',
'Invalid Day',
function(day) {
const month = this.options.parent.dobM;
// Check months with less than 31 days
// 4. April
// 6. June
// 9. September
// 11. November
if ((month == 4 || month == 6 || month == 9 || month == 11) amp;amp; day == 31) {
return false;
}
return true;
}
)
.test(
'dobD',
'Invalid Day',
day => {
if (day < 1 || day > 31) {
return false;
}
return true;
}
)
.matches(/^[0-9] $/, 'Digits Only')
.min(2, 'Invalid Day')
.max(2, 'Invalid Day')
.required('Required'),
}),
Примечание: для удобства чтения я перенес каждую проверку на dobD в свой собственный Yup .test() , однако это не обязательно.