반응형
해당 글에서는 Thymeleaf 내에서 JQuery DatePicker 라이브러리를 사용하는 방법에 대해서 공유합니다.
1) 라이브러리 선언하기
💡 jQuery 3.6.1과 jQuery-ui.css를 CDN 방식이 아닌 직접 다운로드 받는 방식으로 구성하였습니다. 해당 라이브러리 내의 Datepicker가 포함되어 있습니다.
<th:block layout:fragment="script">
<script th:inline="javascript" type="text/javascript" th:src="@{/lib/jquery-3.6.1.min.js}"></script>
<script th:inline="javascript" type="text/javascript" th:src="@{/lib/jquery-ui.min.js}"></script>
</th:block>
2) HTML 화면 구성
💡 HTML 화면에서는 input으로 구성된 datepicker와 버튼으로 구성된 이전 날짜인 prevDate, 이후 날짜인 postDate을 추가하였습니다.
<div style="flex-direction: row">
<button id="prevDate" onclick="chgDatePicker('prev')">◀️</button>
<label for="datepicker">
<input type="text" id="datepicker" style="text-align: center" readonly/>
</label>
<button id="postDate" onclick="chgDatePicker('post')" disabled>▶️</button>
</div>
3) JS 구성
1. DatePicker 옵션 설정
💡 기본적으로 format으로 "23.08.01(화)" 형태의 데이터 형태를 사용하며 한글 형태의 달력으로 구성하였습니다.
<!-- IN-line JS 영역-->
<script th:inline="javascript" type="text/javascript">
const datePickerOptions = {
dateFormat: "yy.mm.dd(D)",
maxDate: new Date(),
showOtherMonths: true, // 현재 월에 속하지 않는 날짜도 달력 위젯에 표시하도록 지시
selectOtherMonths: true, // 이전 월 및 다음 월의 날짜를 선택할 수 있도록 함
prevText: '이전 달',
nextText: '다음 달',
monthNames: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
monthNamesShort: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
dayNames: ['일', '월', '화', '수', '목', '금', '토'],
dayNamesShort: ['일', '월', '화', '수', '목', '금', '토'],
dayNamesMin: ['일', '월', '화', '수', '목', '금', '토'],
showMonthAfterYear: true,
yearSuffix: '년'
}
</script>
옵션 | 설명 |
dateFormat | 날짜 형식을 지정합니다. |
maxDate | 선택 가능한 최대 날짜를 지정합니다. |
showOtherMonths | 이전달, 다음달의 날짜를 표시합니다. |
selectOtherMonths | 이전달, 다음달의 날짜를 선택할 수 있도록 합니다. |
prevText | 이전 달 버튼의 텍스트를 지정합니다. |
nextText | 다음 달 버튼의 텍스트를 지정합니다. |
monthNames | 월 이름을 지정합니다. |
monthNamesShort | 월 이름의 약어를 지정합니다. |
dayNames | 요일 이름을 지정합니다. |
dayNamesShort | 요일 이름의 약어를 지정합니다. |
dayNamesMin | 요일 이름의 최소 텍스트를 지정합니다. |
showMonthAfterYear | 년도 뒤에 월을 표시합니다. |
yearSuffix | 년도 뒤에 추가될 텍스트를 지정합니다 (예: 2022년). |
2. DatePicker 그려주기
💡 화면이 다 그려진 이후에 datepicker를 찾아서 옵션을 주었고 달력의 날짜를 선택하였을때 onSelect 이벤트가 수행되도록 등록을 하였고 마지막으로 구성한 데이터를 input 값에 세팅하도록 구성하였습니다.
(단 해당 부분에서는 오늘을 선택하면 다음날을 선택하지 못하도록 비활성화 기능을 추가하였습니다)
<!-- IN-line JS 영역-->
<script th:inline="javascript" type="text/javascript">
/**
* 화면이 렌더링 된 이후에 수행됩니다.
*/
$(document).ready(function () {
const todayDate = new Date();
const datePicker = $("#datepicker");
// DatePicker 옵션 설정하고 선택하였을때 이벤트 동작 처리를 추가합니다.
datePicker.datepicker(
Object.assign({}, datePickerOptions, {
// DatePicker 선택 하였을때 처리
onSelect: (dataString, selectedAttr) => {
// 선택한게 오늘이면 다음 버튼을 비활성화 시킵니다
if (todayDate.getFullYear() === selectedAttr.currentYear &&
todayDate.getMonth() === selectedAttr.currentMonth &&
todayDate.getDate() === selectedAttr.currentDay) {
$('#postDate').attr("disabled", true);
} else {
$('#postDate').attr("disabled", false);
}
},
})
);
// UI 날짜를 지정합니다.
datePicker.datepicker("setDate", todayDate);
});
</script>
3. 이전날짜 / 다음 날짜
💡 chgDatePicker()는 이전 버튼과 이후 버튼을 눌렀을때 각각 다른 처리를 하도록 구성하였습니다.
- 이전 버튼을 눌렀을 경우 datepicker 입력된 날짜를 가져와서 -1일을 뺍니다.
- 이후 버튼을 눌렀을 경우 오늘 이후 날짜로 넘기려고 하는 경우 경고 메시지를 띄어주며 아닐 경우는 datepicker 입력된 날짜를 가져와서 +1일을 더합니다
💡 datePickerFormatting()는 date 값을 전달 받아서 DatePicker에서 사용하는 형태로 formatting 해서 반환해주는 기능을 수행하는 함수입니다.
<!-- IN-line JS 영역-->
<script th:inline="javascript" type="text/javascript">
/**
* DatePicker 전날/이후 날짜 선택
* @param type
*/
const chgDatePicker = (type) => {
const today = new Date(); // 오늘 날짜
let datePicker = $("#datepicker"); // DatePicker 에서 선택된 날짜
let datePickerToDate = new Date(datePicker.val()); // DatePicker 에서 선택되어 Date 타입으로 변경된 날짜
// [CASE1] 이전 버튼을 눌렀을 경우
if (type === "prev") {
datePickerToDate.setDate(datePickerToDate.getDate() - 1); // DatePicker 날짜를 하루 뺍니다.
datePicker.val(datePickerFormatting(datePickerToDate)); // 화면상에 보이는 DatePicker 날짜를 변경합니다.
$('#postDate').attr("disabled", false) // 이전 버튼을 누르면 disalbed가 사라집니다.
}
// [CASE2] 이후 버튼을 눌렀을 경우
else if (type === "post") {
// [CASE2-1] 오늘 이후 날짜는 처리하지 않습니다. (년 월 일에 비교를 합니다)
if (datePickerToDate.getFullYear() === today.getFullYear()
&& datePickerToDate.getMonth() === today.getMonth()
&& datePickerToDate.getDate() === today.getDate()) {
alert('오늘 이후 날짜는 선택할 수 없습니다.');
$('#postDate').attr("disabled", true) // 이후날짜 버튼 disabled
}
// [CASE2-2] 오늘 이후 날짜는 변경합니다.
else {
datePickerToDate.setDate(datePickerToDate.getDate() + 1); // DatePicker 날짜를 하루 더합니다.
datePicker.val(datePickerFormatting(datePickerToDate)); // 화면상에 보이는 DatePicker 날짜를 변경합니다.
}
}
}
/**
* yyyy.mm.dd(요일) 형식으로 포맷팅
* @param {Date} date
* @return {string}
*/
const datePickerFormatting = (date) => {
return date.getFullYear() + '.' + (date.getMonth() + 1).toString().padStart(2, '0') + '.' + date.getDate().toString().padStart(2, '0') + '(' + ['일', '월', '화', '수', '목', '금', '토'][date.getDay()] + ')';
}
</script>
4) 작업 결과
1. 작업 화면
1.1. 초기 화면
1.2. 좌측 이동
1.3. 우측 이동(오늘 이후 값)
2. 최종 소스코드
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{common/layouts/defaultLayout}"
layout:fragment="content"
>
<!-- IN-line JS 영역-->
<script th:inline="javascript" type="text/javascript">
const datePickerOptions = {
dateFormat: "yy.mm.dd(D)",
maxDate: new Date(),
showOtherMonths: true, // 현재 월에 속하지 않는 날짜도 달력 위젯에 표시하도록 지시
selectOtherMonths: true, // 이전 월 및 다음 월의 날짜를 선택할 수 있도록 함
prevText: '이전 달',
nextText: '다음 달',
monthNames: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
monthNamesShort: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
dayNames: ['일', '월', '화', '수', '목', '금', '토'],
dayNamesShort: ['일', '월', '화', '수', '목', '금', '토'],
dayNamesMin: ['일', '월', '화', '수', '목', '금', '토'],
showMonthAfterYear: true,
yearSuffix: '년'
}
/**
* 화면이 렌더링 된 이후에 수행됩니다.
*/
$(() => {
const todayDate = new Date();
const datePicker = $("#datepicker");
// DatePicker 옵션 설정하고 선택하였을때 이벤트 동작 처리를 추가합니다.
datePicker.datepicker(
Object.assign({}, datePickerOptions, {
// DatePicker 선택 하였을때 처리
onSelect: (dataString, selectedAttr) => {
// 선택한게 오늘이면 다음 버튼을 비활성화 시킵니다
if (todayDate.getFullYear() === selectedAttr.currentYear &&
todayDate.getMonth() === selectedAttr.currentMonth &&
todayDate.getDate() === selectedAttr.currentDay) {
$('#postDate').attr("disabled", true);
} else {
$('#postDate').attr("disabled", false);
}
},
})
);
// UI 날짜를 지정합니다.
datePicker.datepicker("setDate", todayDate);
});
/**
* DatePicker 전날/이후 날짜 선택
* @param type
*/
const chgDatePicker = (type) => {
const today = new Date(); // 오늘 날짜
let datePicker = $("#datepicker"); // DatePicker 에서 선택된 날짜
let datePickerToDate = new Date(datePicker.val()); // DatePicker 에서 선택되어 Date 타입으로 변경된 날짜
// [CASE1] 이전 버튼을 눌렀을 경우
if (type === "prev") {
datePickerToDate.setDate(datePickerToDate.getDate() - 1); // DatePicker 날짜를 하루 뺍니다.
datePicker.val(datePickerFormatting(datePickerToDate)); // 화면상에 보이는 DatePicker 날짜를 변경합니다.
$('#postDate').attr("disabled", false) // 이전 버튼을 누르면 disalbed가 사라집니다.
}
// [CASE2] 이후 버튼을 눌렀을 경우
else if (type === "post") {
// [CASE2-1] 오늘 이후 날짜는 처리하지 않습니다. (년 월 일에 비교를 합니다)
if (datePickerToDate.getFullYear() === today.getFullYear()
&& datePickerToDate.getMonth() === today.getMonth()
&& datePickerToDate.getDate() === today.getDate()) {
alert('오늘 이후 날짜는 선택할 수 없습니다.');
$('#postDate').attr("disabled", true) // 이후날짜 버튼 disabled
}
// [CASE2-2] 오늘 이후 날짜는 변경합니다.
else {
datePickerToDate.setDate(datePickerToDate.getDate() + 1); // DatePicker 날짜를 하루 더합니다.
datePicker.val(datePickerFormatting(datePickerToDate)); // 화면상에 보이는 DatePicker 날짜를 변경합니다.
}
}
}
/**
* yyyy.mm.dd(요일) 형식으로 포맷팅
* @param {Date} date
* @return {string}
*/
const datePickerFormatting = (date) => {
return date.getFullYear() + '.' + (date.getMonth() + 1).toString().padStart(2, '0') + '.' + date.getDate().toString().padStart(2, '0') + '(' + ['일', '월', '화', '수', '목', '금', '토'][date.getDay()] + ')';
};
</script>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div style="background-color: white">
<div>
<!-- ====================================== DatePicker 영역================================================= -->
<div style="flex-direction: row">
<button id="prevDate" onclick="chgDatePicker('prev')">◀️</button>
<label for="datepicker">
<input type="text" id="datepicker" style="text-align: center" readonly/>
</label>
<button id="postDate" onclick="chgDatePicker('post')" disabled>▶️</button>
</div>
</div>
</div>
</body>
</html>
오늘도 감사합니다. 😀
반응형
'Javascript & Typescript > 라이브러리' 카테고리의 다른 글
[JS] Toast UI Grid 설정 및 응용하기 : Thymeleaf 기반 구성 (0) | 2023.01.05 |
---|---|
[JS/Library] Webpack 이해하기 - 1 : 주요 용어 (0) | 2022.11.04 |
[JS] Next.js 이해하기(정의, 사용목적) (0) | 2022.08.15 |
[JS/library] Prettier 환경설정 방법 (3) | 2022.02.01 |