From 9a81b1b8eef2e0c09bbd3345d3a0f5fd680c4e86 Mon Sep 17 00:00:00 2001 From: lyf-coder <58352715+lyf-coder@users.noreply.github.com> Date: Mon, 31 Oct 2022 11:12:19 +0800 Subject: [PATCH] fix(client/formula): set cursor focus on input (#959) * fix(client/formula): set cursor focus on input * fix(client/formula): when formula field name has contains the other one will case FormulaError refactor partial implementation --- .../antd/formula-input/FormulaInput.tsx | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/packages/core/client/src/schema-component/antd/formula-input/FormulaInput.tsx b/packages/core/client/src/schema-component/antd/formula-input/FormulaInput.tsx index b037c2e4fd..94c38f649f 100644 --- a/packages/core/client/src/schema-component/antd/formula-input/FormulaInput.tsx +++ b/packages/core/client/src/schema-component/antd/formula-input/FormulaInput.tsx @@ -1,7 +1,7 @@ import { Field, onFormSubmitValidateStart } from '@formily/core'; -import { connect, mapProps, mapReadPretty, useField, useFieldSchema, useFormEffects } from '@formily/react'; -import { Button, Input, Popover, Tag, Menu, Dropdown } from 'antd'; -import React, { useContext, useEffect, useRef, useState } from 'react'; +import { connect, mapProps, useField, useFormEffects } from '@formily/react'; +import { Menu, Dropdown } from 'antd'; +import React, { useEffect, useRef, useState } from 'react'; import ContentEditable from 'react-contenteditable'; import { useTranslation } from 'react-i18next'; import * as math from 'mathjs'; @@ -14,62 +14,65 @@ const AntdFormulaInput = (props) => { const inputRef = useRef(); const [dropdownVisible, setDropdownVisible] = useState(false); - const [formula, setFormula] = useState(null); const [html, setHtml] = useState(null); const numColumns = new Map(); const scope = {}; - fields.filter(field => supports.includes(field.interface)).forEach(field => { - numColumns.set(field.name, field.uiSchema.title); - scope[field.name] = 1; - }) + fields + .filter((field) => supports.includes(field.interface)) + .forEach((field) => { + numColumns.set(field.name, field.uiSchema.title); + scope[field.name] = 1; + }); const keys = Array.from(numColumns.keys()); - let initHtml; - if (value) { - initHtml = value; - numColumns.forEach((value, key) => { - initHtml = initHtml.replaceAll(key, `${value}`) - }) - } - useEffect(() => { - if (onChange && formula) { - let v = formula || ''; + if (value) { + let newHtml = value; numColumns.forEach((value, key) => { - v = v.replaceAll(value, key); - }) - if (v != value) { - onChange(v); - } + newHtml = newHtml.replaceAll( + key, + ``, + ); + }); + newHtml = `${newHtml}`; // set extra span for cursor focus on last position + setHtml(newHtml); + } else { + setHtml(''); } - }, [formula]) + }, [value]); const menu = ( - { - const replaceFormula = formula.replace('@', numColumns.get(args.key)); - const replaceHtml = html.replace('@', `${numColumns.get(args.key)}`); - setFormula(replaceFormula); - setHtml(replaceHtml); - setDropdownVisible(false); - }}> - { - keys.map(key => ({numColumns.get(key)})) - } + { + const replaceFormula = field.value.replace('@', args.key); + if (onChange && replaceFormula != field.value) { + onChange(replaceFormula); + } + setDropdownVisible(false); + (inputRef.current as any).focus(); + }} + > + {keys.map((key) => ( + {numColumns.get(key)} + ))} ); const handleChange = (e) => { - const current = inputRef.current as any; - setFormula(e.currentTarget.textContent); - setHtml(current.innerHTML); - if (e.currentTarget.textContent == '' && onChange) { - onChange(null); + if (onChange) { + if (e.currentTarget.textContent == '') { + onChange(null); + } else { + onChange(e.currentTarget.textContent); + } } - } + }; const handleKeyDown = (e) => { - const {key} = e; + const { key } = e; switch (key) { case 'Enter': e.preventDefault(); @@ -82,22 +85,23 @@ const AntdFormulaInput = (props) => { setDropdownVisible(false); break; } - } + }; useFormEffects(() => { onFormSubmitValidateStart(() => { try { math.evaluate(field.value, scope); field.feedbacks = []; - } catch { + } catch (e) { + console.error(field.value, scope, (e as Error).message); field.setFeedback({ type: 'error', code: 'FormulaError', messages: [t('Formula error.')], }); } - }) - }) + }); + }); return ( @@ -106,16 +110,12 @@ const AntdFormulaInput = (props) => { className="ant-input" onChange={handleChange} onKeyDown={handleKeyDown} - html={html || initHtml || ''} + html={html || ''} /> - ) -} + ); +}; -export const FormulaInput = connect( - AntdFormulaInput, - mapProps({ - }), -); +export const FormulaInput = connect(AntdFormulaInput, mapProps({})); -export default FormulaInput; \ No newline at end of file +export default FormulaInput;