관리 메뉴

거니의 velog

(2) 공통 모듈 : FullCalender 본문

대덕인재개발원/대덕인재개발원_final project

(2) 공통 모듈 : FullCalender

Unlimited00 2023. 12. 8. 16:00


[Oracle SQL]

DROP TABLE CALENDAR CASCADE CONSTRAINTS;
DROP SEQUENCE CALENDAR_NO_SEQ;

CREATE TABLE CALENDAR (
	CALENDAR_NO NUMBER	NOT NULL PRIMARY KEY,
	CALENDAR_TITLE	VARCHAR2(200)	NOT NULL,
	CALENDAR_MEMO	VARCHAR2(500),
	CALENDAR_START	DATE,
	CALENDAR_END	DATE
);

CREATE SEQUENCE CALENDAR_NO_SEQ
    START WITH 1
    INCREMENT BY 1;

commit;

INSERT INTO CALENDAR VALUES (CALENDAR_NO_SEQ.NEXTVAL, '새해', '일정좀 넣어 봐유', SYSDATE, SYSDATE);
INSERT INTO CALENDAR VALUES (CALENDAR_NO_SEQ.NEXTVAL, '복', '일정좀 넣어 봐유', '2023/12/10', '2023/12/10');
INSERT INTO CALENDAR VALUES (CALENDAR_NO_SEQ.NEXTVAL, '많이', '일정좀 넣어 봐유', '2023/12/14', '2023/12/14');
INSERT INTO CALENDAR VALUES (CALENDAR_NO_SEQ.NEXTVAL, '받으세요', '일정좀 넣어 봐유', '2023/12/18', '2023/12/18');
INSERT INTO CALENDAR VALUES (CALENDAR_NO_SEQ.NEXTVAL, '해피뉴이어', '일정좀 넣어 봐유', '2023/12/20', '2023/12/22');

commit;

select * from CALENDAR;

[CalendarVO.java]

package kr.or.ddit.vo;

import lombok.Data;

@Data
public class CalendarVO {

	private int calendarNo;
	private String calendarTitle;
	private String calendarMemo;
	private String calendarStart;
	private String calendarEnd;
	
}

[ICalenderService.java]

package kr.or.ddit.service;

import java.util.List;

import kr.or.ddit.ServiceResult;
import kr.or.ddit.vo.CalendarVO;

public interface ICalenderService {

	public List<CalendarVO> getCalender();
	public ServiceResult insertCal(CalendarVO calendarVO);
	public ServiceResult deleteCal(int calendarNo);
	public ServiceResult updateCal(CalendarVO calendarVO);

}

[CalenderServiceImpl.java]

package kr.or.ddit.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import kr.or.ddit.ServiceResult;
import kr.or.ddit.mapper.ICalenderMapper;
import kr.or.ddit.service.ICalenderService;
import kr.or.ddit.vo.CalendarVO;

@Service
public class CalenderServiceImpl implements ICalenderService {

	@Inject
	private ICalenderMapper calenderMapper;
	
	@Override
	public List<CalendarVO> getCalender() {
		return calenderMapper.getCalender();
	}

	@Override
	public ServiceResult insertCal(CalendarVO calendarVO) {
		ServiceResult result = null;
		
		int status = calenderMapper.insertCal(calendarVO);
		if(status > 0) { // 캘린더 등록이 성공했을 때
			result = ServiceResult.OK;
		}else { // 캘린더 등록이 실패했을 때
			result = ServiceResult.FAILED;
		}
		
		return result;
	}

	@Override
	public ServiceResult deleteCal(int calendarNo) {
		ServiceResult result = null;
		
		int status = calenderMapper.deleteCal(calendarNo);
		if(status > 0) { // 캘린더 삭제가 성공했을 때
			result = ServiceResult.OK;
		}else { // 캘린더 삭제가 실패했을 때
			result = ServiceResult.FAILED;
		}
		
		return result;
	}

