ant-design / pro-components

🏆 Use Ant Design like a Pro!
https://pro-components.antdigital.dev
MIT License
4.24k stars 1.35k forks source link

EditableProTable通过ProFormCheckbox控制行,每新增一行页面焦点会直接定位到表单第一个输入框🧐[问题] #6968

Closed yangyan123 closed 1 year ago

yangyan123 commented 1 year ago

提问前先看看:

https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md

🧐 问题描述

ProForm嵌套EditableProTable,通过ProFormCheckbox控制EditableProTable的行,每新增一行页面焦点会直接定位到表单第一个输入框,且同页面的两个ProFormCheckbox会闪动

💻 示例代码

import React, { useEffect, useRef, useState } from 'react'; import { message } from 'antd'; import { history } from 'umi'; import { ProForm, ProFormText, ProFormSelect, PageContainer, ProCard, ProFormDependency, ProFormDateRangePicker, ProFormCheckbox, ProFormDatePicker, EditableProTable, FooterToolbar, } from '@ant-design/pro-components'; import type { ProFormInstance, ProColumns, EditableFormInstance } from '@ant-design/pro-components'; import { defaultStatusEnum, paperSpecsEnum } from '@/enumerate'; import { getExaminationDetailById, addExamination, updateExamination, } from '@/services/systemConfig'; import { areaList } from '@/services/api'; import { IntegerRegExp } from '@/utils/regExp';

const Index: React.FC = ({}) => { // 页面类型 const { pathname, query } = history.location; const pageType = pathname.split('/').slice(-1)[0]; const { id } = query as any; const props: API.ProFieldProps = { readonly: pageType === 'detail', colProps: { md: 12, xl: 12 }, labelAlign: 'left', labelCol: { span: 5 }, wrapperCol: { span: 17 }, }; const formRef = useRef(); const editorFormRef = useRef<EditableFormInstance>(); const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);

const onSubmit = async (values: API.ExaminationParams) => { await formRef.current?.validateFieldsReturnFormatValue?.(); console.log('校验表单并返回格式化后的所有数据:', values); let res; if (!id) { res = await addExamination({ ...values }); } else { res = await updateExamination({ ...values, id }); } // 请求成功 if (res) { message.success(id ? '编辑成功' : '添加成功'); history.push('/systemConfig/examManage'); } };

const columns: ProColumns[] = [ { title: '科目', dataIndex: 'subjectName', readonly: true, width: 60, }, { title: '考试时间', dataIndex: 'examTime', valueType: 'dateTime', fieldProps: { format: 'YYYY-MM-DD HH:mm', minuteStep: 30, }, formItemProps: { rules: [ { required: true, message: '此项是必填项', }, ], }, }, { title: '配送时间', dataIndex: 'deliveryTime', valueType: 'dateTime', // valueType: 'dateTimeRange', fieldProps: { format: 'YYYY-MM-DD HH:mm', minuteStep: 30, transform: (value: any) => { console.log(value); return {}; }, }, formItemProps: { rules: [ { required: true, message: '此项是必填项', }, ], }, }, { title: '拣货日', dataIndex: 'pickTime', valueType: 'date', formItemProps: { rules: [ { required: true, message: '此项是必填项', }, ], }, }, { title: '晚发拣货日', dataIndex: 'lateHairPickTime', valueType: 'date', formItemProps: { rules: [ { required: true, message: '此项是必填项', }, ], }, }, { title: '30份/袋/卡克重', dataIndex: 'cardThirtyWeight', width: 100, formItemProps: { rules: [ // { // required: true, // message: '此项是必填项', // }, { pattern: IntegerRegExp }, ], }, }, { title: '30份/袋/纸克重', dataIndex: 'paperThirtyWeight', width: 100, formItemProps: { rules: [ // { // required: true, // message: '此项是必填项', // }, { pattern: IntegerRegExp }, ], }, }, { title: '10份/袋/卡克重', dataIndex: 'cardTenWeight', width: 100, formItemProps: { rules: [ // { // required: true, // message: '此项是必填项', // }, { pattern: IntegerRegExp }, ], }, }, { title: '10份/袋/纸克重', dataIndex: 'paperTenWeight', width: 100, formItemProps: { rules: [ // { // required: true, // message: '此项是必填项', // }, { pattern: IntegerRegExp }, ], }, }, ];

const init = async () => { const res = await getExaminationDetailById({ id }); const subject: any = res?.subjectsList?.map((item) => item.subjectId); formRef.current?.setFieldsValue({ ...res, examinationTime: [res?.examinationStartTime, res?.examinationEndTime], reserveTime: [res?.reserveStartTime, res?.reserveEndTime], subject, cityCode: res.cityCode?.split(','), }); if (pageType === 'edit') { setEditableRowKeys([...subject]); } };

useEffect(() => { if (id) { init(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [id]);

return (

pageType !== 'detail' && ( {dom} ), }} > *不同地区科目不一致,算2次考试,需录入2次;考试名称可根据建议套用之前配置数据;
} /> { const [v1, v2] = values; return { examinationStartTime: v1, examinationEndTime: v2, }; }} rules={[{ required: true }]} /> value} transform={(values) => { const [v1, v2] = values; return { reserveEndTime: v1, reserveStartTime: v2, }; }} rules={[{ required: true }]} /> { const res = await areaList(); return res; }} rules={[{ required: true }]} /> { console.log(value); formRef.current?.setFieldValue( 'subjectsList', value?.map((_: any) => { return { subjectId: _, subjectName: subjectTypeEnum.enums[_], // cardTenWeight: '', // cardThirtyWeight: '', // deliveryTime: undefined, // examTime: undefined, // lateHairPickTime: undefined, // paperTenWeight: '', // paperThirtyWeight: '', // pickTime: undefined, }; }), ); setEditableRowKeys([...value]); }, }} rules={[{ required: false }]} /> {({ subject }) => { return ( subject?.length && ( editableFormRef={editorFormRef} columns={columns.map((item) => ({ ...item, align: 'center' }))} rowKey="subjectId" recordCreatorProps={false} editable={{ type: 'multiple', editableKeys, onChange: setEditableRowKeys, onValuesChange: (record, recordList) => { console.log(record, recordList); }, }} /> ) ); }}

); };

export default Index;

🚑 其他信息

yangyan123 commented 1 year ago

版本号image

chenshuai2144 commented 1 year ago

1.0 已经不维护了。

每新增一行页面焦点会直接定位到表单第一个输入框

当您新增一行页面时,焦点会直接定位到表单的第一个输入框。这个问题可能是由于组件在重新销毁过程中导致的。重新销毁组件意味着该组件被移除或销毁,并随后重新创建一个新的实例。在重新创建组件时,焦点自动定位到了表单的第一个输入框。

为了解决这个问题,您可以考虑以下步骤:

检查组件的生命周期,特别关注在新增一行页面时的处理过程。确保组件被正确销毁并重新创建。

检查相关的代码和事件处理程序,查看是否存在明确的逻辑导致焦点定位在表单的第一个输入框上。可能涉及事件绑定、聚焦方法或其他与焦点相关的代码。

检查组件的配置选项和属性,看是否存在可以控制焦点定位行为的设置。可能会有相关的选项可以进行调整或配置。

如果有可能,与其他开发人员或团队成员进行沟通和协作,了解是否有其他人遇到类似的问题,或者是否存在关于该组件的已知问题和解决方案。

通过仔细检查代码和组件的配置,您应该能够找到导致焦点定位在表单第一个输入框的原因,并采取相应的措施解决该问题。