본문으로 건너뛰기

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 버튼 데모

각 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.$textboxeditType: '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/onconfirmelID는 팝업을 실제로 열었던 컨트롤 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 폴더, 사용 개요는 이 문서의 사용법 섹션를 참고하세요.