	@Override
	public ServiceResult updateCal(CalendarVO calendarVO) {
		ServiceResult result = null;
		
		int status = calenderMapper.updateCal(calendarVO);
		if(status > 0) { // 캘린더 수정이 성공했을 때
			result = ServiceResult.OK;
		}else { // 캘린더 수정이 실패했을 때
			result = ServiceResult.FAILED;
		}
		
		return result;
	}

}

[ICalenderMapper.java]

package kr.or.ddit.mapper;

import java.util.List;

import kr.or.ddit.vo.CalendarVO;

public interface ICalenderMapper {

	public List<CalendarVO> getCalender();
	public int insertCal(CalendarVO calendarVO);
	public int deleteCal(int calendarNo);
	public int updateCal(CalendarVO calendarVO);

}

[calenderMapper_SQL.xml]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.ICalenderMapper">
	
	<select id="getCalender" resultType="calendarVO">
		SELECT
		    calendar_no,
		    calendar_title,
		    calendar_memo,
		    calendar_start,
		    calendar_end
		FROM
		    calendar
	</select>
	
	<insert id="insertCal" parameterType="calendarVO">
		INSERT INTO calendar (
		    calendar_no,
		    calendar_title,
		    calendar_memo,
		    calendar_start,
		    calendar_end
		) VALUES (
		    calendar_no_seq.nextval,
		    #{calendarTitle},
		    #{calendarMemo},
		    #{calendarStart},
		    #{calendarEnd}
		)
	</insert>
	
	<delete id="deleteCal" parameterType="int">
		DELETE FROM calendar 
		WHERE 
		calendar_no = #{calendarNo}
	</delete>
	
	<update id="updateCal" parameterType="calendarVO">
		UPDATE calendar
		SET
		    calendar_title = #{calendarTitle},
		    calendar_memo = #{calendarMemo},
		    calendar_start = #{calendarStart},
		    calendar_end = #{calendarEnd}
		WHERE
		    calendar_no = #{calendarNo}
	</update>
	
</mapper>

[mybatisAlias.xml]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
	
	<typeAliases>
		<typeAlias type="kr.or.ddit.vo.CalendarVO" alias="calendarVO"/>
	</typeAliases>
	
</configuration>

[ServiceResult.java]

package kr.or.ddit;

public enum ServiceResult {

	OK, FAILED, EXIST, NOTEXIST
	
}

