Валидация форм React, часть 3. Катомные методы в Yup, валидация данных юридических лиц
VIDEO
Материалы к видео
Валидация данных юридического лица — здесь набор методов для валидации ИНН, КПП, ОГРН(ИП), ОКПО… в реализации для typescript.
Видео 1 , — простая валидация формы регистрации с подтверждение пароля.
Видео 2 — валидация файлов, изменения схемы валидации в зависимости от данных полей формы.
Генератор тестовых данных юр. лица
Декларирование методов Yup в typescript
Нужно запомнить, что в typescipt первым аргументом метода будет this. Тип у this будет такой же как у ассоциированой с ним схемы.
// В данном методе this - это StringShema
function checkPayment(this: yup.StringSchema, ref: any, msg: string) {
return this.test({
name: 'checkPaymentMethod',
exclusive: false,
message: msg || 'accountNumber',
params: { reference: ref.path},
test: function(value: string){
return checkPaymetAccount(value, this.resolve(ref))
}
})
}
Добавление метода будет принимать тип схемы нашего нового метода:
yup.addMethod<yup.StringSchema>(yup.string, 'checkPaymentMethod', checkPayment);
А перед всем этим мы должны задекларировать модуль, добавив типы методов соответствующих интерфейсов:
declare module "yup" {
interface StringSchema {
checkPaymentMethod(ref: Ref): StringSchema;
checkCorrespondentMethod(ref: Ref): StringSchema;
},
interface NumberSchema {
...
},
......
}
Код в видео
App.js
import React from 'react';
import { Formik } from 'formik'
import yup, { checkBIK, isINNLegalEntity } from './validation'
import './App.scss'
function App() {
const getError = (touched, error) => {
return touched && error && <p key={error} className={'error'}>{error}</p>
}
const validationsSchema = yup.object().shape({
bik: yup.string().test('BIK', 'БИК не валидный', checkBIK),
accountNumber: yup.string().checkPaymentMethod(yup.ref('bik'), 'Сообщение'),
inn: yup.string().test('INN', 'ИНН не валидный', isINNLegalEntity)
})
return (
<div>
<Formik
initialValues={{
bik: '',
accountNumber: '',
inn: ''
}}
validateOnBlur
onSubmit={(values) => { console.log(values) }}
validationSchema={validationsSchema}
>
{({ values, errors, touched, handleChange, handleBlur, isValid, handleSubmit, dirty }) => (
<div className={from
}>
<p>
<label htmlFor={bik
}>БИК</label><br />
<input
className={'input'}
type={text
}
name={bik
}
onChange={handleChange}
onBlur={handleBlur}
value={values.bik}
/>
</p>
{getError(touched.bik, errors.bik)}
<p>
<label htmlFor={accountNumber
}>Р/C</label><br />
<input
className={'input'}
type={text
}
name={accountNumber
}
onChange={handleChange}
onBlur={handleBlur}
value={values.accountNumber}
/>
</p>
{getError(touched.accountNumber, errors.accountNumber)}
<p>
<label htmlFor={inn
}>ИНН</label><br />
<input
className={'input'}
type={text
}
name={inn
}
onChange={handleChange}
onBlur={handleBlur}
value={values.inn}
/>
</p>
{getError(touched.inn, errors.inn)}
<button
disabled={!isValid || !dirty}
onClick={handleSubmit}
type={submit
}
>Отправить</button>
</div>
)}
</Formik>
</div>
);
}
export default App;
// Р / с 40702810038050103285
// К / с 30101810400000000225
// БИК 044525225
validation.js
import * as yup from 'yup'
export const checkBIK = (value) => {
if (!/^\d{9}$/.test(value)) return false
const thirdPart = value.slice(-3);
if (+thirdPart === 0 || +thirdPart === 1 || +thirdPart === 2) return true
return +thirdPart >= 50 && +thirdPart < 1000
}
export const checkPaymetAccount = (value, bik) => {
const valueToString = value ? value.toString() : '';
if (checkBIK(bik)) {
if (!/[^0-9]/.test(valueToString) && valueToString.length === 20) {
const bikRs = bik.toString().slice(-3) + valueToString;
let checkSum = 0;
const coefficients = [7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1];
for (var i in coefficients) {
checkSum += coefficients[i] * (Number(bikRs[i]) % 10);
}
return checkSum % 10 === 0;
}
}
return false;
};
export const isINNLegalEntity = (value) => {
const valueToString = value ? value.toString() : ''
const getN = (index) => (parseInt(valueToString[index]))
if (valueToString.length === 10) {
const dgt10 = ((
2 * getN(0) + 4 * getN(1) + 10 * getN(2) +
3 * getN(3) + 5 * getN(4) + 9 * getN(5) +
4 * getN(6) + 6 * getN(7) + 8 * getN(8)
) % 11) % 10
return (getN(9) === dgt10)
}
return false
}
function checkPayment(ref, msg) {
return this.test({
name: 'checkPaymentMethod',
exclusive: false,
message: msg || 'accountNumber not valid', // Сообщение об ошибке
params: { reference: ref ? ref.path : undefined },
test: function (value) {
return checkPaymetAccount(value, this.resolve(ref)) // Функция валидации
}
})
}
yup.addMethod(yup.string, 'checkPaymentMethod', checkPayment)
export default yup
Поддержи Xakplant
Я давно хочу развить видеоверсию, но пока этого не получается из-за нехватки ресурсов. Сейчас я собираю деньги на новый компьютер и микрофон. Поддержи xaklant и ты увидишь полезные видео быстрее.
Поддержать
Навигация по записям