본문으로 건너뛰기

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(팝업에 프리셋 버튼이 내장되어 있음)

빠른 시작​

<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 버튼 데모
  • example/search.html : 목록 화면 조회 기간 실무 패턴 - 기본 기간(month:-3)으로 pageLoad 시 즉시 조회, _StartedAt/_EndedAt 문자열 비교로 시작일 > 종료일 검증

각 HTML은 같은 이름의 .js 파일과 짝을 이루며, 화면 하단 로그 영역에 syn.$l.eventLog로 동작 로그가 출력됩니다.

더 알아보기​

  • 상세 옵션·메서드·이벤트 표는 아래 API 참조 섹션 문서를 참고하세요.
  • 달력 팝업 자체의 세부 동작(연/월 이동 등)은 내부적으로 사용하는 Pikaday 라이브러리 문서를 참고하세요: https://github.com/Pikaday/Pikaday
  • 날짜 1개만 필요하다면 형제 컨트롤 DatePicker(syn.uicontrols.$datepicker)를 확인하세요.

실전 예제 페이지​

/uicontrols/DatePeriodPicker/example/ 경로의 예제를 아래 iframe에서 바로 확인할 수 있습니다.

basic.html​

events.html​

shorthand.html​

search.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
  • syn-events에 지정한 이벤트 이름 배열은 시작일/종료일 입력창 두 곳에 그대로 복사되며, 팝업에서 발생하는 onselect/onreset/onconfirm 이벤트를 페이지 스크립트로 전달하는 데 사용됩니다.
  • 페이지 안에서 <syn_dateperiodpicker>를 몇 개를 쓰더라도, 빠른 선택 버튼이 포함된 팝업(#divPeriodPicker)과 Pikaday 인스턴스 2개(시작일용/종료일용)는 페이지 전체에서 1세트만 공유됩니다. 버튼을 누른 컨트롤의 id가 팝업의 elID 속성에 기록되고, "확인"/"기간 선택 취소" 버튼 클릭 시 이 elID를 기준으로 어떤 컨트롤에 값을 반영할지 결정합니다.

Options (defaultSetting)​

옵션타입/기본값설명
elIDstring컨트롤 로드시 내부적으로 자동 채워짐(직접 지정할 필요 없음)
widthstring, 기본 '100%'컨트롤 전체 폭(참고용 값, 실제 폭은 생성된 입력창들의 CSS에 따름)
valuestring, 기본 ''초기값 축약 표기. 아래 "value 축약 표기" 표 참고
defaultDate / setDefaultDatePikaday 옵션 그대로 전달달력을 처음 열 때 표시할 기본 날짜
minDate / maxDateDate, 기본 null선택 가능한 최소/최대 날짜(Pikaday에 그대로 전달)
boundboolean, 기본 falsePikaday 옵션. 이 컨트롤은 팝업 표시/숨김을 자체 로직(showPopup/hidePopup)으로 제어하므로 기본값 false 사용
formatstring, 기본 'YYYY-MM-DD'Pikaday에 전달되는 날짜 포맷(moment 포맷 문자열)
ariaLabelstring, 기본 '날짜를 선택 하세요'달력 접근성 라벨
i18nobject월/요일 이름 등 한글 로케일 텍스트(기본값이 이미 한글로 설정되어 있어 보통 그대로 사용)
showWeekNumberboolean, 기본 false주차 번호 표시 여부
showMonthAfterYearboolean, 기본 true달력 헤더에 "년도 다음에 월" 순서로 표시
showDaysInNextAndPreviousMonthsboolean, 기본 true이전/다음 달 날짜를 회색으로 함께 표시
enableSelectionDaysInNextAndPreviousMonthsboolean, 기본 true이전/다음 달 날짜도 선택 가능하게 할지 여부
yearSuffixstring, 기본 '년'연도 뒤에 붙는 접미사
firstDaynumber, 기본 0한 주의 시작 요일(0=일요일)
numberOfMonthsnumber, 기본 1달력 하나에 동시에 표시할 월 수
startDataFieldIDstring, 기본 ''생성되는 시작일 입력창의 syn-datafield 값. 비우면 {elID}_StartedAt 사용
endDataFieldIDstring, 기본 ''생성되는 종료일 입력창의 syn-datafield 값. 비우면 {elID}_EndedAt 사용
startClassNamestring, 기본 'form-control'시작일 입력창에 적용할 CSS class
endClassNamestring, 기본 'form-control'종료일 입력창에 적용할 CSS class
dataTypestring, 기본 'string'다른 컨트롤과 동일한 관례로 정의만 되어 있으며, 이 컨트롤의 clear()는 값 형식과 무관하게 항상 빈 문자열로 초기화함(내부에서 별도로 참조하지 않음)
belongIDstring | array, 기본 null소속 그룹/프레임 식별자. 지정하면 생성되는 시작일/종료일 입력창의 syn-options에 그대로 전달됨
getter / setterboolean, 기본 false다른 컨트롤과 동일한 표준 옵션(정의되어 있으나 이 컨트롤 내부 로직에서 직접 참조하지는 않음)
controlTextstring, 기본 null컨트롤 표시명(다른 컨트롤과 동일한 관례)
validatorsarray, 기본 null폼 전송 검증 규칙(다른 컨트롤과 동일한 관례)
transactConfig / triggerConfigobject, 기본 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 폴더, 사용 개요는 이 문서의 사용법 섹션를 참고하세요.