JavaScript [React + Typescript + Antd] Common Filter Condition Component 소스.
페이지 정보
본문
안녕하세요. 엔지엠소프트웨어입니다. 리액트, 타입스크립트, 앤트 디자인을 이용한 필터 컨디션 컴포넌트 소스입니다. 이 컴포넌트는 공용으로 사용할 수 있도록 만든건데요. Backend로부터 일부 정보는 가져와야 사용할 수 있습니다. Filter Condition Component는 공통된 디자인 및 검색 로직을 사용하기 위한 컴포넌트입니다. 반도체와 같은 제조 프로젝트 환경에서 Depth(일반적으로 Site, Line, Area...와 같은 Location 정보)를 Select(ComboBox, DropDownList) 컨트롤로 표시합니다. 또한, 기간을 선택할 수 있도록 useDateTime 속성이 존재합니다. 각각의 Chart 또는 View Component에서 아래 Syntax에 맞게 사용할 수 있습니다. UI에서 Depth 정보를 Filter Condition Component로 넘겨줘야 합니다. Depth 정보를 바탕으로 각각의 Select 컨트롤을 동적으로 생성하고, Option 아이템을 바인딩합니다.
Design
Location Filter Condition
Parameter Filter Condition
Syntax
<ConditionComponent
conditionType={ConditionType.Location | ConditionType.Parameter}
backendAPI="http://localhost:2023/api/v1/common/condition/search-condition"
depths={depths | params}
selectLabelWidth={110}
useDateTime={false}
dateTimeText="Select Date (Default: 7days)"
title="Condition"
isMultiple={true}
isShowTime={true}
useRefresh={true}
useClear={true}
useAll={true}
useSelectAll={true}
useCancelRestore={true}
isMaskClosable={true}
isDestroyOnClose={true}
useDraggable={true}
propFunction={propFunction}>
</ConditionComponent>
Filter Condition Component를 사용하는 경우 아래와 같은 기본 정보가 필요합니다. 이 정보는 같이 배포되는 Backend의 Application.yml 또는 PostgreSQL DB에서 Query하거나 Frontend의 Config나 ini와 같은 설정 정보를 저장하는 곳에 입력해야 합니다. 사이트마다 Location은 동적으로 변경될 수 있기 때문에 공통 컴포넌트를 사용하는쪽에서 데이타를 넘겨야 합니다.
const depths = () => {
return [
{ key: 0, value: 'SITE', alias: '사이트 (Site)' },
{ key: 1, value: 'LINE', alias: '라인 (Line)' },
{ key: 2, value: 'AREA', alias: '에어리어 (Area)' },
];
};
const params = () => {
return [
{ key: 0, value: 'EQP01_PM1', alias: 'Parameters', type: '', limit: 100 }
];
};
Filter Condition Component Source
ConditionComponent.tsx
/**
* Documentation
* Filter Condition Component는 공통된 디자인 및 검색 로직을 사용하기 위한 컴포넌트입니다.
* 반도체와 같은 제조 프로젝트 환경에서 Depth(일반적으로 Site, Line, Area...와 같은 Location 정보)를 Select(ComboBox, DropDownList) 컨트롤로 표시합니다.
* 또한, 기간을 선택할 수 있도록 useDateTime 속성이 존재합니다.
* 각각의 Chart 또는 View Component에서 아래 Syntax에 맞게 사용할 수 있습니다.
* Frontend에서 Depth(Location) 정보를 Filter Condition Component로 넘겨줘야 합니다.
* Depth (Location) 정보를 바탕으로 각각의 Select 컨트롤을 동적으로 생성하고, Option 아이템을 바인딩합니다.
*/
import { SettingOutlined, ReloadOutlined } from '@ant-design/icons';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Modal, Form, Select, DatePicker, Tooltip, Space, Button } from 'antd';
import classes from './ConditionComponent.module.css';
import dayjs from 'dayjs';
import 'dayjs/locale/ko';
import moment from 'moment';
import type { DraggableData, DraggableEvent } from 'react-draggable';
import Draggable from 'react-draggable';
import { lutimes } from 'fs';
import { NavigationType } from 'react-router-dom';
function ConditionComponent(props: any) {
const { RangePicker } = DatePicker;
/**
* Default Depth 설정
* 이 값은 View Component로부터 받아야 합니다.
*/
const [depths, setDepths] = useState<any[]>([
{ key: 0, value: 'SITE', alias: '사이트', type: '', limit: -1 },
{ key: 1, value: 'LINE', alias: '라인', type: '', limit: -1 },
{ key: 2, value: 'AREA', alias: '에어리어', type: '', limit: -1 },
]);
/**
* Condition Result Items
*/
const [conditionData, setConditionData] = useState<any>({});
//#region Component state
//#region Date Ragne Picker state
const [isShowTime, setIsShowTime] = useState<Boolean>(props.isShowTime);
const [selectTime, setConfigTime] = useState<any>([
dayjs().add(-7, 'd'),
dayjs(),
]);
const [dateTimeFormat, setDateTimeFormat] = useState<String>(
props.dateTimeFormat
);
const [start, setStart] = useState<any>(dayjs().add(-7, 'd'));
const [end, setEnd] = useState<any>(dayjs());
//#endregion
//#region Select config state
const [selectedOptionItems, setSelectedOptionItems] = useState<any>({});
const [selectLabelWidth, setSelectLabelWidth] = useState<any>(
props.selectLabelWidth
);
const [isMultiple, setIsMultiple] = useState<Boolean>(props.isMultiple);
const [selectOptionItems, setSelectOptionItems] = useState<any>({});
const [optionItems, setOptionItems] = useState<any>({});
const [prevConditionData, setPrevConditionData] = useState<any>({});
const [selectPlaceholder, setSelectPlaceholder] = useState<String>(
props.selectPlaceholder
);
//#endregion
//#region Component design state
const [useDraggable, setUseDraggable] = useState<any>(props.useDraggable);
const [disabled, setDisabled] = useState(true);
const [bounds, setBounds] = useState({
left: 0,
top: 0,
bottom: 0,
right: 0,
});
const draggleRef = useRef<HTMLDivElement>(null);
const [conditionTitle, setTitle] = useState<String>(props.title);
const [isModalOpen, setIsModalOpen] = useState<any>(false);
const [useAll, setUseAll] = useState<any>(props.useAll);
const [useAllText, setUseAllText] = useState<String>(props.useAllText);
const [useCancelRestore, setUseCancelRestore] = useState<any>(
props.useCancelRestore
);
const [useClear, setUseClear] = useState<any>(props.useClear);
const [useSelectAll, setUseSelectAll] = useState<any>(props.useSelectAll);
const [useDateTime, setUseDateTime] = useState<any>(props.useDateTime);
const [dateTimeText, setDateTimeText] = useState<any>(props.dateTimeText);
const [useRefresh, setUseRefresh] = useState<any>(props.useRefresh);
const [isMaskClosable, setIsMaskCloable] = useState<any>(
props.isMaskClosable
);
const [isDestroyOnClose, setIsDestroyOnClose] = useState<any>(
props.isDestroyOnClose
);
const [conditionType, setConditionType] = useState<ConditionType>(
props.conditionType
);
const [restfulAPI, setRestfulAPI] = useState<String>(props.restfulAPI);
//#endregion
const fetchDepthDataHandler = useCallback(async (request: any) => {
if (request.length == 0) {
return;
}
let backendAPI = restfulAPI;
try {
if (request.paths != undefined && request.paths.length > 0) {
if (!(typeof request.paths[0] === 'string')) {
request.paths = request.paths.map(function (v: any) {
return v.value;
});
}
}
const resquestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application.json',
},
};
let params = '';
switch (conditionType) {
case ConditionType.Location:
params = new URLSearchParams({
conditionDesignData: JSON.stringify(request),
}).toString();
break;
case ConditionType.Parameter:
params = `assetID=${request.assetID}&type=${request.type}&limit=${request.limit}`;
break;
}
const response = await fetch(`${backendAPI}?${params}`, resquestOptions);
if (!response.ok) {
throw new Error('Something went wrong!');
}
const data = await response.json();
if (useSelectAll && isMultiple) {
switch (conditionType) {
case ConditionType.Location:
if (data.result.items.length > 0) {
data.result.items.splice(0, 0, { key: -1, value: 'ALL' });
}
break;
case ConditionType.Parameter:
if (data.result.length > 0) {
data.result.splice(0, 0, { rawid: -1, name: 'ALL' });
}
break;
}
}
switch (conditionType) {
case ConditionType.Location:
setSelectOptionItems((prevState: any) => {
return { ...prevState, [request.depth]: data.result.items };
});
break;
case ConditionType.Parameter:
let params: any = [];
data.result.forEach((item: any) => {
params.push({ key: item.rawid, value: item.name });
});
setSelectOptionItems((prevState: any) => {
return { ...prevState, [request.assetID]: params };
});
break;
}
} catch (error: any) {
throw error;
}
}, []);
//#region Events
//#region Life-cycle events
/**
* WebPage 가 Loaded되면 최초 발생하는 이벤트입니다.
*/
useEffect(() => {
props.propFunction(conditionData);
if (props.conditionType == undefined || props.conditionType == '') {
setConditionType(ConditionType.Location);
}
if (props.dateTimeFormat == undefined || props.dateTimeFormat == '') {
setDateTimeFormat('YYYY-MM-DD HH:mm:ss');
}
if (props.selectPlaceholder == undefined || props.selectPlaceholder == '') {
setSelectPlaceholder('Please select');
}
if (props.useAllText == undefined || props.useAllText == '') {
setUseAllText('Select ALL');
}
setDepths(props.depths);
fetchDepthDataHandler(props.depths);
}, [conditionData]);
//#endregion
//#region Component events
/**
* Condition Component에서 Cancel 버튼을 클릭할 때 이벤트가 발생합니다.
*/
const onOk = () => {
// 모달을 닫아줍니다.
setIsModalOpen(false);
let startTime = '';
let endTime = '';
selectTime.forEach((d: any, index = 0) => {
const date = moment(d.$d).format(`${dateTimeFormat}`);
if (index === 0) {
startTime = date;
index++;
} else {
endTime = date;
}
});
depths.forEach((d: any) => {
if (d.value in optionItems && d.value in selectOptionItems) {
selectOptionItems[d.value].forEach((x: any) => {
if (x.value == 'ALL') {
return;
}
optionItems[d.value].forEach((y: any) => {
const index = optionItems[d.value].indexOf(x.value);
if (index > -1) {
optionItems[d.value].splice(index, 1, x);
}
});
});
}
});
if (useDateTime) {
setConditionData({
startTime: startTime,
endTime: endTime,
selectItems: optionItems,
});
} else {
setConditionData({
selectItems: optionItems,
});
}
if (useCancelRestore) {
setPrevConditionData([
{ ...optionItems },
{ ...selectOptionItems },
{ ...selectedOptionItems },
]);
}
if (isDestroyOnClose) {
refreshClick();
}
};
/**
* Condition Component에서 Cancel 버튼을 클릭할 때 이벤트가 발생합니다.
*/
const onCancel = () => {
// 모달을 닫아줍니다.
setIsModalOpen(false);
if (useCancelRestore) {
if (
prevConditionData &&
prevConditionData.length != undefined &&
prevConditionData.length > 2
) {
setOptionItems(prevConditionData[0]);
setSelectOptionItems(prevConditionData[1]);
setSelectedOptionItems(prevConditionData[2]);
}
}
if (isDestroyOnClose) {
refreshClick();
}
};
/**
* Select에서 항목을 선택할 때 이벤트가 발생합니다.
* @param e Select에서 선택한 항목이 배열로 들어옵니다.
* isMultiple 속성을 false로 설정하면 항목 이름만 들어옵니다.
*/
const dateChange = (e: any) => {
const timeList: any[] = [];
setStart(e[0]);
setEnd(e[1]);
timeList.push(e[0], e[1]);
setConfigTime(timeList);
};
/**
* 새로고침 버튼을 클릭하면 이벤트가 발생합니다.
* 모든 내용을 초기 상태로 만듭니다. (시간은 현재 시간으로 다시 설정됩니다.)
*/
const refreshClick = () => {
setStart(dayjs().add(-7, 'd'));
setEnd(dayjs());
setOptionItems({});
setSelectOptionItems({});
setSelectedOptionItems({});
depths.forEach((d: any) => {
optionItems[d.value] = [];
});
setOptionItems({ ...optionItems });
setSelectOptionItems({ ...optionItems });
setSelectedOptionItems({ ...optionItems });
};
/**
* Select를 클릭하면 이벤트가 발생합니다.
* Select의 Option(Item)을 채워주는 로직입니다.
* @param value select control
* @param index select index
*/
const selectClick = (value: any, index: number) => {
setSelectedOptionItems({});
switch (conditionType) {
case ConditionType.Location:
if (!(value.target.className.toString().indexOf('option') > -1)) {
if (index == 0) {
fetchDepthDataHandler({
depth: depths[index].value,
depthIndex: index,
});
} else {
if (
optionItems[depths[index - 1].value] != undefined &&
optionItems[depths[index - 1].value].length > 0
) {
fetchDepthDataHandler({
depth: depths[index].value,
depthIndex: index - 1,
paths: optionItems[depths[index - 1].value],
});
} else {
selectOptionItems[depths[index].value] = [];
setSelectOptionItems(selectOptionItems);
}
}
}
break;
case ConditionType.Parameter:
fetchDepthDataHandler({
assetID: depths[index].value,
type: depths[index].type,
limit: depths[index].limit,
});
break;
}
if (!isMultiple) {
setTimeout(function () {
cleanOptionItems(optionItems);
}, 1);
}
};
/**
* Select 에서 항목(Option)을 선택한 값이 배열로 들어옵니다.
* @param value selected options
* @param index select index
*/
const selectChange = (value: string[], index: number) => {
if (isMultiple) {
if (useSelectAll && Object.values(value).includes('ALL')) {
selectOptionItems[depths[index].value].splice(0, 1);
const items = selectOptionItems[depths[index].value].map(function (
v: any
) {
return v.value;
});
if (items.length == value.length - 1) {
return;
}
optionItems[depths[index].value] = items;
} else {
optionItems[depths[index].value] = value;
}
if (value.length == 0) {
depths.forEach((d: any, i: number) => {
if (index <= i) {
optionItems[d.value] = [];
}
});
}
} else {
optionItems[depths[index].value] = [value];
depths.forEach((d: any, i: number) => {
if (index < i) {
optionItems[d.value] = [];
}
});
}
};
const deselectChange = (value: string[], index: number) => {
if (isMultiple) {
depths.forEach((d: any, i: number) => {
if (index < i) {
optionItems[d.value] = [];
}
});
setSelectedOptionItems({ ...optionItems });
}
};
const selectAll = async () => {
try {
var i = 0;
const resquestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application.json',
},
};
let params: any;
let response: any;
let data: any;
for (const d of depths) {
let request;
optionItems[d.value] = [];
switch (conditionType) {
case ConditionType.Location:
if (i == 0) {
request = { depth: d.value, depthIndex: i };
} else {
var idx = 0;
if (i > 1) {
idx = 1;
}
request = {
depth: d.value,
depthIndex: idx,
paths: optionItems[depths[i - 1].value].map(function (v: any) {
return v.value;
}),
};
}
params = new URLSearchParams({
conditionDesignData: JSON.stringify(request),
}).toString();
response = await fetch(`${restfulAPI}?${params}`, resquestOptions);
if (!response.ok) {
throw new Error('Something went wrong!');
}
data = await response.json();
optionItems[d.value] = data.result.items;
break;
case ConditionType.Parameter:
request = {
assetID: depths[i].value,
type: depths[i].type,
limit: depths[i].limit,
};
params = `assetID=${request.assetID}&type=${request.type}&limit=${request.limit}`;
response = await fetch(`${restfulAPI}?${params}`, resquestOptions);
if (!response.ok) {
throw new Error('Something went wrong!');
}
data = await response.json();
params = [];
data.result.forEach((item: any) => {
params.push({ key: item.rawid, value: item.name });
});
optionItems[d.value] = params;
break;
}
i++;
}
setSelectedOptionItems(optionItems);
} catch (error: any) {
throw error;
}
};
/**
* Select 내부 이벤트(onChange, onSelect)에서 항목을 갱신할 수 없는 문제가 있어서,
* 별도 함수에서 업데이트 하도록 처리하는 함수입니다.
* @param items Select를 갱신할 옵션 아이템 목록입니다.
*/
const cleanOptionItems = (items: any) => {
setSelectedOptionItems(items);
};
const onStart = (_event: DraggableEvent, uiData: DraggableData) => {
const { clientWidth, clientHeight } = window.document.documentElement;
const targetRect = draggleRef.current?.getBoundingClientRect();
if (!targetRect) {
return;
}
setBounds({
left: -targetRect.left + uiData.x,
right: clientWidth - (targetRect.right - uiData.x),
top: -targetRect.top + uiData.y,
bottom: clientHeight - (targetRect.bottom - uiData.y),
});
};
//#endregion
//#endregion
/**
* Condition Component 실행 여부 상태를 저장합니다.
*/
const showModal = () => {
setIsModalOpen(true);
};
return (
<div className={classes.btn}>
<SettingOutlined onClick={showModal} />
<Modal
maskClosable={isMaskClosable}
title={
useDraggable ? (
<div
style={{
width: '100%',
cursor: 'move',
}}
onMouseOver={() => {
if (disabled) {
setDisabled(false);
}
}}
onMouseOut={() => {
setDisabled(true);
}}
onFocus={() => {}}
onBlur={() => {}}
>
{conditionTitle}
</div>
) : (
<div>{conditionTitle}</div>
)
}
open={isModalOpen}
onOk={onOk}
onCancel={onCancel}
footer={
useAll
? [
<Button onClick={selectAll}>Select ALL</Button>,
<Button key="cancel" onClick={onCancel}>
Cancel
</Button>,
<Button key="submit" type="primary" onClick={onOk}>
OK
</Button>,
]
: [
<Button key="cancel" onClick={onCancel}>
Cancel
</Button>,
<Button key="submit" type="primary" onClick={onOk}>
OK
</Button>,
]
}
modalRender={(modal) => (
<Draggable
disabled={disabled}
bounds={bounds}
onStart={(event, uiData) => onStart(event, uiData)}
>
<div ref={draggleRef}>{modal}</div>
</Draggable>
)}
>
<div
style={{ display: useDateTime ? 'block' : 'none', marginBottom: 10 }}
>
{dateTimeText != undefined ? (
<div style={{ marginBottom: 10 }} className={classes.title}>
{dateTimeText}
</div>
) : (
''
)}
<div style={{ float: useRefresh ? 'left' : 'none', marginRight: 10 }}>
<RangePicker
className={classes.date}
defaultValue={[dayjs().add(-7, 'd'), dayjs()]}
value={[start, end]}
onChange={(e) => dateChange(e)}
showTime={isShowTime ? true : false}
/>
</div>
<div style={{ display: useRefresh ? 'block' : 'none' }}>
<Tooltip title="refresh">
<ReloadOutlined
className={classes.refresh}
onClick={refreshClick}
/>
</Tooltip>
</div>
</div>
<br />
{depths.map((d, i) => (
<Form
key={d.key}
labelCol={{ span: 4 }}
wrapperCol={{ span: 14 }}
layout="horizontal"
style={{ maxWidth: 600 }}
>
<Form.Item
label={d.alias}
labelCol={{
style: {
width: selectLabelWidth == undefined ? 100 : selectLabelWidth,
},
}}
>
<Space wrap style={{ width: 600 }}>
<Select
allowClear={useClear}
style={{
width:
!useDateTime && useRefresh
? 330 -
((selectLabelWidth == undefined
? 100
: selectLabelWidth) -
100)
: 370 -
((selectLabelWidth == undefined
? 100
: selectLabelWidth) -
100),
}}
mode={isMultiple ? 'multiple' : undefined}
placeholder={selectPlaceholder}
value={
d.value in selectedOptionItems
? selectedOptionItems[d.value]
: optionItems[d.value]
}
onClick={(e) => selectClick(e, i)}
onChange={(e) => selectChange(e, i)}
onDeselect={(e) => deselectChange(e, i)}
>
{d.value in selectOptionItems
? selectOptionItems[d.value].map((c: any) => (
<Select.Option key={c.key} value={c.value}>
{c.value}
</Select.Option>
))
: ''}
</Select>
{i == 0 && !useDateTime && useRefresh ? (
<Tooltip title="refresh">
<ReloadOutlined
className={classes.refresh}
onClick={refreshClick}
/>
</Tooltip>
) : (
''
)}
</Space>
</Form.Item>
</Form>
))}
</Modal>
</div>
);
}
export default ConditionComponent;
export enum ConditionType {
Location = 0,
Parameter = 1,
}
Properties
1. depths (Required): 사이트(Site), 라인(Line), 에어리어(Area)로 표시되는 정보를 ConditionComponent로 넘겨줍니다. 이 값은 depth라고 부르며, location_mst 테이블에 code로 등록되어 있습니다.
- ex) depths 오브젝트
- key: rawid
- value: location_mst 테이블의 code 또는 assetID
- alias: 사용자에게 보여지는 텍스트
- type: 파라메터 타입
- limit: 가져올 파라메터 수
// 로케이션 필터 컨디션
const depths = () => {
return [
{ key: 0, value: 'SITE', alias: '사이트 (Site)' },
{ key: 1, value: 'LINE', alias: '라인 (Line)' },
{ key: 2, value: 'AREA', alias: '에어리어 (Area)' },
];
};
<ConditionComponent conditionType={ConditionType.Location} depths={depths} ...
// 파라메터 필터 컨디션
const params = () => {
return [
{ key: 0, value: 'eqp01_pm1', alias: '파라메터', type: '', limit: 100 }
];
};
<ConditionComponent conditionType={ConditionType.Parameter} depths={params} ...
2. selectLabelWidth (Optional): Select 콘트롤의 좌측에 표시되는 라벨의 넓이입니다. 크기를 200 또는 "100%"와 같이 입력할 수 있습니다.
- selectLabelWidth={110} or selectLabelWidth="100%"
3. useDateTime (Optional): 조회 조건 컨트롤에서 상단의 날짜 컨트롤 표시 여부를 true, false로 설정합니다.
4. dateTimeText (Optional): 날짜 기간 조건의 설명 글을 추가할 수 있습니다.
5. useRefresh (Optional): 조회 조건 초기화 버튼을 표시합니다.
6. title (Optional): ConditionComponent의 제목입니다.
7. isMultiple (Optional): Select 콘트롤에서 아이템을 멀티로 선택할지 여부를 true, false로 설정합니다.
8. isShowTime (Optional): 날짜 선택 콘트롤에서 시간을 표시할지 여부를 true, false로 설정합니다.
9. isDestroyOnClose (Optional): 모달 콘디션창을 닫을 때 모달의 모든 내용을 삭제합니다.
10. propFunction (Required): ConditionComponent에서 사용자가 선택한 데이타를 받아올 함수를 연결합니다.
11. useAll (Optional): Modal 상자에 All Select 버튼이 생성되고, 모든 Select 콘트롤의 모든 항목이 추가됩니다.
12. useSelectAll (Optional): Select 콘트롤에서 ALL 옵션이 추가되고, 클릭하면 모든 항목이 추가됩니다.
13. useClear (Optional): Select 콘트롤에서 전체 삭제 버튼을 표시합니다.
14. isMaskClosable (Optional): 모달창의 외부를 클릭했을 때 창을 닫을지 여부를 설정합니다.
15. useDraggable (Optional): 모달창을 드래그하여 위치를 이동할 수 있습니다.
16. useCancelRestore (Optional): 모달창에서 Cancel 버튼을 클릭하는 경우 이전 OK 정보로 복구 해줍니다.
17. dateTimeFormat (Optional): YYYY-MM-DD HH:mm:ss
18. selectPlaceholder (Optional): Please select
19. useAllText (Optional): Select ALL
20. restfulAPI (Required): Backend API를 넘겨줍니다.
- Location: http://localhost:2023/api/v1/common/condition/locations
- Parameter: http://localhost:2023/api/v1/common/condition/parameters
Result
endTime: string (useDateTime 속성이 true인 경우만 반환)
startTime: string (useDateTime 속성이 true인 경우만 반환)
selectItems: indexer
{selectItems:
[SITE]: [
{ key: rawid, value: SITE1 },
{ key: rawid, value: SITE2 },
{ key: rawid, value: SITE3 },
],
[LINE]: [
{ key: rawid, value: LINE1},
{ key: rawid, value: LINE2},
{ key: rawid, value: LINE3},
],
[AREA]: [
{ key: rawid, value: AREA1 },
{ key: rawid, value: AREA2 },
{ key: rawid, value: AREA3 },
]
}
Examples
기본 조건 컴포넌트로 단일 항목만 선택할 수 있습니다.
<ConditionComponent depths={depths} propFunction={propFunction}></ConditionComponent>
조건 컴포넌트에 날짜 조건을 추가하려면 아래와 같이 useDateTime을 true로 설정하세요.
<ConditionComponent depths={depths} useDateTime={true} propFunction={propFunction}></ConditionComponent>
시간까지 표시하려면 isShowTime을 true로 설정해야 합니다.
<ConditionComponent depths={depths} useDateTime={true} isShowTime={true} propFunction={propFunction}></ConditionComponent>
날짜 콘트롤에 도움말을 표시하려면 아래와 같이 dateTimeText 속성에 텍스트를 추가할 수 있습니다.
<ConditionComponent depths={depths} useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
모달창에 타이틀을 추가하려면 title 속성을 사용하세요.
<ConditionComponent depths={depths} title="Common Condition" useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
useClear 속성을 true로 변경하면 Select 콘트롤에 전체 삭제 아이콘이 표시됩니다.
<ConditionComponent depths={depths} useClear={true} isMultiple={true} title="Common Condition" useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
useAll 속성을 true로 설정하면 모달창 하단에 Select ALL 버튼이 추가되고, 모든 Select 컨트롤의 항목이 선택됩니다.
<ConditionComponent depths={depths} useClear={true} isMultiple={true} title="Common Condition" useAll={true} useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
useSelectAll 속성을 true로 설정하면 Select 콘트롤에 ALL 항목이 추가되고, Select 컨트롤의 모든 항목이 선택됩니다.
<ConditionComponent depths={depths} useClear={true} isMultiple={true} title="Common Condition" useAll={true} useSelectAll={true} useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
전체 속성을 사용하면 아래와 같이 표시됩니다.
<ConditionComponent useClear={true} depths={depths} useAll={true} useSelectAll={true} isDestroyOnClose={true} dateTimeText="Select Date ( Default : 7days)" isMultiple={true} selectLabelWidth={110} useDateTime={true} useRefresh={true} title="Common Condition" isShowTime={true} propFunction={propFunction}></ConditionComponent>
개발자에게 후원하기
추천, 구독, 홍보 꼭~ 부탁드립니다.
여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~
감사합니다~
- 이전글Spring boot - 외부에서 설정 주입하는 방법. (application.properties, application.yml) 23.04.25
- 다음글JavaScript에서 배열의 값을 삭제하고, 삭제한 위치에 새로운 내용을 추가하는 방법. (with Array.prototype.splice()) 23.04.22
댓글목록
등록된 댓글이 없습니다.