UNPKG

xph-form

Version:

This is a configurable form component that supports React

175 lines (174 loc) 6.48 kB
import { useRef, useState, useEffect } from "react"; import { isComponentFormItemProps, } from "../types"; import { isBoolean, isFunction, isNull, isEqual, isNil } from "lodash-es"; import { setComponentRuleType, createPlaceholderMessage } from "../helper"; export const useFormItemShow = (item, model, collapseRef) => { /** * useRef存储上一次的结果,如果开启了折叠状态,表单项由于联动数量发生了变化,需自动展开整个表单项 */ const lastIsShow = useRef(null); const lastIsIfShow = useRef(null); const { handleCollapseChangeFalse } = collapseRef.current || {}; const { show, ifShow } = item; let isShow = true; let isIfShow = true; if (isBoolean(show)) { isShow = show; } if (isBoolean(ifShow)) { isIfShow = ifShow; } if (isFunction(show)) { isShow = show({ model }); const lastIsShowTemp = isNil(lastIsShow.current) ? isShow : lastIsShow.current; useEffect(() => { if (!isEqual(isShow, lastIsShowTemp)) { handleCollapseChangeFalse && handleCollapseChangeFalse(); } }, [model]); } if (isFunction(ifShow)) { isIfShow = ifShow({ model }); const lastIsIfShowTemp = isNil(lastIsIfShow.current) ? isIfShow : lastIsIfShow.current; useEffect(() => { if (!isEqual(isIfShow, lastIsIfShowTemp)) { handleCollapseChangeFalse && handleCollapseChangeFalse(); } }, [model]); } lastIsShow.current = isShow; lastIsIfShow.current = isIfShow; return { isShow, isIfShow }; }; export const useFormItemCollapse = (formProps, index) => { const { collapsible, collapseNum } = formProps; const [itemCollapse, setItemCollapse] = useState(collapsible && index >= collapseNum ? true : false); return { itemCollapse, setItemCollapse, }; }; export const useFormItemRules = ({ item, model, isShow, componentProps, }) => { const { rules: defRules = [], label, required } = item; let rules = defRules; const isComponent = isComponentFormItemProps(item); const defaultMsg = isComponent ? createPlaceholderMessage(item.component) + label : ""; function validator(rule, value) { const msg = rule.message || defaultMsg; if (value === undefined || isNull(value)) { // 空值 return Promise.reject(msg); } else if (Array.isArray(value) && value.length === 0) { // 数组类型 return Promise.reject(msg); } else if (typeof value === "string" && value.trim() === "") { // 空字符串 return Promise.reject(msg); } else if (typeof value === "object" && Reflect.has(value, "checked") && Reflect.has(value, "halfChecked") && Array.isArray(value.checked) && Array.isArray(value.halfChecked) && value.checked.length === 0 && value.halfChecked.length === 0) { // 非关联选择的tree组件 return Promise.reject(msg); } return Promise.resolve(); } const getRequired = isFunction(required) ? required({ model }) : required; /* * 1、若设置了required属性,又没有其他的rules,就创建一个验证规则; * 2、若设置了required属性,又存在其他的rules,则只rules中不存在required属性时,才添加验证required的规则 * 也就是说rules中的required,优先级大于required */ if (getRequired) { if (!rules || rules.length === 0) { rules = [{ required: getRequired, validator }]; } else { const requiredIndex = rules.findIndex((rule) => Reflect.has(rule, "required")); if (requiredIndex === -1) { rules.push({ required: getRequired, validator }); } } } const requiredRuleIndex = rules.findIndex((rule) => Reflect.has(rule, "required") && !Reflect.has(rule, "validator")); if (requiredRuleIndex !== -1) { const rule = rules[requiredRuleIndex]; if (!isShow) { rule.required = false; } if (isComponent) { const { component } = item; if (!Reflect.has(rule, "type")) { rule.type = component === "InputNumber" ? "number" : "string"; } rule.message = rule.message || defaultMsg; if (component.includes("Input") || component.includes("Textarea")) { rule.whitespace = true; } const valueFormat = componentProps.valueFormat; setComponentRuleType(rule, component, valueFormat); } } // Maximum input length rule check const characterInx = rules.findIndex((val) => val.max); if (characterInx !== -1 && !rules[characterInx].validator) { rules[characterInx].message = rules[characterInx].message || `字符数应小于${rules[characterInx].max}位`; } return { rules, }; }; export const useFormItemDisabled = (formProps, item, model) => { /** item中的优先级比form中的高 */ const { disabled: formDisabled } = formProps; let _disabled = false; const { disabled } = item; if (isFunction(disabled)) { _disabled = disabled({ model }); } if (isBoolean(disabled)) { _disabled = disabled; } return { disabled: Reflect.has(item, "disabled") ? _disabled : formDisabled, }; }; export const useFormItemComponentProps = (item, model) => { const props = {}; const { componentProps = {} } = item; if (isFunction(componentProps)) { Object.assign(props, componentProps({ model })); } Object.assign(props, componentProps); return { componentProps: props, }; }; export const useFormItemColProps = (itemProps, formProps) => { const { colProps: itemColProps = {} } = itemProps; /** 默认占一行 */ const { colProps: formColProps = { span: 24 } } = formProps; const colProps = { ...formColProps, ...itemColProps }; return { colProps }; }; const useFormItem = ({ formProps }) => { const { items } = formProps; const formItems = items.map((item) => { return { ...item }; }); return { formItems }; }; export default useFormItem;