Skip to content

Commit 1f4d321

Browse files
authoredMar 16, 2022
faeat(Transfer): 添加Tree节点全选支持 (#678)
1 parent 7f8c2d9 commit 1f4d321

File tree

2 files changed

+92
-62
lines changed

2 files changed

+92
-62
lines changed
 

‎packages/react-transfer/README.md

+18-5
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,24 @@ import { Transfer } from 'uiw';
5353
function Demo() {
5454

5555
const options = [
56-
{ label: '武汉市', key: 1 },
57-
{ label: '汉南区1', key: 5 },
58-
{ label: '汉南区2', key: 6 },
59-
{ label: '汉南区3', key: 7 },
60-
]
56+
{
57+
label: '武汉市',
58+
key: 1,
59+
children: [
60+
{ label: '新洲区', key: 2, disabled: true },
61+
{ label: '武昌区', key: 3 },
62+
{
63+
label: '汉南区',
64+
key: 4,
65+
children: [
66+
{ label: '汉南区1', key: 5 },
67+
{ label: '汉南区2', key: 6 },
68+
{ label: '汉南区3', key: 7 },
69+
]
70+
},
71+
]
72+
}
73+
];
6174

6275
const [value,valueSet] = React.useState([{ label: '武汉市', key: 1 }, { label: '汉南区1', key: 5 }])
6376

‎packages/react-transfer/src/index.tsx

+74-57
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function Transfer(props: TransferProps) {
5252
const [selectedOptions, selectedOptionSet] = useState<Array<TreeData>>(options || []);
5353
const selectedOptionsShowCount = useRef<number>(0);
5454
const [selectOption, selectOptionSet] = useState<Map<string | number, string>>(new Map());
55+
const [leftSelectOption, leftSelectOptionSet] = useState<Map<string | number, string>>(new Map());
5556
const [leftSelectedKeys, leftSelectedKeySet] = useState<Array<string | number | undefined>>([]);
5657
const [rightSelectedKeys, rightSelectedKeySet] = useState<Array<string | number | undefined>>([]);
5758
const [rightOpions, rightOpionSet] = useState<Array<TreeData>>([]);
@@ -81,54 +82,16 @@ function Transfer(props: TransferProps) {
8182
child.hideNode = isHide && !find;
8283
} else {
8384
child.hideNode = isHide;
84-
if (!child.hideNode) {
85-
selectedOptionsShowCount.current++;
86-
}
85+
}
86+
if (!child.hideNode) {
87+
selectedOptionsShowCount.current++;
8788
}
8889
});
8990
};
9091
hiddenNodeForSeach(selectedOptions);
9192
selectedOptionSet([...selectedOptions]);
9293
};
9394

