목차
1. 달력만들기
1) 년/월 변경하기 - HTML
2) 달력 일자표시하기 - HTML
3) Date() 객체 - JavaScript
4) 년/월 변경하기 - JavaScript
5) 내 예약정보 가져오기 - JavaScript
6) 내 예약정보 가져오기 - Controller
7) 내 예약정보 가져오기 - ServiceImpl
8) 내 예약정보 가져오기 - MyBatis.xml
9) 대망의 찐 달력만들기 - JavaScript
2. 모달만들기(달력의 일자를 누르면 해당일자의 예약정보를 모달에 띄운다.)
초보개발자 Toy-project 개발일지 ▲NO.9 ▲ 스터디룸 예약확인기능 만들기, 달력만들기, 모달만들기
목차 1. 달력만들기 1) 년/월 변경하기 - HTML 2) 달력 일자표시하기 - HTML 3) Date() 객체 - JavaScript 4) 년/월 변경하기 - JavaScript 5) 내 예약정보 가져오기 - JavaSc..
isjiji.tistory.com
'내가 예약한 스터디룸의 정보'를 확인하는 기능을 만들었다.
- 효과적으로 정보를 확인하기 위해 달력을 직접 만들었고,
- 예약이 있는 날짜는 색으로 차이를 두었다.
- 해당 날짜를 클릭하면 모달을 띄워서 예약정보를 확인할 수 있게 만들었으며
- 취소하고싶은 예약은 삭제할 수 있도록 삭제기능도 추가했다.

1. 달력만들기
자바스크립트로 달력을 직접 만들었다. 이전게시글을 보면, 예약할 때 띄울 달력은 Boot-strap에서 제공하는 아주 간편한 data-picker를 사용했다.
예약확인기능에서도 오픈소스를 찾아 사용할 수 있지만, 직접 해보기로했다.
1) 년/월 변경하기 - HTML