[calList.jsp]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>CALENDAR</title>
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
		<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.css">
		<script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/locales-all.js"></script>
		<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
  		<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
  		<style type="text/css">
  			#calender a {
  				text-decoration: none!important;
  				color: #333!important;
  			}
  			#calender h2 {
  				font-weight: bold!important;
  			}
  			#calender .fc-daygrid-day-frame {
  				cursor: pointer;
  				transition: all 0.2s;
  			}
  			#calender .fc-daygrid-day-frame:hover {
  				background-color: #eee;
  			}
		    #calender .fc-event-time {
		    	display: none;
		    }
		    
		    #calModal label {
		    	width: 100%!important; 
		    	margin-bottom: 10px!important;
		    }
		    
  			.tooltip-title {
  				color: white;
		    }
		    .tooltip-memo {
		    	color: black;
		    	background-color: white;
		    }
  		</style>
  		
	</head>
	<body>
		<c:if test="${not empty message }">
			<script type="text/javascript">
				alert("${message}");
				<c:remove var="message" scope="request"/>
				<c:remove var="message" scope="session"/>
			</script>
		</c:if>
		
		<div id="calender"></div>
		
		<!-- The Modal -->
		<div class="modal fade" id="calModal">
		    <div class="modal-dialog modal-lg modal-dialog-centered">
		        <div class="modal-content">
		
		            <!-- Modal Header -->
		            <div class="modal-header">
		                <h4 class="modal-title">일정 등록</h4>
		                <button type="button" class="btn-close initBtn" data-bs-dismiss="modal"></button>
		            </div>
		
		            <!-- Modal body -->
		            <div class="modal-body">
		                <form id="calForm" name="calForm" action="/cal/insertCal.do" method="post">
		                	<label for="calendarTitle">
		                		일정명
			                	<input class="form-control" type="text" id="calendarTitle" name="calendarTitle" value="${calendarVO.calendarTitle }" />
		                	</label>
		                	<label for="calendarMemo">
		                		일정 내용
			                	<textarea class="form-control" id="calendarMemo" name="calendarMemo" style="height: 300px;" wrap="soft">${calendarVO.calendarMemo }</textarea>
		                	</label>
		                	<label for="calendarStart">
		                		시작일
			                	<input id="calendarStart" name="calendarStart" class="form-control" type="date" value="${calendarVO.calendarStart }" />
		                	</label>
		                	<label for="calendarEnd">
		                		종료일
			                	<input id="calendarEnd" name="calendarEnd" class="form-control" type="date" value="${calendarVO.calendarEnd }" />
		                	</label>
		                	<button type="button" id="insertCal" class="btn btn-primary">일정 등록</button>
		                </form>
		            </div>
		
		            <!-- Modal footer -->
		            <div class="modal-footer">
		                <button type="button" class="btn btn-danger initBtn" data-bs-dismiss="modal">Close</button>
		            </div>
		
		        </div>
		    </div>
		</div>
	</body>
	
	<script type="text/javascript">
	
		// 전역 변수
		var currentTooltip;
		
		document.addEventListener('DOMContentLoaded', function(){
			var calendarEl = document.getElementById('calender');
			var calendar = new FullCalendar.Calendar(calendarEl, {
				initialView : 'dayGridMonth',
				locale : 'ko', // 한국어 설정
				headerToolbar: {
	        	    left: 'prevYear,prev,next,nextYear today',
	        	    center: 'title',
	        	    right: 'dayGridMonth,dayGridWeek,dayGridDay'
	        	},
	        	navLinks: true, // 요일이랑 날짜 클릭 시 일이나 주단위 보여주는 화면으로 넘어감
	        	editable: true, // 드래그해서 수정 가능한지. 길게 확장도 가능
	        	dayMaxEvents: true, // +more 표시 전 최대 이벤트 갯수. true는 셀 높이에 의해 결정
	        	selectable : true, // 캘린더에서 날짜 영역을 선택할 수 있는지 여부를 결정
	        	droppable : true, // 외부 요소나 다른 캘린더 이벤트 등을 캘린더 영역에 끌어서 떨어뜨릴 수 있는지 여부를 결정
	        	events : [
	        		<c:forEach var="vo" items="${calendarList}">
	                    {
	                    	calendarNo: '<c:out value="${vo.calendarNo}"/>',
	                        title: '<c:out value="${vo.calendarTitle}"/>',
	                        start: '<c:out value="${vo.calendarStart}"/>',
	                        end: '<c:out value="${vo.calendarEnd}"/>',
	                        memo: `<c:out value="${vo.calendarMemo}"/>`,
	                        color: '#' + Math.round(Math.random() * 0xffffff).toString(16)
	                    },
                	</c:forEach>
	        	],
	        	dateClick: function(info) {
	        		// 클릭된 날짜 정보 출력
	        	    console.log('Clicked on: ' + info.dateStr);

	        	    // 여기에 클릭된 날짜에 대한 추가 동작을 구현할 수 있습니다.
	        	    // 예를 들어, 모달 창 열기, 이벤트 추가 등의 동작을 수행할 수 있습니다.
	        	    $("#calModal #calendarTitle").val("");
	        	    $("#calModal #calendarStart").val("");
	        	    $("#calModal #calendarEnd").val("");
	        	    $("#calModal #calendarMemo").val("");
	        	    
	        	    // 등록 버튼의 스타일을 파란색으로 변경
	        	    $("#insertCal")
	        	        .removeClass("btn-danger font-weight-bold")
	        	        .addClass("btn-primary");

	        	    $("#calModal").modal("show");
	        	    $(".modal-header .modal-title").html("<strong style='color: red;'>일간</strong> 일정 등록");
	        	    $("#calModal #calendarStart").val(info.dateStr);
	        	    $("#calModal #calendarEnd").val(info.dateStr);
	            },
	            select: function(info) {
	                // 선택된 날짜 범위 정보 출력
	                console.log('Selected from: ' + info.startStr + ' to: ' + info.endStr);

	                // 여기에 선택된 날짜 범위에 대한 추가 동작을 구현할 수 있습니다.
	                // 예를 들어, 모달 창 열기, 이벤트 추가 등의 동작을 수행할 수 있습니다.
	                
	             	// info.end를 Moment.js 객체로 변환
				    var momentEnd = moment(info.end);
				
				    // Moment.js 객체인 경우에만 clone 메서드 사용
				    if (momentEnd.isValid()) {
				        var modifiedEnd = momentEnd.clone().subtract(1, 'days');
				        var formattedDate = modifiedEnd.format('YYYY-MM-DD');
				        console.log('Modified end date: ' + formattedDate);
				
				        // 여기에서 수정된 날짜를 사용하여 추가 작업 수행
				        $("#calModal #calendarTitle").val("");
		                $("#calModal #calendarStart").val("");
		                $("#calModal #calendarEnd").val("");
		                $("#calModal #calendarMemo").val("");
				        
				        $("#calModal").modal("show");
				        $(".modal-header .modal-title").html("<strong style='color: blue;'>주간</strong> 일정 등록");
				        $("#calModal #calendarStart").val(info.startStr);
				        $("#calModal #calendarEnd").val(formattedDate);
				    } else {
				        console.error('info.end is not a valid Moment.js object');
				    }
	            },
	            selectMinDistance: 5, // 기본값은 0입니다. 원하는 값으로 조정하세요.
	            eventDrop: function(info) {
	                // 드래그한 이벤트의 정보 출력
	                console.log('Event dropped: ' + info.event.title);
	                console.log('Calendar No: ' + info.event.extendedProps.calendarNo);
	                console.log('New start date: ' + info.event.startStr);
	                console.log('New end date: ' + info.event.endStr);
	                
	             	// 추가: 드래그된 이벤트의 title과 memo 값 출력
	                console.log('Event title: ' + info.event.title);
	                console.log('Event memo: ' + info.event.extendedProps.memo);
	                
	             	// info.event.startStr와 info.event.endStr는 ISO 형식의 날짜 문자열입니다.
	                var startDate = new Date(info.event.startStr);
	                var endDate = new Date(info.event.endStr);
	                
	                console.log("startDate : " + startDate);
	                console.log("endDate : " + endDate);
	                
	                if(endDate == 'Invalid Date') {
	                	endDate = startDate;
	                }
	                
	                if(startDate != endDate){
		                // 하루 뒤로 미룸
		                startDate.setDate(startDate.getDate() + 1);
		                endDate.setDate(endDate.getDate() + 1);
	                }else {
	                	endDate.setDate(endDate.getDate() + 1);
	                }

	                // 날짜를 'YYYY-MM-DD' 형식으로 변환
	                var formattedStartDate = startDate.toISOString().split('T')[0];
	                var formattedEndDate = endDate.toISOString().split('T')[0];

	                console.log('New start date: ' + formattedStartDate);
	                console.log('New end date: ' + formattedEndDate);

	                // 여기에 드래그한 이벤트에 대한 추가 동작을 구현할 수 있습니다.
	                // 예를 들어, 이벤트의 업데이트, 모달 창 열기 등의 동작을 수행할 수 있습니다.
	                $("#calForm #calendarNo").remove();
	                $("#calForm").prepend("<input id='calendarNo' name='calendarNo' type='hidden' value='"+info.event.extendedProps.calendarNo+"' />");
	                
	                $("#calForm #calendarTitle").remove();
	                $("#calForm label[for=calendarTitle]").prepend("<input id='calendarTitle' name='calendarTitle' type='hidden' value='"+info.event.title+"' />");
	                
	                $("#calForm #calendarMemo").remove();
	                $("#calForm label[for=calendarStart]").prepend("<input id='calendarMemo' name='calendarMemo' type='hidden' value='"+info.event.extendedProps.memo+"' />");
	                
	                $("#calForm #calendarStart").remove();
	                $("#calForm label[for=calendarStart]").prepend("<input id='calendarStart' name='calendarStart' type='hidden' value='"+formattedStartDate+"' />");
	                
	                $("#calForm #calendarEnd").remove();
	                $("#calForm label[for=calendarEnd]").prepend("<input id='calendarEnd' name='calendarEnd' type='hidden' value='"+formattedEndDate+"' />");
	                
	                $("#calForm").attr("action", "/cal/updateCal.do");
	                $("#calForm").submit();
	            },
	            eventClick: function(info) {
	            	// 클릭된 이벤트의 정보 출력
	                console.log('클릭한 이벤트: ', info.event);

	                // 시작일 및 종료일이 null이 아닌지 확인
	                var startDate = info.event.start ? moment(info.event.start).format('YYYY-MM-DD') : "";
	                var endDate = info.event.end ? moment(info.event.end).subtract(1, 'days').format('YYYY-MM-DD') : "";

	                // 종료일이 없으면 시작일로 설정
	                if (!endDate) {
	                    endDate = startDate;
	                }

	                console.log("일정 시작 날짜: " + startDate);
	                console.log("일정 종료 날짜: " + endDate);

	                // extendedProps가 존재하고 그 안에 calendarMemo가 있는지 확인
	                var calendarMemo = info.event.extendedProps && info.event.extendedProps.memo
	                    ? info.event.extendedProps.memo
	                    : "";

	                console.log("일정 내용: " + calendarMemo);
	                
	             	// 캘린더 번호 값을 숨겨진 입력 필드에 설정
	             	// 폼 태그 안쪽에 prepend 해보자. 안되겠다...
	             	$("#calForm #calendarNo").remove();
	             	$("#calForm").prepend("<input id='calendarNo' name='calendarNo' type='hidden' value='"+info.event.extendedProps.calendarNo+"' />");

	                // 입력 요소를 읽기 전용으로 설정
	                $("#calModal #calendarTitle").prop("readonly", true);
	                $("#calModal #calendarStart").prop("readonly", true);
	                $("#calModal #calendarEnd").prop("readonly", true);
	                $("#calModal #calendarMemo").prop("readonly", true);

	                // 버튼 텍스트 변경 및 클래스 추가
	                $("#insertCal")
	                    .text("수정")
	                    .removeClass("btn-primary")
	                    .removeClass("btn-danger")
	                    .addClass("btn-warning");
	                
	                // 삭제 버튼 추가
	                var removeBtn = "<button type='button' id='deleteCal' class='btn btn-danger'>삭제</button>";
	                $("#calForm").append(removeBtn);

	                // 모달 창 열기
	                $("#calModal #calendarTitle").val(info.event.title);
	                $("#calModal #calendarStart").val(startDate);
	                $("#calModal #calendarEnd").val(endDate);
	                $("#calModal #calendarMemo").val(calendarMemo);

	                $("#calModal").modal("show");
	                $(".modal-header .modal-title").html("<strong style='color: green;'>일정 확인</strong>");
	            },
	            eventMouseEnter: function (info) {
	                // 툴팁 내용 생성
	                var tooltipContent = '<span class="tooltip-title">' + info.event.title + '</span><br /><span class="tooltip-memo">' + info.event.extendedProps.memo + '</span>';

	                // 부트스트랩 툴팁 적용
	                $(info.el).tooltip({
	                    title: tooltipContent,
	                    html: true,
	                    placement: 'top',
	                    trigger: 'hover focus', // 툴팁을 호버 또는 포커스할 때만 표시
	                }).tooltip('show');
	            },
	            eventMouseLeave: function (info) {
	                // 툴팁 숨기기
	                $(info.el).tooltip('hide');
	            }
			});
			
			calendar.render();
		});
		
		$(function() {
		    var calForm = $("#calForm"); // 등록/수정 폼 엘리먼트
		    var insertCal = $("#insertCal"); // 등록/수정 버튼 엘리먼트
		    var initBtn = $(".initBtn"); // 초기화 버튼 엘리먼트
		    
		    var calendarTitleEl = $("#calendarTitle");
		    var calendarMemoEl = $("#calendarMemo");
		    var calendarStartEl = $("#calendarStart");
		    var calendarEndEl = $("#calendarEnd");
		    
		    initBtn.on("click", function(){
		    	
		    	$("#calModal #calendarTitle").prop("readonly", false);
                $("#calModal #calendarStart").prop("readonly", false);
                $("#calModal #calendarEnd").prop("readonly", false);
                $("#calModal #calendarMemo").prop("readonly", false);
                
                $("#calModal #calendarTitle").val("");
                $("#calModal #calendarStart").val("");
                $("#calModal #calendarEnd").val("");
                $("#calModal #calendarMemo").val("");
                
                $("#calForm #calendarNo").remove();
                $("#calForm #deleteCal").remove();
                
                calForm.attr("action", "/cal/insertCal.do");
                
             	// 버튼 텍스트 변경 및 클래스 추가
                $("#insertCal")
                    .text("일정 등록")
                    .removeClass("btn-warning")
                    .removeClass("btn-secondary")
                    .addClass("btn-primary");
             	
		    });
		    
		    $(document).on("click", "#deleteCal", function() {
		    	calForm.attr("action", "/cal/deleteCal.do");
		    	calForm.submit();
		    });

		    insertCal.on("click", function() {
		    	
		        var calendarTitle = calendarTitleEl.val();
		        var calendarMemo = calendarMemoEl.val();
		        var calendarStart = calendarStartEl.val();
		        var calendarEnd = calendarEndEl.val();

		        if ($(this).text() == "일정 등록") {
		        	
		            $("#calForm #calendarNo").remove();
		            
		            if (!calendarTitle) {
		                alert("제목을 입력해 주세요");
		                calendarTitleEl.focus();
		                return false;
		            }
		            if (!calendarMemo) {
		                alert("내용을 입력해 주세요");
		                calendarMemoEl.focus();
		                return false;
		            }
		            if (!calendarStart) {
		                alert("시작일을 입력해 주세요");
		                calendarStartEl.focus();
		                return false;
		            }
		            if (!calendarEnd) {
		                alert("종료일을 입력해 주세요");
		                calendarEndEl.focus();
		                return false;
		            }

		            // 종료일에 하루 추가
		            var momentStart = moment(calendarStart);
		            var momentEnd = moment(calendarEnd);

		            if (momentStart.isValid() && momentEnd.isValid()) {
		                // 시작일과 종료일이 같은 경우 예외 처리
		                if (momentStart.isSame(momentEnd, 'day')) {
		                    // 여기에 시작일과 종료일이 같은 경우의 예외 처리를 추가할 수 있습니다.
		                    calForm.submit();
		                }

		                // 종료일에 하루 추가
		                var modifiedEnd = momentEnd.clone().add(1, 'days');
		                var formattedDate = modifiedEnd.format('YYYY-MM-DD');
		                console.log('Modified end date: ' + formattedDate);
		                calendarEndEl.val(formattedDate);

		                // 유효성 검사 통과 시 폼 제출 진행
		                calForm.submit();
		            } else {
		                console.error('calendarStart 또는 calendarEnd가 유효한 Moment.js 객체가 아닙니다');
		                // 유효하지 않은 경우에 대한 처리를 추가할 수 있습니다.
		                // 예: alert("시작일 또는 종료일이 유효하지 않습니다");
		                return false;
		            }
		        } else if ($(this).text() == "수정") {
		        	$(".modal-header .modal-title").html("<strong style='color: red; font-weight: bold;'>일정 수정</strong>");
		            
		            // readonly 속성 해제
		            $("#calModal input, #calModal textarea").prop("readonly", false);
		            
		            // 삭제 버튼 제거
		            $("#calForm #deleteCal").remove();
		            
		            // 버튼 텍스트 및 스타일 변경
		            insertCal.text("저장")
		                .removeClass("btn-primary")
		                .removeClass("btn-warning")
		                .addClass("btn-secondary font-weight-bold"); // 빨간색, 두꺼운 글씨체
		                
		            return false;
		        }
		        
		     	// 저장 버튼 클릭 시 폼 제출
	            if ($(this).text() == "저장") {
	                // 수정 버튼이 클릭된 경우의 동작
	                var calendarTitle = calendarTitleEl.val();
	                var calendarMemo = calendarMemoEl.val();
	                var calendarStart = calendarStartEl.val();
	                var calendarEnd = calendarEndEl.val();
	                
	                if (!calendarTitle) {
	                    alert("제목을 입력해 주세요");
	                    calendarTitleEl.focus();
	                    return false;
	                }
	                if (!calendarMemo) {
	                    alert("내용을 입력해 주세요");
	                    calendarMemoEl.focus();
	                    return false;
	                }
	                if (!calendarStart) {
	                    alert("시작일을 입력해 주세요");
	                    calendarStartEl.focus();
	                    return false;
	                }
	                if (!calendarEnd) {
	                    alert("종료일을 입력해 주세요");
	                    calendarEndEl.focus();
	                    return false;
	                }
	                
	             	// 종료일에 하루 추가
		            var momentStart = moment(calendarStart);
		            var momentEnd = moment(calendarEnd);

		            if (momentStart.isValid() && momentEnd.isValid()) {
		                // 시작일과 종료일이 같은 경우 예외 처리
		                if (momentStart.isSame(momentEnd, 'day')) {
		                    // 여기에 시작일과 종료일이 같은 경우의 예외 처리를 추가할 수 있습니다.
		                    calForm.submit();
		                }

		                // 종료일에 하루 추가
		                var modifiedEnd = momentEnd.clone().add(1, 'days');
		                var formattedDate = modifiedEnd.format('YYYY-MM-DD');
		                console.log('Modified end date: ' + formattedDate);
		                calendarEndEl.val(formattedDate);

		                // 유효성 검사 통과 시 폼 제출 진행
		                calForm.submit();
		            } else {
		                console.error('calendarStart 또는 calendarEnd가 유효한 Moment.js 객체가 아닙니다');
		                // 유효하지 않은 경우에 대한 처리를 추가할 수 있습니다.
		                // 예: alert("시작일 또는 종료일이 유효하지 않습니다");
		                return false;
		            }

	                // 유효성 검사 통과 시 폼 제출 진행
	                calForm.attr("action", "/cal/updateCal.do");
	                calForm.submit();
	            }
		    });
		    
		    calendarStartEl.on("change", function(event){
		    	
		    	var calendarStart = calendarStartEl.val();
		    	console.log("calendarStart : " + calendarStart);
		    	var calendarEnd = calendarEndEl.val();
		    	console.log("calendarEnd : " + calendarEnd);
		    	var currentValue = event.target.value;
		    	console.log("currentValue : " + currentValue);
		    	
		    	if($(".modal-header .modal-title strong").text().trim() == "일정 수정") {
		    		if(calendarStart > calendarEnd) {
		    			alert("시작일이 종료일보다 빠른 일자여야 합니다.")
		    			event.target.value = calendarEnd;
		    			return false;
		    		}
		    		return false;
		    	}
		    	
		    	if(calendarStart == calendarEnd){
		    		$(".modal-header .modal-title").html("<strong style='color: red;'>일간</strong> 일정 등록");
		    	}else {
		    		if(calendarStart > calendarEnd) {
		    			alert("시작일이 종료일보다 빠른 일자여야 합니다.")
		    			event.target.value = calendarEnd;
		    			$(".modal-header .modal-title").html("<strong style='color: red;'>일간</strong> 일정 등록");
		    			return false;
		    		}
		    		$(".modal-header .modal-title").html("<strong style='color: blue;'>주간</strong> 일정 등록");
		    	}
		    	
		    });
		    
		    calendarEndEl.on("change", function(event){
		    	
		    	var calendarStart = calendarStartEl.val();
		    	console.log("calendarStart : " + calendarStart);
		    	var calendarEnd = calendarEndEl.val();
		    	console.log("calendarEnd : " + calendarEnd);
		    	var currentValue = event.target.value;
		    	console.log("currentValue : " + currentValue);
		    	
		    	if($(".modal-header .modal-title strong").text().trim() == "일정 수정") {
		    		if(calendarStart > calendarEnd) {
		    			alert("종료일이 시작일보다 늦은 일자여야 합니다.")
		    			event.target.value = calendarStart;
		    			return false;
		    		}
		    		return false;
		    	}
		    	
		    	if(calendarStart == calendarEnd){
		    		$(".modal-header .modal-title").html("<strong style='color: red;'>일간</strong> 일정 등록");
		    	}else {
		    		if(calendarStart > calendarEnd) {
		    			alert("종료일이 시작일보다 늦은 일자여야 합니다.")
		    			event.target.value = calendarStart;
		    			$(".modal-header .modal-title").html("<strong style='color: red;'>일간</strong> 일정 등록");
		    			return false;
		    		}
		    		$(".modal-header .modal-title").html("<strong style='color: blue;'>주간</strong> 일정 등록");
		    	}
		    	
		    });
		    
		});
		
	</script>
	