94-
const leftTreeOnSelected = (
95-
selectedKeys: Array<string | number | undefined>,
96-
_1: any,
97-
isChecked: boolean,
98-
evn: TreeData,
99-
) => {
100-
selectedAllActive(selectedKeys, 'left');
101-
102-
leftSelectedKeySet(selectedKeys);
103-
const selectOptionTemp = getOptionsRecursion([evn], selectOption, isChecked);
104-
selectOptionSet(selectOptionTemp);
105-
};
106-
107-
const rightTreeOnSelected = (selectedKeys: Array<string | number | undefined>) => {
108-
selectedAllActive(selectedKeys, 'right');
109-
110-
rightSelectedKeySet(selectedKeys);
111-
selectedKeys.forEach((key) => {
112-
selectOption.delete(key!);
113-
});
114-
selectOptionSet(selectOption);
115-
};
116-
117-
function selectedAllActive(selectedKeys: (string | number | undefined)[], key: 'left' | 'right') {
118-
let selectedAll = true;
119-
rightOpions.forEach((selected) => {
120-
const find = selectedKeys.find((key) => key === selected.key);
121-
selectedAll = selectedAll && !!find;
122-
});
123-
selectAllChecked[key] = selectedAll
124-
? CheckedStatus.AllChecked
125-
: selectedKeys.length
126-
? CheckedStatus.Indeterminate
127-
: CheckedStatus.UnChecked;
128-
129-
selectAllCheckedSet(selectAllChecked);
130-
}
131-
13295
const getOptionsRecursion = (childrens: TreeData[], selectOption: Map<string | number, string>, isAdd: boolean) => {
13396
const addOrDel = (key: string | number, label: string, isAdd: boolean) => {
13497
if (isAdd) {
@@ -155,12 +118,37 @@ function Transfer(props: TransferProps) {
155118
return selectOption;
156119
};
157120

158-
const transferClick = (transferType: string) => {
159-
selectAllChecked.right = CheckedStatus.UnChecked;
160-
selectAllCheckedSet(selectAllChecked);
121+
const leftTreeOnSelected = (
122+
selectedKeys: Array<string | number | undefined>,
123+
_1: any,
124+
isChecked: boolean,
125+
evn: TreeData,
126+
) => {
127+
leftSelectedKeySet(selectedKeys);
128+
const selectOptionTemp = getOptionsRecursion([evn], leftSelectOption, isChecked);
129+
leftSelectOptionSet(selectOptionTemp);
130+
};
131+
132+
const rightTreeOnSelected = (selectedKeys: Array<string | number | undefined>) => {
133+
rightSelectedKeySet(selectedKeys);
134+
};
161135

136+
const transferClick = (transferType: 'left' | 'right') => {
137+
let selectOptionTemp = selectOption;
138+
if (transferType === 'left') {
139+
leftSelectOption.forEach((value, key) => {
140+
selectOptionTemp.set(key, value);
141+
});
142+
} else {
143+
rightSelectedKeys.forEach((key) => {
144+
selectOption.delete(key!);
145+
});
146+
}
147+
148+
selectOptionSet(selectOptionTemp);
149+
// leftSelectOptionSet(selectOptionTemp);
162150
const option: Array<TransferOptionType> = [];
163-
selectOption.forEach((label, key) => option.push({ key, label }));
151+
selectOptionTemp.forEach((label, key) => option.push({ key, label }));
164152
props.onChange?.(transferType, option);
165153
};
166154

@@ -191,14 +179,41 @@ function Transfer(props: TransferProps) {
191179
props.onSearch?.('right', searchValue);
192180
};
193181

194-
const selectAllCheckedChange = (e: React.ChangeEvent<HTMLInputElement>) => {
182+
const selectAllLeftChange = (e: React.ChangeEvent<HTMLInputElement>) => {
183+
const isChecked = e.target.checked;
184+
185+
selectAllChecked.left = isChecked ? 1 : 0;
186+
if (isChecked) {
187+
const keys: Array<string | number> = [];
188+
const selectedOptionsRecursion = (selectedOptions: Array<TreeData>) => {
189+
selectedOptions.forEach((child) => {
190+
if (child.children?.length) {
191+
selectedOptionsRecursion(child.children);
192+
} else {
193+
if (!child.hideNode) {
194+
selectOption.set(child.key!, child.label as string);
195+
keys.push(child.key!);
196+
}
197+
}
198+
});
199+
};
200+
selectedOptionsRecursion(selectedOptions);
201+
leftSelectedKeySet(keys);
202+
} else {
203+
leftSelectedKeySet([]);
204+
}
205+
selectOptionSet(selectOption);
206+
selectAllCheckedSet(selectAllChecked);
207+
};
208+
209+
const selectAllRightChange = (e: React.ChangeEvent<HTMLInputElement>) => {
195210
const isChecked = e.target.checked;
196211

197212
selectAllChecked.right = isChecked ? 1 : 0;
198213
if (isChecked) {
199-
const keys = rightOpions.map((selected) => {
200-
selectOption.delete(selected.key!);
201-
return selected.key;
214+
const keys = rightOpions.map((child) => {
215+
selectOption.delete(child.key!);
216+
return child.key;
202217
});
203218
rightSelectedKeySet(keys);
204219
} else {
@@ -223,11 +238,13 @@ function Transfer(props: TransferProps) {
223238
bodyStyle={{ padding: 5 }}
224239
title={
225240
<div>
226-
{/* <Checkbox
227-
indeterminate={selectAllChecked.left === CheckedStatus.Indeterminate}
228-
checked={selectAllChecked.left === CheckedStatus.AllChecked}
229-
onChange={selectAllCheckedChange}
230-
/> */}
241+
{selectedAll && (
242+
<Checkbox
243+
indeterminate={leftSelectedKeys.length < selectedOptionsShowCount.current && !!leftSelectedKeys.length}
244+
checked={leftSelectedKeys.length >= selectedOptionsShowCount.current && !!leftSelectedKeys.length}
245+
onChange={selectAllLeftChange}
246+
/>
247+
)}
231248
<span style={{ marginLeft: 10 }}>
232249
{leftSelectedKeys.length}/{selectedOptionsShowCount.current}
233250
</span>
@@ -263,9 +280,9 @@ function Transfer(props: TransferProps) {
263280
<div>
264281
{selectedAll && (
265282
<Checkbox
266-
indeterminate={selectAllChecked.right === CheckedStatus.Indeterminate}
267-
checked={selectAllChecked.right === CheckedStatus.AllChecked}
268-
onChange={selectAllCheckedChange}
283+
indeterminate={rightSelectedKeys.length < rightOpions.length && !!rightSelectedKeys.length}
284+
checked={rightSelectedKeys.length === rightOpions.length && !!rightSelectedKeys.length}
285+
onChange={selectAllRightChange}
269286
/>
270287
)}
271288
<span style={{ marginLeft: 10 }}>

0 commit comments

Comments
 (0)
Please sign in to comment.