Skip to content

Commit 9f4700b

Browse files
authored
feat: add form.getFieldsValue filterFunc (closes #43) (#44)
1 parent d24e9d1 commit 9f4700b

File tree

3 files changed

+89
-15
lines changed

3 files changed

+89
-15
lines changed

src/interface.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ export interface ValidateErrorEntity {
8080
}
8181

8282
export interface FieldEntity {
83-
onStoreChange: (store: Store, namePathList: InternalNamePath[] | null, info: NotifyInfo) => void;
83+
onStoreChange: (
84+
store: Store,
85+
namePathList: InternalNamePath[] | null,
86+
info: NotifyInfo,
87+
) => void;
8488
isFieldTouched: () => boolean;
8589
isFieldValidating: () => boolean;
8690
validateRules: (options?: ValidateOptions) => Promise<string[]>;
@@ -154,7 +158,10 @@ export interface InternalHooks {
154158
export interface FormInstance {
155159
// Origin Form API
156160
getFieldValue: (name: NamePath) => StoreValue;
157-
getFieldsValue: (nameList?: NamePath[]) => Store;
161+
getFieldsValue: (
162+
nameList?: NamePath[],
163+
filterFunc?: (meta: Meta) => boolean,
164+
) => Store;
158165
getFieldError: (name: NamePath) => string[];
159166
getFieldsError: (nameList?: NamePath[]) => FieldError[];
160167
isFieldsTouched(nameList?: NamePath[], allFieldsTouched?: boolean): boolean;

src/useForm.ts

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
InternalFormInstance,
1818
ValidateErrorEntity,
1919
StoreValue,
20+
Meta,
2021
} from './interface';
2122
import { HOOK_MARK } from './FieldContext';
2223
import { allPromiseFinish } from './utils/asyncUtil';
@@ -161,14 +162,42 @@ export class FormStore {
161162
return cache;
162163
};
163164

164-
private getFieldsValue = (nameList?: NamePath[]) => {
165+
private getFieldEntitiesForNamePathList = (nameList?: NamePath[]) => {
166+
if (!nameList) {
167+
return this.getFieldEntities(true);
168+
}
169+
const cache = this.getFieldsMap(true);
170+
return nameList.map(name => {
171+
const namePath = getNamePath(name);
172+
return cache.get(namePath);
173+
});
174+
};
175+
176+
private getFieldsValue = (
177+
nameList?: NamePath[],
178+
filterFunc?: (meta: Meta) => boolean,
179+
) => {
165180
this.warningUnhooked();
166181

167-
if (!nameList) {
182+
if (!nameList && !filterFunc) {
168183
return this.store;
169184
}
185+
if (!filterFunc) {
186+
return cloneByNamePathList(this.store, nameList.map(getNamePath));
187+
}
170188

171-
return cloneByNamePathList(this.store, nameList.map(getNamePath));
189+
const fieldEntities = this.getFieldEntitiesForNamePathList(nameList);
190+
191+
const filteredNameList: NamePath[] = [];
192+
fieldEntities.forEach((field: FieldEntity) => {
193+
const namePath = field.getNamePath();
194+
const meta = field.getMeta();
195+
if (filterFunc(meta)) {
196+
filteredNameList.push(namePath);
197+
}
198+
});
199+
200+
return cloneByNamePathList(this.store, filteredNameList.map(getNamePath));
172201
};
173202

174203
private getFieldValue = (name: NamePath) => {
@@ -181,16 +210,7 @@ export class FormStore {
181210
private getFieldsError = (nameList?: NamePath[]) => {
182211
this.warningUnhooked();
183212

184-
let fieldEntities = this.getFieldEntities(true);
185-
186-
if (nameList) {
187-
const cache = this.getFieldsMap(true);
188-
189-
fieldEntities = nameList.map(name => {
190-
const namePath = getNamePath(name);
191-
return cache.get(namePath);
192-
});
193-
}
213+
const fieldEntities = this.getFieldEntitiesForNamePathList(nameList);
194214

195215
return fieldEntities.map((entity, index) => {
196216
if (entity) {

tests/index.test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,4 +664,51 @@ describe('Form.Basic', () => {
664664
);
665665
errorSpy.mockRestore();
666666
});
667+
668+
it('filtering fields by meta', async () => {
669+
let form;
670+
671+
const wrapper = mount(
672+
<div>
673+
<Form
674+
ref={instance => {
675+
form = instance;
676+
}}
677+
>
678+
<InfoField name="username" />
679+
<InfoField name="password" />
680+
<Field>{() => null}</Field>
681+
</Form>
682+
</div>,
683+
);
684+
685+
expect(
686+
form.getFieldsValue(null, meta => {
687+
expect(Object.keys(meta)).toEqual([
688+
'touched',
689+
'validating',
690+
'errors',
691+
'name',
692+
]);
693+
return false;
694+
}),
695+
).toEqual({});
696+
697+
expect(form.getFieldsValue(null, () => true)).toEqual(
698+
form.getFieldsValue(),
699+
);
700+
expect(form.getFieldsValue(null, meta => meta.touched)).toEqual({});
701+
702+
await changeValue(getField(wrapper, 0), 'Bamboo');
703+
expect(form.getFieldsValue(null, () => true)).toEqual(
704+
form.getFieldsValue(),
705+
);
706+
expect(form.getFieldsValue(null, meta => meta.touched)).toEqual({
707+
username: 'Bamboo',
708+
});
709+
expect(form.getFieldsValue(['username'], meta => meta.touched)).toEqual({
710+
username: 'Bamboo',
711+
});
712+
expect(form.getFieldsValue(['password'], meta => meta.touched)).toEqual({});
713+
});
667714
});

0 commit comments

Comments
 (0)