Skip to content

Commit 36ce341

Browse files
committed
add option custom option
1 parent 516ed27 commit 36ce341

File tree

7 files changed

+222
-69
lines changed

7 files changed

+222
-69
lines changed

mobile-ui/src/components/form/form.scss

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
display: flex;
1111
justify-content: center;
1212
align-items: center;
13-
flex-wrap: wrap; /* 允许子元素换行 */
14-
text-align: center; /* 水平居中 */
13+
flex-wrap: wrap; /* 允许子元素换行 */
14+
text-align: center; /* 水平居中 */
1515
word-wrap: break-word; /* 超出容器时换行 */
1616
border: 0.5px solid $body-background-color;
1717
position: relative;
1818

19-
.delete-icon{
19+
.delete-icon {
2020
margin-top: -5px;
2121
margin-right: -5px;
2222
position: absolute;
@@ -26,7 +26,7 @@
2626
height: 15px;
2727
}
2828

29-
a{
29+
a {
3030
width: 100%;
3131
font-size: 12px;
3232
}
@@ -63,6 +63,25 @@
6363
display: flex;
6464
justify-content: space-between;
6565
}
66+
67+
68+
.select-popup-content-custom-form {
69+
70+
71+
.select-popup-content-custom-footer {
72+
display: flex;
73+
justify-content: space-between;
74+
align-items: center;
75+
margin: 30px;
76+
77+
button{
78+
width: 300px;
79+
margin: 10px;
80+
}
81+
}
82+
83+
}
84+
6685
}
6786

6887
.select-popup-header {
@@ -107,6 +126,18 @@
107126
.select-popup-search {
108127
height: 30px;
109128
padding: 5px;
129+
display: flex;
130+
align-items: center;
131+
132+
.select-popup-search-bar {
133+
flex: 9;
134+
height: 30px;
135+
}
136+
137+
.select-popup-search-button {
138+
flex: 1;
139+
height: 20px;
140+
}
110141
}
111142

112143
}

mobile-ui/src/components/form/select.tsx

Lines changed: 109 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import React, {useEffect} from "react";
22
import {FormItemProps, FormOption} from "@/components/form/types";
3-
import {CheckList, Form, Popup, SearchBar} from "antd-mobile";
4-
import {RightOutline} from "antd-mobile-icons";
3+
import {Button, CheckList, Form, Popup, SearchBar} from "antd-mobile";
4+
import {RightOutline, SetOutline} from "antd-mobile-icons";
55
import formFieldInit from "@/components/form/common";
6+
import {FormAction} from "@/components/form/index";
67
import "./form.scss";
78

89

@@ -14,7 +15,6 @@ const valueToForm = (value: string) => {
1415
}
1516

1617
const formToValue = (value: string[]) => {
17-
console.log('select', value);
1818
if (value && value.length > 0) {
1919
return value.join(",")
2020
}
@@ -34,6 +34,8 @@ const FormSelect: React.FC<FormItemProps> = (props) => {
3434

3535
const [selected, setSelected] = React.useState<string[]>(currentValue);
3636

37+
const [settingOptionVisible, setSettingOptionVisible] = React.useState(false);
38+
3739
// 当前页面展示的选项的数据,会随着树级目录进入子数据,从而更新数据
3840
const [options, setOptions] = React.useState(props.options);
3941

@@ -150,6 +152,23 @@ const FormSelect: React.FC<FormItemProps> = (props) => {
150152
}
151153
}, [visible]);
152154

