달력, 시간표 출력해서 예약 시스템 만들기 - appendChild 에러 문제해결

J_m2n·2023년 8월 4일
0
post-custom-banner

현재 진행 중인 세차장 예약 시스템에서 예약페이지 개발을 맡고 있다

이런 식으로 구상 중인데, 오늘 날짜에서 일주일 동안만 예약할 수 있는 시스템으로 구상했다. (화면 캡쳐는 어제(8월 4일)에 함)



달력은 table을 이용해서 만들었다.



그래서 어제 날짜(8월 4일) ~ 일주일 동안인 8월 10일까지의 셀 색상이 예약 가능하다는 뜻인 흰색 색상이고, 다른 날짜들은 예약 불가능한 회색이다. (click 메서드도 부여 안했음)



오른쪽의 시간과 분 div에는 JS에서 button을 만들어서 div에 추가시키고, 하나씩만 클릭하여 원하는 시간대를 선택하도록 만들었다.

여기까지는 그래도 꽤 순조로웠다.



문제는 오늘 날짜에 예약하려고 할 때 이미 지나간 시간들에 대해서는 예약을 못하게 만들어야겠다는 생각에서 시작되었다.



처음엔 그냥 현재 시간 값을 받아와서 오른쪽 시간 버튼의 값들과 비교해서
현재 시간 값보다 작은 버튼들은 click 메서드를 부여하지 않는 형태로 만들었다.

var date = new Date(); //현재 날짜 정보

var realMonth = date.getMonth()+1; //현재 날짜의 달
var realToDay = date.getDate(); //현재 날짜
    
var currentMonth = realMonth >= 10 ? realMonth : "0" + realMonth; 
var currentDate = date.getDate() >= 10 ? date.getDate() : "0" +date.getDate();
// ex.08-04 형태의 날짜 정보를 만들고 싶어서 일의 자리 달인 1~9월은 앞에 0을 붙이게, 일의 자리 일인 1~9일도 앞에 0을 붙이게 만듦.

var currentMD = currentMonth + "-" + currentDate; //현재 달-일 정보 

function timeHour(){ //시간 버튼들을 만드는 함수
    if(currentMD == clickedMD){ //clickedMD는 달력에서 선택한 날짜
    if(i >= currentHour){ //i는 9시~23시까지 반복되는 변수,  currentHour은 현재 시각 정보
    .
    .
    button들 생성
    .
    .
    .
    생략
    }
	var container = document.getElementById('container');
	container.appendChild('button');
    //container는 오른쪽의 시간 버튼들을 담을 div의 id
}




이렇게 하고 달력을 만드는 함수인 buildCalendar()안의 각 셀들에게 onclick 이벤트를 연결할 때 timeHour();를 넣어서 해당 날짜의 시간대 버튼들이 뜨도록 만들고 싶었다.



즉, 날짜를 바꿀 때마다 시간 div의 버튼들의 상태가 바뀌었으면 했다.

그런데 여기서 문제가 발생했다,,

> .문제 : appendChild에서 한 번도 본 적 없는 Uncaught TypeError: Cannot read property 'appendChild' of null 이라는 에러가 발생했다.




진짜 장난안하고 거의 5시간 동안 이 문제를 해결하고자 달력을 새로 만들어보기도 하고, 시간 버튼들을 담는 div를 jsp에 생성해놓지 않고 이 div를 만드는 함수까지 코딩했다.



그럼에도 계속 뜨는 에러에 포기할까 하던 찰나에..

jsp파일에서 달력을 생성하는 buildCalendar()함수를 달력을 띄우는 div에

<div>
<script> buildCalendar(); </script>
</div>

형태로 해놨던게 문제인가 싶어 찾아보니 html이 로드될 때, html안의 요소들을 다 읽기도 전에 timeHour()의 appendChild로 아직 읽히지도 않은 요소인 div의 id인 container를 접근하려 해서 문제였던 것이다..!!



그렇다고 이 함수들이 들어있는 js 파일을 연결시키는

<script src=...> </script>

코드를 body맨 밑부분에 놓으니 buildCalendar()가 define되지 않은 상태라는 에러가 뜨기 시작..!

해결 : 결국 buildCalendar()도 싹 다 갈아엎기 시작했고, 오랫동안 고민하고 찾아본 결과, 이 문제를 해결했다!!

<div>
<script> buildCalendar(); </script>
</div>



생각보다 간단했는데,, buildCalendar()를 위에서 처럼 쓰지 않고.

  1. div에 id를 부여한다.
  2. js 파일의 상단 부분에 해당 div를 document.getElementById()를 통해 전역변수(const element)로 만든다.
  3. buildCalendar()함수를 작성하고 js 파일의 하단 부분에element.appendChild(buildCalendar());를 작성한다.
  4. timeHour()함수에서는 함수 안에서 document.getElementById()로 div의 id를 받아오지 말고 똑같이 전역변수로 받아온다.
  5. 그 후 button들을 appendChild()시킨다.



이렇게하니 드디어 성공했다..
드디어 각 날짜 별로 다른 시간 버튼들이 생성된다,,!! ㅠㅠ



ps. 물론 그냥 이렇게 만들면 날짜를 바꿀 때마다 시간대 div에 각 날짜의 버튼들이 스택처럼 쌓이니 timeHour()에 div의 자식 요소들을 다 삭제시켜 div를 초기화 시키는 함수가 필요하다!!

profile
코딩 초짜입니다
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 8월 4일

즐겁게 읽었습니다. 유용한 정보 감사합니다.

1개의 답글