DatePeriodPicker
이 컨트롤은 무엇인가요?
DatePeriodPicker는 <syn_dateperiodpicker> 태그 하나로 "시작일 입력창 + ~ + 종료일 입력창 + 달력 아이콘 버튼"을 만들어 주는 레거시 내부 JS UI 컨트롤입니다. 버튼을 누르면 화면 우측에 시작 일용/종료일용 달력 2개와, "올해/오늘까지/오늘/전일/주간/전주/당월/이전달/전년도/전전년도/14분기/상반기/하반기/112월" 같은 자주 쓰는 기간을 한 번에 선택할 수 있는 빠른 선택 버튼 모음(팝업)이 함께 나타납니다.
내부적으로는 Pikaday 달력 라이브러리를 시작일/종료일 각각 하나씩(총 2개) 사용하며, 실제로 화면에 보이는 시작일/종료일 입력창 2개는 syn.uicontrols.$textbox(editType: 'date') 컨트롤로 각각 초기화됩니다. 즉 DatePeriodPicker 하나는 내부적으로 텍스트박스 2개 + 공용 팝업 1개로 구성됩니다.
syn.loader.js가 페이지에 있는 <syn_dateperiodpicker> 태그를 찾아서 자동으로 다음을 처리합니다.
DatePeriodPicker.js/DatePeriodPicker.css등 필요한 스크립트·스타일 자동 주입- 원래 태그를 숨김 처리(
display: none)하고, 그 옆에 실제 보이는 시작일 입력창,~구분자, 종료일 입력창, 달력 버튼을 순서대로 생성 - 페이지 안에 하나뿐인 공용 팝업(
#divPeriodPicker)을 최초 1회 생성하고, 팝업 안 빠른 선택 버튼들에 이벤트를 연결 syn.uicontrols.$dateperiodpicker싱글턴 객체에 컨트롤 정보 등록 (getValue/setValue/clear등으로 제어 가능)
이름은 $dateperiodpicker이지만, 페이지에서 사용하는 태그명은 syn_dateperiodpicker입니다. 이 문서 전체에서 "DatePeriodPicker 컨트롤"이라 하면 이 둘을 함께 가리킵니다.
이 컨트롤은 아직
sample/uicontrol아래에 표준 데모 페이 지가 없습니다. 이 문서의 API 사실 근거는DatePeriodPicker.js소스 코드 전체를 직접 읽고 확인한 내용이며, 실사용 마크업 스타일은qcn.groupware저장소의modules/bridal/wwwroot/bridal/view/HDS/BDL/BOD001.html예시(참고용)를 참고했습니다.
언제 사용하나요?
- 형제 컨트롤인
DatePicker(syn.uicontrols.$datepicker) 는 날짜 1개만 다룹니다. DatePeriodPicker는 처음부터 "기간(period)" 개념으로 설계되어, 시작일~종료일 한 쌍을 태그 하나로 관리합니다.- 요약하면:
- 날짜 1개, 단순 입력 →
DatePicker - 조회 시작일/종료일처럼 기간을 하나의 값으로 다루고 싶다 →
DatePeriodPicker - "최근 1주일", "이번 달", "1분기"처럼 자주 쓰는 기간을 버튼 한 번으로 선택하게 하고 싶다 →
DatePeriodPicker(팝업에 프리셋 버튼이 내장되어 있음)
- 날짜 1개, 단순 입력 →
빠른 시작
<form autocomplete="off" id="form1" syn-datafield="MainForm">
<syn_dateperiodpicker id="dtpSearchPeriod" syn-datafield="SearchPeriod"></syn_dateperiodpicker>
</form>
<script src="/js/syn.loader.js"></script>
이렇게만 작성해도 syn.loader.js가 알아서 필요한 리소스를 불러오고, 화면에는 "시작일 입력창 ~ 종료일 입력창 + 달력 버튼"이 나타납니다. 버튼을 누르면 팝업이 열리고, 좌우 달력에서 시작일/종료일을 각각 클릭한 뒤 "확인" 버튼을 눌러야 실제 입력창에 값이 반영됩니다. 값을 지우려면 팝업의 "기간 선택 취소" 버튼을 사용합니다.
값을 코드로 다루고 싶다면 아래처럼 syn.uicontrols.$dateperiodpicker를 사용합니다.
// 값 읽기 (형식: "시작일 ~ 종료일")
var value = syn.uicontrols.$dateperiodpicker.getValue('dtpSearchPeriod'); // 예: '2026-07-01 ~ 2026-07-06'
// 값 설정 (콤마로 시작일, 종료일 구분. 값이 1개면 시작일=종료일로 처리)
syn.uicontrols.$dateperiodpicker.setValue('dtpSearchPeriod', '2026-01-01,2026-01-31');
// 값 초기화
syn.uicontrols.$dateperiodpicker.clear('dtpSearchPeriod');
시작일/종료일을 서로 다른 데이터필드에 매핑하고, 기본값을 "오늘부터 3개월 후까지"로 지정하고 싶다면 다음처럼 사용할 수 있습니다(실사용 예: qcn.groupware의 공지 게시 기간).
<syn_dateperiodpicker id="dtpAlertPeriod" syn-datafield="AlertPeriod" syn-events="['onselect']" syn-options="{
value: 'month:3', startDataFieldID: 'AlertStartedDate', endDataFieldID: 'AlertEndedDate'
}"></syn_dateperiodpicker>
예제 실행하기
이 폴더의 example 하위 폴더에 있는 HTML 파일을 웹서버(예: rdy 실행 중인 wwwroot)를 통해 브라우저로 열어보세요. file://로 직접 열면 syn.loader.js가 정상 동작하지 않을 수 있으니 반드시 프로젝트를 실행한 상태에서 접속해야 합니다.
example/basic.html: 가장 단순한 기간 선택 예제(팝업의 빠른 선택 버튼 포함)example/shorthand.html:value축약 표기('day:-7','month:3'등)로 초기값을 지정하는 예제example/events.html:onselect/onreset/onconfirm이벤트,getValue/setValue/clear버튼 데모
각 HTML은 같은 이름의 .js 파일과 짝을 이루며, 화면 하단 로그 영역에 syn.$l.eventLog로 동작 로그가 출력됩니다.
더 알아보기
- 상세 옵션·메서드·이벤트 표는 아래 API 참조 섹션 문서를 참고하세요.
- 달력 팝업 자체의 세부 동작(연/월 이동 등)은 내부적으로 사용하는 Pikaday 라이브러리 문서를 참고하세요: https://github.com/Pikaday/Pikaday
- 날짜 1개만 필요하다면 형제 컨트롤
DatePicker(syn.uicontrols.$datepicker)를 확인하세요. - 소스 위치:
uicontrols/DatePeriodPicker/DatePeriodPicker.js,uicontrols/DatePeriodPicker/DatePeriodPicker.css
실전 예제 페이지
/uicontrols/DatePeriodPicker/example/ 경로의 예제를 아래 iframe에서 바로 확인할 수 있습니다.
basic.html
events.html
shorthand.html
소스와 로드 파일
| 항목 | 내용 |
|---|---|
| 컨트롤 | DatePeriodPicker |
| 전역 별칭 | syn.uicontrols.$dateperiodpicker |
| 버전 | v2025.5.22 |
| 소스 | uicontrols/DatePeriodPicker/DatePeriodPicker.js |
| 스타일 | uicontrols/DatePeriodPicker/DatePeriodPicker.css |
API 참조
syn.uicontrols.$dateperiodpicker
마크업
<syn_dateperiodpicker id="dtpSearchPeriod" syn-datafield="SearchPeriod" syn-events="['onselect', 'onreset', 'onconfirm']" syn-options="{
value: 'month:3',
startDataFieldID: 'SearchStartedDate',
endDataFieldID: 'SearchEndedDate',
belongID: 'M01'
}"></syn_dateperiodpicker>
syn.loader.js가 로드되면서controlLoad(elID, setting)이 자동 호출되어 원래<syn_dateperiodpicker>태그는elID + '_hidden'으로 숨겨지고, 그 자리에 다음 요소들이 순서대로 생성됩니다.- 시작일 입력창: id =
{elID}_StartedAt(내부적으로syn.uicontrols.$textbox에editType: 'date',maskPattern: '9999-99-99'로 등록) ~구분<span>- 종료일 입력창: id =
{elID}_EndedAt(시작일 입력창과 동일한 방식으로 등록) - 달력 버튼: id =
{elID}_Button
- 시작일 입력창: id =
syn-events에 지정한 이벤트 이름 배열은 시작일/종료일 입력창 두 곳에 그대로 복사되며, 팝업에서 발생하는onselect/onreset/onconfirm이벤트를 페이지 스크립트로 전달하는 데 사용됩니다.- 페이지 안에서
<syn_dateperiodpicker>를 몇 개를 쓰더라도, 빠른 선택 버튼이 포함된 팝업(#divPeriodPicker)과 Pikaday 인스턴스 2개(시작일용/종료일용)는 페이지 전체에서 1세트만 공유됩니다. 버튼을 누른 컨트롤의 id가 팝업의elID속성에 기록되고, "확인"/"기간 선택 취소" 버튼 클릭 시 이elID를 기준으로 어떤 컨트롤에 값을 반영할지 결정합니다.
Options (defaultSetting)
| 옵션 | 타입/기본값 | 설명 |
|---|---|---|
elID | string | 컨트롤 로드시 내부적으로 자동 채워짐(직접 지정할 필요 없음) |
width | string, 기본 '100%' | 컨트롤 전체 폭(참고용 값, 실제 폭은 생성된 입력창들의 CSS에 따름) |
value | string, 기본 '' | 초기값 축약 표기. 아래 "value 축약 표기" 표 참고 |
defaultDate / setDefaultDate | Pikaday 옵션 그대로 전달 | 달력을 처음 열 때 표시할 기본 날짜 |
minDate / maxDate | Date, 기본 null | 선택 가능한 최소/최대 날짜(Pikaday에 그대로 전달) |
bound | boolean, 기본 false | Pikaday 옵션. 이 컨트롤은 팝업 표시/숨김을 자체 로직(showPopup/hidePopup)으로 제어하므로 기본값 false 사용 |
format | string, 기본 'YYYY-MM-DD' | Pikaday에 전달되는 날짜 포맷(moment 포맷 문자열) |
ariaLabel | string, 기본 '날짜를 선택 하세요' | 달력 접근성 라벨 |
i18n | object | 월/요일 이름 등 한글 로케일 텍스트(기본값이 이미 한글로 설정되어 있어 보통 그대로 사용) |
showWeekNumber | boolean, 기본 false | 주차 번호 표시 여부 |
showMonthAfterYear | boolean, 기본 true | 달력 헤더에 "년도 다음에 월" 순서로 표시 |
showDaysInNextAndPreviousMonths | boolean, 기본 true | 이전/다음 달 날짜를 회색으로 함께 표시 |
enableSelectionDaysInNextAndPreviousMonths | boolean, 기본 true | 이전/다음 달 날짜도 선택 가능하게 할지 여부 |
yearSuffix | string, 기본 '년' | 연도 뒤에 붙는 접미사 |
firstDay | number, 기본 0 | 한 주의 시작 요일(0=일요일) |
numberOfMonths | number, 기본 1 | 달력 하나에 동시에 표시할 월 수 |
startDataFieldID | string, 기본 '' | 생성되는 시작일 입력창의 syn-datafield 값. 비우면 {elID}_StartedAt 사용 |
endDataFieldID | string, 기본 '' | 생성되는 종료일 입력창의 syn-datafield 값. 비우면 {elID}_EndedAt 사용 |
startClassName | string, 기본 'form-control' | 시작일 입력창에 적용할 CSS class |
endClassName | string, 기본 'form-control' | 종료일 입력창에 적용할 CSS class |
dataType | string, 기본 'string' | 다른 컨트롤과 동일한 관례로 정의만 되어 있으며, 이 컨트롤의 clear()는 값 형식과 무관하게 항상 빈 문자열로 초기화함(내부에서 별도로 참조하지 않음) |
belongID | string | array, 기본 null | 소속 그룹/프레임 식별자. 지정하면 생성되는 시작일/종료일 입력창의 syn-options에 그대로 전달됨 |
getter / setter | boolean, 기본 false | 다른 컨트롤과 동일한 표준 옵션(정의되어 있으나 이 컨트롤 내부 로직에서 직접 참조하지는 않음) |
controlText | string, 기본 null | 컨트롤 표시명(다른 컨트롤과 동일한 관례) |
validators | array, 기본 null | 폼 전송 검증 규칙(다른 컨트롤과 동일한 관례) |
transactConfig / triggerConfig | object, 기본 null | 트랜잭션/트리거 연동 설정(다른 컨트롤과 동일한 관례) |
value 축약 표기
value 옵션에 아래 형식의 문자열을 지정하면 컨트롤 로드 시 시작일/종료일 입력창에 초기값이 자동으로 채워집니다(오늘 날짜 기준으로 계산).
| 표기 | 의미 | 숫자가 음수일 때 | 숫자가 0 이상일 때 |
|---|---|---|---|
'now' | 오늘 하 루 | - | 시작일 = 종료일 = 오늘 |
'day:N' | 오늘 기준 N일 | 시작일 = N일 전, 종료일 = 오늘 | 시작일 = 오늘, 종료일 = N일 후 |
'week:N' | 오늘 기준 N주 | 시작일 = N주 전, 종료일 = 오늘 | 시작일 = 오늘, 종료일 = N주 후 |
'month:N' | 오늘 기준 N개월 | 시작일 = N개월 전, 종료일 = 오늘 | 시작일 = 오늘, 종료일 = N개월 후 |
'year:N' | 오늘 기준 N년 | 시작일 = N년 전, 종료일 = 오늘 | 시작일 = 오늘, 종료일 = N년 후 |
예: value: 'month:3' → 시작일 = 오늘, 종료일 = 3개월 후. value: 'day:-7' → 시작일 = 7일 전, 종료일 = 오늘.
이 표기는 컨트롤이 처음 로드될 때 입력창의 표시값만 채워주는 용도이며, 사용자가 팝업을 열어 직접 확인/변경할 수 있습니다.
메서드
| 메서드 | 매개변수 | 설명 |
|---|---|---|
controlLoad(elID, setting) | 요소 id, 옵션 객체 | 컨트롤 초기화(페이지 로드시 자동 호출됨) |
getValue(elID) | 요소 id | "시작일 ~ 종료일" 형식의 문자열 반환(예: '2026-07-01 ~ 2026-07-06'). 값이 비어있으면 해당 부분이 빈 문자열로 채워짐 |
setValue(elID, value) | 요소 id, 값 | value를 콤마(,)로 분리해 앞부분을 시작일, 뒷부 분을 종료일 입력창에 채움. 콤마가 없으면 같은 값을 시작일/종료일에 동일하게 채움(단일 날짜 지정) |
clear(elID, isControlLoad) | 요소 id | 시작일/종료일 입력창을 모두 빈 문자열로 초기화 |
getControl(elID) | 요소 id | 내부 관리 객체 객체 설정 반환. textbox1ID/textbox2ID로 생성된 시작일/종료일 입력창 id를 알 수 있음 |
showPopup(elID) | 요소 id | 공용 팝업을 해당 컨트롤 아래에 열기(달력 버튼 클릭과 동일한 동작) |
hidePopup() | - | 공용 팝업 닫기 |
setDateRange(startDate, endDate) | 'YYYY-MM-DD' 문자열 2개 | 팝업이 열려있는 상태에서 좌우 달력의 선택 날짜와 "선택기간: N일" 표시를 갱신함. 팝업 내부 상태만 바꾸며, 실제 입력창 값은 사용자가 "확인" 버튼을 눌러야 반영됨(코드로 값을 곧바로 채우고 싶다면 setValue를 사용) |
setLocale(elID, translations, control, options) | - | 다국어 로케일 훅. 현재 구현은 빈 함수(아무 동작 없음) |
팝업 안의 "올해/오늘까지/오늘/전일/주간/전주/당월/이전달/전년도/전전년도/1~4분기/상반기/하반기/월별 체크박스/기간 선택 취소/확인" 버튼들은 모두
setDateRange를 내부적으로 호출하는 전용 클릭 핸들러(_DatePeriodPicker_btnXxx_click)로 구현되어 있으며, 페이지 스크립트에서 직접 호출하도록 만들어진 공개 API는 아닙니다.
이벤트 (syn-events)
syn-events에 이벤트 이름을 배열로 지정하면, 페이지 스크립트의 event.{elID}_{이벤트명} 함수가 호출됩니다. DatePeriodPicker는 표준 DOM 이벤트 대신 아래 3개의 전용 이벤트를 사용합니다.
| 이벤트 | 호출 시점 | 콜백 인자 |
|---|---|---|
onselect | 팝업이 열린 상태에서 좌측(시작일) 또는 우측(종료일) 달력에서 날짜를 클릭할 때마다 | (elID, which, date) — which는 'startedAt' 또는 'endedAt', date는 선택한 날짜의 Date 객체 |
onreset | 팝업의 "기간 선택 취소" 버튼 클릭 시 | (elID, startValue, endValue) — 이 시점에는 두 값 모두 빈 문자열 |
onconfirm | 팝업의 "확인" 버튼 클릭 시(입력창에 값이 실제로 반영된 직후) | (elID, startValue, endValue) — 'YYYY-MM-DD' 형식 문자열 |
<syn_dateperiodpicker id="dtpSearchPeriod" syn-options="{}" syn-events="['onselect', 'onreset', 'onconfirm']"></syn_dateperiodpicker>
let $sample = {
event: {
dtpSearchPeriod_onselect(elID, which, date) {
syn.$l.eventLog('dtpSearchPeriod_onselect', `${which}: ${date}`);
},
dtpSearchPeriod_onreset(elID, startValue, endValue) {
syn.$l.eventLog('dtpSearchPeriod_onreset', `${startValue} ~ ${endValue}`);
},
dtpSearchPeriod_onconfirm(elID, startValue, endValue) {
syn.$l.eventLog('dtpSearchPeriod_onconfirm', `${startValue} ~ ${endValue}`);
}
}
}
추가로 알아둘 점:
- "확인" 버튼 클릭 시 시작일이 종료일보다 크면
syn.$w.alert('시작일자가 종료일자 보다 클 수 없습니다.')가 표시되고 팝업이 닫히지 않으며,onconfirm도 호출되지 않습니다. - 시작일/종료일 입력창에 키보드로 직접 값을 입력한 뒤 포커스를 벗어나면(blur), 시작일 > 종료일인 경우 자동으로 값이 서로 맞춰집니다(별도 이벤트 없음).
- 페이지에
<syn_dateperiodpicker>가 여러 개 있는 경우 팝업과 Pikaday 인스턴스가 공유되므로,onselect콜백에 전달되는elID는 내부 구현상 페이지에서 가장 먼저 로드된 컨트롤의 id로 고정됩니다(공유 팝업 생성 시점의 클로저를 그대로 사용하기 때문). 반면onreset/onconfirm의elID는 팝업을 실제로 열었던 컨트롤 id를 정확히 사용합니다. 페이지에 컨트롤이 1개뿐이라면 이 차이는 드러나지 않습니다.
참고
- 소스:
DatePeriodPicker.js,DatePeriodPicker.css - 이 컨트롤 전용 표준 샘플 페이지(
sample/uicontrol)는 아직 없습니다. 위 내용은DatePeriodPicker.js전체 소스 코드를 직접 읽어 확인한 사실이며, 실제 사용 마크업 스타일(value: 'month:3',startDataFieldID/endDataFieldID등)은qcn.groupware저장소의modules/bridal/wwwroot/bridal/view/HDS/BDL/BOD001.html실사용 예시를 참고했습니다(단, 그 예시에서 사용된belongID: ['MD01']배열 표기도 소스 코드상 실제로 지원되는 것을 확인했습니다). - 시작일/종료일 입력창 자체의 문자 입력 마스크·형식 검증 동작은
TextBox컨트롤(editType: 'date')과 동일합니다. - 예제는
example폴더, 사용 개요는 이 문서의 사용법 섹션를 참고하세요.