155+
const selectOptionFormEditAction = React.useRef<FormAction>(null);
156+
157+
158+
const handlerOptionFormFinish = ()=>{
159+
if (props.onSelectOptionFormFinish && selectOptionFormEditAction.current && formAction) {
160+
props.onSelectOptionFormFinish(
161+
formAction,
162+
selectOptionFormEditAction.current,
163+
reloadOptions,
164+
() => {
165+
setSettingOptionVisible(false);
166+
setVisible(false);
167+
}
168+
);
169+
}
170+
}
171+
153172
return (
154173
<Form.Item
155174
name={props.name}
@@ -192,21 +211,37 @@ const FormSelect: React.FC<FormItemProps> = (props) => {
192211
>取消</a>
193212
<a
194213
onClick={() => {
195-
formAction?.setFieldValue(props.name, formToValue(selected));
196-
props.onChange && props.onChange(selected, formAction);
197-
setVisible(false);
214+
if(props.selectOptionFormEditable){
215+
handlerOptionFormFinish();
216+
}else {
217+
formAction?.setFieldValue(props.name, formToValue(selected));
218+
props.onChange && props.onChange(selected, formAction);
219+
setVisible(false);
220+
}
198221
}}
199222
>确定</a>
200223
</div>
201-
<div className={"select-popup-search"}>
202-
<SearchBar
203-
placeholder='输入查询选项'
204-
value={searchText}
205-
onChange={v => {
206-
setSearchText(v);
207-
}}
208-
/>
209-
</div>
224+
{!settingOptionVisible && (
225+
<div className={"select-popup-search"}>
226+
<SearchBar
227+
className={"select-popup-search-bar"}
228+
placeholder='输入查询选项'
229+
value={searchText}
230+
onChange={v => {
231+
setSearchText(v);
232+
}}
233+
/>
234+
{props.selectOptionFormEditable && (
235+
<SetOutline
236+
className={"select-popup-search-button"}
237+
onClick={() => {
238+
setSettingOptionVisible(!settingOptionVisible);
239+
}}
240+
/>
241+
)}
242+
</div>
243+
)}
244+
210245
{paths.length > 0 && (
211246
<div className={"select-popup-navbar"}>
212247
{paths.map((item, index) => {
@@ -227,41 +262,67 @@ const FormSelect: React.FC<FormItemProps> = (props) => {
227262
)}
228263

229264
<div className={"select-popup-content"}>
230-
<CheckList
231-
className={"select-popup-content-list"}
232-
value={selected}
233-
onChange={(value) => {
234-
const currentValue = value as string[];
235-
setSelected(currentValue);
236-
// 单选时,选中即关闭弹框
237-
if (!props.selectMultiple) {
238-
formAction?.setFieldValue(props.name, formToValue(currentValue));
239-
props.onChange && props.onChange(formToValue(currentValue), formAction);
240265

241-
setVisible(false);
242-
}
243-
}}
244-
multiple={props.selectMultiple}
245-
>
246-
{options
247-
&& options
248-
.filter(item => {
249-
if (searchText) {
250-
if (item.value.toUpperCase().includes(searchText.toUpperCase())) {
251-
return true;
252-
}
253-
if (item.label.toUpperCase().includes(searchText.toUpperCase())) {
254-
return true;
266+
{settingOptionVisible && (
267+
<div className={"select-popup-content-custom-form"}>
268+
{props.selectOptionFormEditView && (
269+
<props.selectOptionFormEditView formAction={selectOptionFormEditAction}/>
270+
)}
271+
<div className={"select-popup-content-custom-footer"}>
272+
<Button
273+
size={'middle'}
274+
color={'primary'}
275+
onClick={() => {
276+
handlerOptionFormFinish();
277+
}}
278+
>添加选项</Button>
279+
<Button
280+
size={'middle'}
281+
onClick={() => {
282+
setSettingOptionVisible(false);
283+
}}>取消添加</Button>
284+
</div>
285+
286+
</div>
287+
)}
288+
289+
{!settingOptionVisible && (
290+
<CheckList
291+
className={"select-popup-content-list"}
292+
value={selected}
293+
onChange={(value) => {
294+
const currentValue = value as string[];
295+
setSelected(currentValue);
296+
// 单选时,选中即关闭弹框
297+
if (!props.selectMultiple) {
298+
formAction?.setFieldValue(props.name, formToValue(currentValue));
299+
props.onChange && props.onChange(formToValue(currentValue), formAction);
300+
301+
setVisible(false);
302+
}
303+
}}
304+
multiple={props.selectMultiple}
305+
>
306+
{options
307+
&& options
308+
.filter(item => {
309+
if (searchText) {
310+
if (item.value.toUpperCase().includes(searchText.toUpperCase())) {
311+
return true;
312+
}
313+
if (item.label.toUpperCase().includes(searchText.toUpperCase())) {
314+
return true;
315+
}
316+
return false;
255317
}
256-
return false;
257-
}
258-
return true;
259-
}).map((item) => {
260-
return (
261-
<CheckboxItem {...item}/>
262-
)
263-
})}
264-
</CheckList>
318+
return true;
319+
}).map((item) => {
320+
return (
321+
<CheckboxItem {...item}/>
322+
)
323+
})}
324+
</CheckList>
325+
)}
265326
</div>
266327
</Popup>
267328
</Form.Item>

mobile-ui/src/components/form/types.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {NamePath} from "antd-mobile/es/components/form";
22
import {FormValidateContent} from "@/components/form/validate";
33
import {FormAction} from "@/components/form";
4+
import React from "react";
45

56
// Form表单选项类型
67
export interface FormOption {
@@ -24,6 +25,11 @@ export interface FormField {
2425
props: FormItemProps;
2526
}
2627

28+
// 自定义Select组件选项维护视图
29+
export interface SelectOptionFormEditProps {
30+
formAction?: React.Ref<FormAction>;
31+
}
32+
2733
// Form表单字段属性
2834
export interface FormItemProps {
2935
// 是否隐藏字段
@@ -62,6 +68,16 @@ export interface FormItemProps {
6268
textAreaMaxLength?: number,
6369
// select组件是否支持多选
6470
selectMultiple?: boolean,
71+
//select组件添加的视图是否开启编辑
72+
selectOptionFormEditable?: boolean,
73+
// select组件添加的视图
74+
selectOptionFormEditView?: React.ComponentType<SelectOptionFormEditProps>,
75+
// Select组件添加数据事件
76+
onSelectOptionFormFinish?: (formAction: FormAction,
77+
selectOptionFormEditFormAction: FormAction,
78+
reloadOption?: () => void,
79+
close?: () => void) => void;
80+
6581
// 文件上传接受的文件类型,默认为 image/*
6682
uploaderAccept?: string,
6783
// 文件上传最大数量
@@ -108,6 +124,7 @@ export interface FormItemProps {
108124
selectorColumn?: number,
109125
// Captcha组件切换验证码事件
110126
onCaptchaChange?: (value: string) => void;
127+
111128
}
112129

113130

mobile-ui/src/components/list/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, {useEffect} from "react";
22
import {ErrorBlock, InfiniteScroll, PullToRefresh as AntPullToRefresh} from "antd-mobile";
33
import {PullStatus} from "antd-mobile/es/components/pull-to-refresh";
44
import "./index.scss";
@@ -148,6 +148,10 @@ const PullToRefreshList: React.FC<PullToRefreshListProps> = (props) => {
148148
}
149149
}
150150

151+
useEffect(() => {
152+
refresh();
153+
}, []);
154+
151155
return (
152156
<div
153157
style={props.style}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from "react";
2+
import {SelectOptionFormEditProps} from "@/components/form/types";
3+
import Form from "@/components/form";
4+
import FormInput from "@/components/form/input";
5+
6+
const CustomFormEditOption:React.FC<SelectOptionFormEditProps> = (props)=>{
7+
return (
8+
<Form
9+
actionRef={props.formAction}
10+
>
11+
<FormInput
12+
name={"type"}
13+
label={"学科类别"}
14+
placeholder={"请输入学科类别"}
15+
/>
16+
</Form>
17+
)
18+
}
19+
20+
export default CustomFormEditOption;

0 commit comments

Comments
 (0)