</html>

* http://localhost/cal/calender.do

(1) 일정 등록 : 일간

원하는 요일을 클릭하면 일간 일정 등록이 가능하다.
내용을 입력하고 등록!
해당 요일에 일정이 잘 등록되었다.


(2) 일정 등록 : 주간

원하는 일정을 드래그 하면?
시작일과 등록일이 자동으로 기간으로 계산되어 등록된다.


(3) 일정 확인

보고 싶은 일정을 클릭!


(4) 일정 수정

일간 일정이 주간 일정으로 변경되고 내용도 바뀐다.


(5) 일정 삭제


(6) 드래그 앤 드랍 이벤트

일정을 잡아다 끌어 던지면?


[부가 기능]

1. 일정 위에 마우스를 올리면 툴팁으로 일정 제목과 일정 내용이 뜬다.

2. 시작일과 종료일 날짜 Validation 체크 완료
     - 시작일이 종료일 보다 늦은 일자가 되지 않도록
     - 종료일이 시작일 보다 빠른 일자가 되지 않도록

3. 일정 제목, 일정 내용, 시작일, 종료일을 Falsy한 값으로 Validation 체크 완료

'대덕인재개발원 > 대덕인재개발원_final project' 카테고리의 다른 글

(6) 토요일 수업 1  (0) 2023.12.23
(5) 보강 3  (0) 2023.12.22
(4) 보강 2  (0) 2023.12.21
(3) 보강 1  (0) 2023.12.20
(1) 주제 선정  (0) 2023.12.06