import React, {Key, ReactElement} from "react"; import { INPUT_FIELD_SCHEMA, InputFieldOnBlurValidationType, InputFieldValidationFunObjectReturnType, InputFieldValidationFunType } from "../schemes"; import {AdditionPropsType} from "../types"; import { DictDeepActionKeyWayType, InputField, isCustomComponent, UseIsErrorFieldAddErrorFieldType, UseIsErrorFieldRemoveErrorFieldType } from "../dependencies"; import {INIT_FIELDS_NAME} from "../consts"; const getKeyWay = (schema: INPUT_FIELD_SCHEMA, additionProps: AdditionPropsType) => { if (schema.props.keyWay) { return schema.props.keyWay } else if (schema.props.name) { return [...additionProps.keyWay, schema.props.name] } else { // проверка на нахождение поле в array_fields const lastKeyWayItem = additionProps.keyWay[additionProps.keyWay.length - 1] if (typeof lastKeyWayItem === 'object') { return additionProps.keyWay } } return [] } const getValidateFunResponse = (value: any, fun: InputFieldValidationFunType): InputFieldValidationFunObjectReturnType => { const res = fun(value) if (typeof res === 'object') { return res } else if (typeof res === 'string') { if (res === '') return {status: true, message: ''} else return {status: false, message: res} } return {status: res, message: ''} } const getValidateFun = ( validationProps: InputFieldOnBlurValidationType, value: any, keyWay: DictDeepActionKeyWayType, schemeRequired: boolean, removeError: UseIsErrorFieldRemoveErrorFieldType, addError: UseIsErrorFieldAddErrorFieldType, ) => { return () => { let required = schemeRequired let fun: InputFieldValidationFunType = () => true if ('required' in validationProps && validationProps.required !== undefined) { required = validationProps.required } if ('fun' in validationProps && validationProps.fun !== undefined) { fun = validationProps.fun } const isEmptyValue = !value || (Array.isArray(value) && value.length === 0) || (typeof value === 'object' && Object.keys(value).length === 0) const funRes = getValidateFunResponse(value, fun) if (required ? !isEmptyValue && funRes.status : isEmptyValue || funRes.status) { removeError(keyWay) } else { addError(keyWay, funRes.message) } } } const getOnBlurValidation = (schema: INPUT_FIELD_SCHEMA, additionProps: AdditionPropsType, keyWay: DictDeepActionKeyWayType) => { const props = schema.props.onBlurValidation || schema.props.onChangeValidation if (props) { const value = additionProps.getValue(keyWay) return getValidateFun(props, value, keyWay, schema.props.required || false, additionProps.removeErrorField, additionProps.addErrorField) } return undefined } const getOnChangeValidation = (schema: INPUT_FIELD_SCHEMA, additionProps: AdditionPropsType, keyWay: DictDeepActionKeyWayType) => { let props = schema.props.onChangeValidation if (!props && schema.props.required === true) { props = {fun: (data) => true} } if (props) { const value = additionProps.getValue(keyWay) return getValidateFun(props, value, keyWay, schema.props.required || false, additionProps.removeOnChangeErrorField, additionProps.addOnChangeErrorField) } return undefined } const getOnChange = (schema: INPUT_FIELD_SCHEMA, keyWay: DictDeepActionKeyWayType, additionProps: AdditionPropsType) => { const serializeValue = schema.props.serializeValue let onChangeValidation = getOnChangeValidation(schema, additionProps, keyWay) return (data: any) => { onChangeValidation && onChangeValidation() serializeValue ? additionProps.setValue(serializeValue(data), keyWay) : additionProps.setValue(data, keyWay) } } const inputFieldComponent = (schema: INPUT_FIELD_SCHEMA, key: Key, additionProps: AdditionPropsType): ReactElement => { let onChange = undefined let value = undefined let isError = undefined let isErrorHintText = undefined let onBlur: ((e: any) => void) | undefined = undefined let keyWay: DictDeepActionKeyWayType = getKeyWay(schema, additionProps) if (keyWay) { const deserializeValue = schema.props.deserializeValue value = deserializeValue ? deserializeValue(additionProps.getValue(keyWay)) : additionProps.getValue(keyWay) onChange = getOnChange(schema, keyWay, additionProps) isError = additionProps.isErrorField(keyWay) isErrorHintText = additionProps.getErrorMessage(keyWay) onBlur = getOnBlurValidation(schema, additionProps, keyWay) // Поиск инициализированных полей const initFields: DictDeepActionKeyWayType = additionProps.getPrivateRefStoreValue(INIT_FIELDS_NAME) || [] if (!initFields.find(item => JSON.stringify(item) === JSON.stringify(keyWay))) { additionProps.addPrivateRefStoreValue([...initFields, keyWay], INIT_FIELDS_NAME) onChange(value !== undefined ? value : schema.props.defaultValue) } } const comp = schema.props.ownerInputComponent ? schema.props.ownerInputComponent : const props = { ...(additionProps?.inputFieldAdditionProps ? additionProps?.inputFieldAdditionProps : {}), value: value, onChange: onChange, isError: isError, isErrorHintText: isErrorHintText, onBlur: onBlur, key: key, ...(additionProps.inputFieldClassName ? {className: additionProps.inputFieldClassName} : {}), ...(isCustomComponent(comp) ? additionProps.customCompAdditionProps : {}), ...schema.props, } return React.cloneElement(comp, props) } export default inputFieldComponent