Skip to content

Commit 72a829d

Browse files
committed
update form
1 parent 9197aa7 commit 72a829d

25 files changed

+473
-402
lines changed

admin-pro-ui/src/components/form/common.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import {FormItemProps} from "@/components/form/types";
44

55
const formFieldInit = (props: FormItemProps,reloadOption?:()=>void) => {
66
const formContext = React.useContext(FormContext) || undefined;
7-
const formAction = formContext?.formAction;
8-
const validateContext = formContext?.validateContext;
7+
const formAction = formContext?.getFormAction();
8+
const validateContext = formContext?.getFormValidateContext();
99
const [random, setRandom] = React.useState(0);
1010

1111
useEffect(() => {
@@ -18,14 +18,14 @@ const formFieldInit = (props: FormItemProps,reloadOption?:()=>void) => {
1818
}
1919
}
2020
}
21-
const reloadContext = formContext?.reloadContext;
21+
const reloadContext = formContext?.getFormFieldReloadListenerContext();
2222
if (reloadContext) {
2323
reloadContext.addListener(props.name, () => {
2424
setRandom(Math.random);
2525
});
2626
}
2727

28-
const optionContext = formContext?.optionContext;
28+
const optionContext = formContext?.getFormFieldOptionListenerContext();
2929
if (optionContext) {
3030
optionContext.addListener(props.name, () => {
3131
if(reloadOption){
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
import {FormValidateContext} from "@/components/form/validate";
2+
import {FormFieldOptionListenerContext, FormFieldReloadListenerContext} from "@/components/form/listener";
3+
import {NamePath} from "rc-field-form/es/interface";
4+
import {FormField} from "@/components/form/types";
5+
import {Form as AntdForm, message} from "antd";
6+
import {FiledData, FormAction} from "@/components/form";
7+
import {FormInstance as AntdFormInstance} from "antd/es/form/hooks/useForm";
8+
import React from "react";
9+
10+
class FormInstance {
11+
private readonly validateContext: FormValidateContext;
12+
private readonly reloadContext: FormFieldReloadListenerContext;
13+
private readonly optionContext: FormFieldOptionListenerContext;
14+
private readonly formInstance: AntdFormInstance;
15+
private readonly formAction: FormAction;
16+
private fields: FormField[];
17+
18+
private fieldsUpdateDispatch: React.Dispatch<React.SetStateAction<FormField[]>> | undefined;
19+
20+
public setFieldsUpdateDispatch = (fieldsUpdateDispatch: React.Dispatch<React.SetStateAction<FormField[]>>) => {
21+
this.fieldsUpdateDispatch = fieldsUpdateDispatch;
22+
}
23+
24+
private updateFields = (resetFields: (prevState: FormField[]) => FormField[]) => {
25+
this.fields = resetFields(this.fields);
26+
if (this.fieldsUpdateDispatch) {
27+
this.fieldsUpdateDispatch(resetFields);
28+
}
29+
}
30+
31+
private namePathEqual = (name1: NamePath, name2: NamePath) => {
32+
if (Array.isArray(name1) && Array.isArray(name2)) {
33+
if (name1.length !== name2.length) {
34+
return false;
35+
}
36+
for (let i = 0; i < name1.length; i++) {
37+
if (name1[i] !== name2[i]) {
38+
return false;
39+
}
40+
}
41+
return true;
42+
}
43+
return name1 === name2;
44+
}
45+
46+
public submit = async () => {
47+
const res = await this.validateContext.validate(this.formAction);
48+
if (res) {
49+
this.formInstance.submit();
50+
}
51+
}
52+
53+
public reset = (values?: any) => {
54+
this.formInstance.resetFields();
55+
if (values) {
56+
this.formInstance.setFieldsValue(values);
57+
this.reloadContext.notifyAll();
58+
}
59+
}
60+
61+
public hidden = (name: NamePath) => {
62+
if (this.fields.length == 0) {
63+
message.error('表单项未加载').then();
64+
return;
65+
}
66+
this.updateFields(prevFields => prevFields.map((field) => {
67+
if (this.namePathEqual(field.props.name, name)) {
68+
return {
69+
...field,
70+
props: {
71+
...field.props,
72+
hidden: true,
73+
required: false
74+
}
75+
}
76+
}
77+
return field;
78+
}));
79+
this.validateContext.clear();
80+
}
81+
82+
public required = (name: NamePath, required: boolean) => {
83+
if (this.fields.length == 0) {
84+
message.error('表单项未加载').then();
85+
return;
86+
}
87+
this.updateFields(prevFields => prevFields.map((field) => {
88+
if (this.namePathEqual(field.props.name, name)) {
89+
return {
90+
...field,
91+
props: {
92+
...field.props,
93+
required: required
94+
}
95+
}
96+
}
97+
return field;
98+
}));
99+
this.validateContext.clear();
100+
}
101+
102+
public show = (name: NamePath) => {
103+
if (this.fields.length == 0) {
104+
message.error('表单项未加载').then();
105+
return;
106+
}
107+
this.updateFields(prevFields => prevFields.map((field) => {
108+
if (this.namePathEqual(field.props.name, name)) {
109+
return {
110+
...field,
111+
props: {
112+
...field.props,
113+
hidden: false
114+
}
115+
}
116+
}
117+
return field;
118+
}));
119+
this.validateContext.clear();
120+
}
121+
122+
public disable = (name: NamePath) => {
123+
if (this.fields.length == 0) {
124+
message.error('表单项未加载').then();
125+
return;
126+
}
127+
this.updateFields(prevFields => prevFields.map((field) => {
128+
if (this.namePathEqual(field.props.name, name)) {
129+
return {
130+
...field,
131+
props: {
132+
...field.props,
133+
disabled: true
134+
}
135+
}
136+
}
137+
return field;
138+
}));
139+
this.validateContext.clear();
140+
}
141+
142+
public disableAll = () => {
143+
if (this.fields.length == 0) {
144+
message.error('表单项未加载').then();
145+
return;
146+
}
147+
this.updateFields(prevFields => prevFields.map((field) => {
148+
return {
149+
...field,
150+
props: {
151+
...field.props,
152+
disabled: true
153+
}
154+
}
155+
}));
156+
this.validateContext.clear();
157+
}
158+
159+
public enable = (name: NamePath) => {
160+
if (this.fields.length == 0) {
161+
message.error('表单项未加载').then();
162+
return;
163+
}
164+
this.updateFields(prevFields => prevFields.map((field) => {
165+
if (this.namePathEqual(field.props.name, name)) {
166+
return {
167+
...field,
168+
props: {
169+
...field.props,
170+
disabled: false
171+
}
172+
}
173+
}
174+
return field;
175+
}));
176+
this.validateContext.clear();
177+
}
178+
179+
public enableAll = () => {
180+
if (this.fields.length == 0) {
181+
message.error('表单项未加载').then();
182+
return;
183+
}
184+
this.updateFields(prevFields => prevFields.map((field) => {
185+
return {
186+
...field,
187+
props: {
188+
...field.props,
189+
disabled: false
190+
}
191+
}
192+
}));
193+
this.validateContext.clear();
194+
}
195+
196+
public remove = (name: NamePath) => {
197+
if (this.fields.length == 0) {
198+
message.error('表单项未加载').then();
199+
return;
200+
}
201+
this.updateFields(prevFields => prevFields.filter((field) => !this.namePathEqual(field.props.name, name)));
202+
this.validateContext.clear();
203+
}
204+
205+
public create = (field: FormField, index?: number) => {
206+
if (this.fields.length == 0) {
207+
message.error('表单项未加载').then();
208+
return;
209+
}
210+
this.updateFields(prevFields => {
211+
const filteredFields = prevFields.filter((item) => item.props.name !== field.props.name);
212+
if (index === undefined || index < 0) {
213+
return [...filteredFields, field];
214+
} else {
215+
const newFields = [...filteredFields];
216+
newFields.splice(index, 0, field);
217+
return newFields;
218+
}
219+
});
220+
this.validateContext.clear();
221+
}
222+
223+
public getFieldValue = (name: NamePath) => {
224+
return this.formInstance.getFieldValue(name);
225+
}
226+
227+
public getFieldsValue = () => {
228+
return this.formInstance.getFieldsValue();
229+
}
230+
231+
public getFieldProps = (name: NamePath) => {
232+
for (const field of this.fields) {
233+
if (this.namePathEqual(field.props.name, name)) {
234+
return field;
235+
}
236+
}
237+
return null;
238+
}
239+
240+
public reloadOptions = (name: NamePath) => {
241+
this.optionContext.notify(name);
242+
}
243+
244+
public reloadAllOptions = () => {
245+
this.optionContext.notifyAll();
246+
}
247+
248+
public setFieldValue = (name: NamePath, value: any) => {
249+
this.formInstance.setFieldValue(name, value);
250+
this.reloadContext.notify(name);
251+
this.validateContext?.validateField(name, this.formAction);
252+
}
253+
254+
public setFieldsValue = (values: any) => {
255+
this.formInstance.setFieldsValue(values);
256+
this.reloadContext.notifyAll();
257+
}
258+
259+
public setFields = (fields: FiledData[]) => {
260+
this.formInstance.setFields(fields);
261+
}
262+
263+
public validate = () => {
264+
return this.validateContext.validate(this.formAction);
265+
}
266+
267+
public resetFields = (fields: FormField[]) => {
268+
this.fields = fields;
269+
}
270+
271+
constructor() {
272+
this.validateContext = new FormValidateContext();
273+
this.reloadContext = new FormFieldReloadListenerContext();
274+
this.optionContext = new FormFieldOptionListenerContext();
275+
this.formInstance = AntdForm.useForm()[0];
276+
this.fields = [];
277+
this.formAction = {
278+
submit: this.submit,
279+
reset: this.reset,
280+
hidden: this.hidden,
281+
show: this.show,
282+
remove: this.remove,
283+
create: this.create,
284+
disable: this.disable,
285+
disableAll: this.disableAll,
286+
enable: this.enable,
287+
enableAll: this.enableAll,
288+
required: this.required,
289+
getFieldValue: this.getFieldValue,
290+
getFieldsValue: this.getFieldsValue,
291+
getFieldProps: this.getFieldProps,
292+
reloadOptions: this.reloadOptions,
293+
reloadAllOptions: this.reloadAllOptions,
294+
setFieldValue: this.setFieldValue,
295+
setFieldsValue: this.setFieldsValue,
296+
setFields: this.setFields,
297+
validate: this.validate,
298+
}
299+
}
300+
301+
public getFormAction = () => {
302+
return this.formAction;
303+
}
304+
305+
public getFormValidateContext = () => {
306+
return this.validateContext;
307+
}
308+
309+
public getFormFieldReloadListenerContext = () => {
310+
return this.reloadContext;
311+
}
312+
313+
public getFormFieldOptionListenerContext = () => {
314+
return this.optionContext;
315+
}
316+
317+
public getFormControlInstance = (): AntdFormInstance => {
318+
return this.formInstance;
319+
}
320+
321+
}
322+
323+
export default FormInstance;

0 commit comments

Comments
 (0)