년/월을 선택하는 방법으로는 ◀ ▶ 를 담은 버튼을 만들어 버튼을 누를 때마다 월이 변경되게 만들었다. 그리고 년/월 정보를 담을 span태그를 미리 만들어 놓고, 화면이로드될때, 버튼을 눌러 월을 변경할 때 span태그에 정보를 입력하게끔 JavaScript소스를 짰다.
//html
<div>
<input type="button" class="btn btn-light btn-xl" onclick="minusMonth()" value="◀">
<span id="year" style="font-size:xx-large;"> </span>년
<span id="month" style="font-size:xx-large;"> </span>월
<input type="button" class="btn btn-light btn-xl" onclick="plusMonth()" value="▶">
</div>
2) 달력 일자표시하기 - HTML
달력은 table 태그를 이용해서 만들었다. table태그를 html에 미리 만들어 놓고, 화면이 로드되거나 월이 변경되었을 때 JavaScript를 이용해 table태그에 새로운 달력 정보를 띄우게 만들었다.
//html
<table id="tableTag">
</table>
3) Date() 객체 - JavaScript
먼저 Date() 객체를 이용해 오늘의 날짜를 today변수에 담는다.
그리고 today변수를 이용해 오늘의 월, 연도를 각각의 변수에 담아주었다.
바로 아래 코드의 setDate() 함수는 달력위에 년/월을 담는 span태그에 년/월 정보를 담는다.
그리고 달력의 일자를 만들어서 찐 달력을 만들어줄 retrieveBoolStatus() 함수를 호출한다.
setDate() 함수는 화면이 로드될 때 첫번째로 호출되고,
년/월이 변경될 때마다 호출되게끔 만들었다.
<!--달력-->
const today = new Date();
let choiceMonth=today.getMonth();
let choiceYear=today.getFullYear();
let bookCalendar = document.querySelector("#bookCalendar");
const month=document.querySelector("#month");
const year=document.querySelector("#year");
function setDate(){
year.innerHTML=choiceYear;
month.innerHTML=choiceMonth+1;
retrieveBookStatus(choiceYear,choiceMonth);
}
4) 년/월 변경하기 - JavaScript
◀ ▶ 를 눌러서 년/월을 변경할 때 아래의 minusMonth() 함수와 plusMonth() 함수를 사용한다.
◀ 를 눌렀을 때 실행되는 monusMonth()함수는
가장 먼저 if문으로 (오늘의 연도보다 선택된 연도가 크거나 같은지) 확인한다. 그 이유는 최소 이번년도의 예약현황까지만 검색할 수 있게하기 위함이다.(이전년도 검색 안됨. 이후년도는 됨.) 단 자바스크립트의 Data객체는 월을 가져올 때, 1월을 0으로 2월을 1로 가져오기 때문에 이전년도 12월까지는 검색이 가능하다.
그 다음, 현재 선택된 월이 0과 같으면 즉 1월이라면, 월은 11 즉 12월로 세팅이된다.
그리고 선택된 연도에서 1을 감소시켜 이전년도가 세팅되게한다.
정리하자면 2022년 1월에서 ◀ 버튼이 눌려지면 2021년12월이 세팅되는것이다.
◀ 버튼이 눌러졌는데 년도가 변경되는 상황이 아니라면, 월만 줄어든다.
그리고 마지막으로 setMonth()함수를 재실행시킨다.
function minusMonth(){
if(choiceYear>=today.getFullYear()){
if(choiceMonth==0){
choiceMonth=11;
choiceYear--;
}else
choiceMonth--;
setDate();
}
}
▶ 버튼을 눌려 plusMonth()함수가 실행되면,
최대 11개월 까지만 검색할 수 있게 하기 위해, 선택한 날짜가 오늘로부터 11개월 이후의 날짜보다 작은지 확인한다.
만약 선택한 날짜가 11개월 이후보다 크면 ▶ 버튼은 실행되지 않는다.
작다면, minusMonth()와 처럼 년도가 변경되는지 아닌지를 확인하고, 날짜를 입력해준다.
그리고 마지막에 setDate()함수를 실행시킨다.
function plusMonth(){
if(new Date(choiceYear,choiceMonth) < new Date(today.getFullYear()+1,today.getMonth()-1)){
if(choiceMonth==11) {
choiceMonth=0;
choiceYear++;
} else
choiceMonth++;
setDate();
}
}
5) 내 예약정보 가져오기 - JavaScript
벌써 세번이나 retrieveBookStatus()함수를 호출했다.
년/월을 세팅할 때마다 retrieveBookStatus()함수가 호출되었으니, retrieveBookStatus()함수에는 달력의 핵심은 일자를 세팅하는 로직이 있을것으로 추측할 수 있을것이다 !
그렇다. retrieveBookStatus()함수에는 일자를 세팅하는 로직이 있지만,
이 달력은 세미나실 예약현황을 조회하기위해 만들어진 달력이기 때문에 일자를 세팅하기 전에 먼저 DB에 저장된 나의 예약정보를 가져올 것이다. 그리고 예약정보를 가져온 다음 달력의 일자를 만들어주고, 일자별로 예약정보를 세팅해줄것이다.
retrieveBookStatus()함수가 호출될 때, 필요한 인자가 있다. 바로 choiceYear, choiceMonth이다. 선택된 년/월의 정보!
이 정보는 일자를 만드는 함수가 호출될때 사용할것이다.
물론 뒷단에 보내줄 데이터도 choiceMonth, choiceYear와 동일하지만 (이제보니) 나의 로직은 굳이 innerHTML을 받아온다. 아마 choiceMonth에 +1을 해줘야해서 그런게 아닐까.. 싶은데.. 정말 굳이 새로 만들가져올 필요는 없으니
뒷단에 보내줄 데이터를 choiceMonth, choiceYear로 사용하게끔 수정하면 좋겠다.(나자신아)
암튼 DB에 동일한 데이터가 있는지 없는지 확인할 용도로(select문의 where절에서 사용할것) 보내는 데이터이기 때문에 DB에 저장된 년/월 데이터와 동일한 포맷으로 변경한 다음, url에 담아 뒷단으로 보냈다.
목적은 조회이기 때문에 Get방식을 사용했다.
뒷단에서 데이터를 받아온 데이터중, substring을 이용해 날짜만 따로 뗀 다음 배열에 넣어주었다. createClanedar()함수에서 예약정보가 있는 날짜의 색을 변경할때 배열을 사용할것이다.
<!--달력에 띄울 세미나실 예약현황 조회-->
function retrieveBookStatus(choiceYear,choiceMonth){
let cMonth= month.innerHTML;
let cYear= year.innerHTML;
if(cMonth<10)cMonth="0"+cMonth;
let retrieveYM=cYear+"-"+cMonth;
console.log("조회연월"+retrieveYM);
let bookStatusData={"bookDate":retrieveYM};
bookStatusData = JSON.stringify(bookStatusData);
let xhr = new XMLHttpRequest();
xhr.open('GET', "/stuhel/myPage/retrieveBookStatus?bookStatusData="+encodeURI(bookStatusData)
,true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
// 데이터 확인
let txt = xhr.responseText;
monthBookDataArr = JSON.parse(txt);
console.log(monthBookDataArr);
tdTagIdArr=[];
if(monthBookDataArr.length>0){
for(var i=0;i<monthBookDataArr.length;i++){
let bookDate;
if(monthBookDataArr[i].bookDate.substr(8,1)!="0") bookDate=monthBookDataArr[i].bookDate.substr(8,2);
else bookDate=monthBookDataArr[i].bookDate.substr(9,1);
tdTagId = "date"+bookDate;
tdTagIdArr.push(tdTagId);
}
}
createCalendar(choiceYear,choiceMonth,tdTagIdArr);
}
}
}
6) 내 예약정보 가져오기 - Controller
앞단에서 보낸 데이터를 @RequestParam() 어노테이션으로 받은 다음, gson을 이용해 TO에 담아주었다.
(gson은 적은양의 데이터를 주고받을 때 속도면에서 용이하다.)
그리고 login할 때 session에 저장해둔 memberId 즉 사용자 ID를 TO에 담아주었다.
오직 자신의 예약현황만 볼 수 있기 때문이다.
@GetMapping("/retrieveBookStatus")
public String retrieveBookStatus(HttpServletRequest request,@RequestParam("bookStatusData") String bookStatusData){
HttpSession session = request.getSession();
BookTO book = gson.fromJson(bookStatusData, BookTO.class);
book.setUserId((String)session.getAttribute("memberId"));
return gson.toJson(myPageService.retrieveBookStatus(book));
}
7) 내 예약정보 가져오기 - ServiceImpl
ServiceImpl에서 날짜정보가 담긴 TO를 DAO로 넘겨준다.
@Override
public ArrayList<BookTO> retrieveBookStatus(BookTO bookTO) {
ArrayList<BookTO> book= myPageDAO.selectBookStatus(bookTO);
return book;
}
8) 내 예약정보 가져오기 - MyBatis.xml
사용자 아이디와 예약날짜(년/월)를 조건문에 넣어주고, 동일한 조건을 가진데이터를 DB 테이블에서 가져온다.
여기서 쿼리문의 마지막 조건문을 보면 Book_Date를 like로 비교하고, 뒤에는 %를 붙여준것을 볼 있다.
앞단에서 조립해서 보낸 데이터에는 년/월만 들어있지만 테이블의 BOOK_DATE컬럼에는 일자까지 함께 붙어 있다. 그래서 like 와 % 를 이용해 부분 문자열을 조건으로 검색했다.
<select id="selectBookStatus" parameterType="com.helper.study.stuhel.book.to.BookTO" resultMap="myPageBook">
SELECT *
FROM ROOM_BOOK
WHERE USER_ID = #{userId}
AND BOOK_DATE LIKE #{bookDate}||'%'
</select>
9) 대망의 찐 달력만들기 - JavaScript
두둥! 드디어 달력다운 달력을 만들 createCalendar() 함수다!!!!
함수를 호출할 때 인자로 세가지를 받는다. (선택한년도, 선택한 월, 해당년/월에 있는 예약일자)
가장먼저 table태그를 비워준다.
tableTag.innerHTML="";
이거 안해주면 새로운 월의 달력을 조회해도 이전달력이 계속 떠있는다. 수십개의 달력을 보게될수도..
(가장 아래에 있는 소스 확인)
- 요일을 배열에 담았다. 요일은 변할일이 없으니까 const로 만들어준다.
- 선택한 년/월의 마지막 날짜를 변수 lastDate에 담아준다.
- 선택한 년/월의 첫 날 요일을 변수firstBlankNum에 담아준다. / 달력의 첫줄 공백 계산할 때 사용할것임!!
- 선택한 년/월의 첫째주 일수를 변수 firstLineDayNum 에 담아준다. / 식) 7 - firstBlankNum
- 달력의 최소 주수는 5주이다. 변수 lineNum에 담아준다. / 최대주수는 6주이다. if문을 이용해 firstBlankNum와 lastDate를 더한 수가 35보다 크면 6주로 지정해준다.
- 달력의 첫날은 항상 1이기 때문에 firstDay = 1로 지정해준다.
자.. 한거라고는 변수선언 밖에 없지만, 사실 여기까지만 해주면 거의 끝났다!!!!!!!!!!!!!
(가장 아래에 있는 소스 확인)
- for문을 열어서 lineNum 만큼 tr 태그를 만든다. (요일도 tr태그에 넣어줄거라서 0부터시작해야한다.)
- 이중for문을 열어서 tr 태그 안에 td 태그 7개를 만든다.
- 이중for문 안에서 tdTag.innerHTML= firstDay++; 를 해주면서 날짜를 입력해줄것임!
단, 참고해야할 것이 있는데,
1) line이 0과 같으면 요일을 세팅해준다.
2) line이 1과 같으면 첫주의 날짜를 세팅해준다. 단, firstBlankNum-1 만큼의 길이는 빈칸으로 채워준다.
3) line 2부터는 firstDay가 lastDay보다 크지 않으면 계속 날짜를 세팅해주면된다.
4) firstDay가 lastDay보다 크면 날짜대신 공백을 입력한다.
나는 날짜를 클릭하면 예약정보를 확인하는 모달을 띄울것이기 때문에
날짜를 innerHTML 해줄 때마다 td태그 ID 와 onclick 이벤트를 만들었다.
소스를 작성할 때 여기서 많이 막혔다. tdTag.onclick이 아닌, tdTag.id.onclick 으로 이벤트를 실행하려했기 때문이다.ㄷㄷㄷㄷㄷㄷㄷㄷ
아래와 같이 하면 tdTag가 눌러질 때마다, 눌러진 tdTag의 id가 모달을 여는 tdTagClick()함수를 열어준다.
tdTag.onclick = () => {tdTagClick(tdTag.id)};
후후 끝이났다. 아래의 로직에 달력만드는 모든 내용이 들어있다. 굳이 글로 상세하게 쓴 이유는 혹시라도 필요한 사람이 있으면 참고했으면 좋겠어서..ㅎ
function createCalendar(choiceYear,choiceMonth,tdTagIdArr){
tableTag.innerHTML="";
const dayArray=["일","월","화","수","목","금","토"];
let lastDate =new Date(choiceYear,choiceMonth,0).getDate();
let firstBlankNum=new Date(choiceYear,choiceMonth).getDay();
let firstLineDayNum=7-firstBlankNum;
let lineNum=5;
let firstDay=1;
if(firstBlankNum+lastDate > 35) lineNum=6;
for(var line=0;line<=lineNum;line++){
let trTag=document.createElement("tr");
for(var j=0;j<7;j++){
let tdTag=document.createElement("td");
if(line==0){
tdTag.innerHTML = dayArray[j];
}else if(line==1){
if(j<firstBlankNum) tdTag.innerHTML =" ";
else{
tdTag.id="date"+firstDay;
tdTag.innerHTML = firstDay++;
tdTag.onclick = () =>{tdDateClick(tdTag.id);}
}
}else{
if(firstDay>lastDate)
tdTag.innerHTML=" ";
else{
tdTag.id="date"+firstDay;
tdTag.innerHTML=firstDay++;
tdTag.onclick = () =>{tdDateClick(tdTag.id);}
}
}
for(let i=0;i<tdTagIdArr.length;i++){
if(tdTag.id == tdTagIdArr[i]) tdTag.style.color="tomato";
}
tdTag.style.height="60px";
tdTag.style.width="80px";
tdTag.style.textAlign="center";
trTag.appendChild(tdTag);
}
tableTag.appendChild(trTag);
}
}
모달만들기는 아래 게시글을 확인해주세요 ! 너무 길어서 나눴습니다^__^
초보개발자 Toy-project 개발일지 ▲NO.9 ▲ 스터디룸 예약확인기능 만들기, 달력만들기, 모달만들기
목차 1. 달력만들기 1) 년/월 변경하기 - HTML 2) 달력 일자표시하기 - HTML 3) Date() 객체 - JavaScript 4) 년/월 변경하기 - JavaScript 5) 내 예약정보 가져오기 - JavaSc..
isjiji.tistory.com