Bootstrap-Calendar는 그 이름에서 알 수 있듯이, Bootstrap을 이용한 캘린더 모듈(아님 프레임워크, 아직도 이 둘을 구분을 못한다)이다. 몇몇 css 파일과 js 파일을 적절한 위치에 넣고, 캘린더를 호출하면, 그 자리에 뙇하고 캘린더가 나타나기 때문에 웹에서 캘린더를 올려놓고, 일정 공유를 할 필요가 있을 때 상당히 유용한 녀석이다. 하지만, 실제 사용에서는 약간의 문제가 있다. 깃허브에 올라온 도큐멘트와 예세 소스들 중에 하나도 제대로 된 게 없고, bower로 Bootstrap-Calendar를 설치하면 된다고 "나와있음에도 불구하고" bower를 이용하면 제대로 캘린더를 사용할 수가 없다. 기능이 상당히 많은 관계로 소스 코드가 상당히 복잡한데, 약간의 기능 수정이나 경로 변경을 하려고 하면, 거의 모든 캘린더 모듈과 관련된 css와 js파일들을 들쑤셔야하기 때문에 쉽게 문제가 해결 되지도 않는다. 필자도 1~2 시간 동안 bower로 bootstrap, bootstrap-calendar, jQuery, underscore.js 설치하다 경로 관련으로 엄청나게 삽질을 하였고, 현재 실력으로는  해결 할 수 없는 문제들이라는 걸 깨닫고 github 레포지토리를 클론하였다. 하지만 이렇게 클론을 했음에도 불구하고, 캘린더의 몇몇 기능들을 설명하는 소스코드를 참고를 해서는 개발을 할 수 없다. 예제 소스에 오류가 있고 도큐멘테이션이 제대로 되지 않았기 때문인데, sql 쿼리를 던져 일정을 json 객체로 던지는 php 예제 코드가 제대로 작동을 안하는 게 대표적이다. 처음에는 코드가 잘못 된 줄 모른채 mysql이 잘못 붙은 줄 알고 장대한 삽질을 하였는데, 설마하고 .css와 .js 소스코드를 분석하면서 예제가 잘못 됬음을 알게되었다. 단도직입적으로 도큐멘테이션도 예제도 못 믿겠으니 .css 파일과 .js 파일을 하나하나씩 뜯어가면서 작동 로직을 확인하고, 로직에 맞게 코드를 다 짜야한다. 부트스트랩은 분명 아무 생각 없이 도큐멘트와 예제 코드만 보고 웹 개발하라고 있는 녀석인데, 이건 좀 아닌거 같았고, 결국 이 글을 쓰게 되었다.


Github 주소 : https://github.com/Serhioromano/bootstrap-calendar

캘린더 데모 : http://bootstrap-calendar.azurewebsites.net/


설치를 위해 git를 이용하자. 설치를 원하는 폴더로 이동하고, git clone을 이용하여 받으면 된다. bower를 써도 된다고 하지만, 적극적으로 비추한다. ( 윈도 환경에서 쓰겠다고 한다면, github에 가서 download .zip을 이용하여 zip파일로 받고 압축 해제를 하면 된다. 또한 리눅스 터미널을 모른다면, zip 파일을 받자)

 git clone https://github.com/Serhioromano/bootstrap-calendar 

index.html를 열어보면 이쁘장한 캘린더가 나올 것이다. 이제 여기에 일정을 넣는 방법을 찾아야한다. 일단, 녀석은 js 폴더 아래에 있는 app.js를 불러오면서 calendar를 그린다. app.js를 보면 알겠지만, 이것도 예제 코드고 개발자는 귀찮았는지 바로 적용해서 바로 쓸 수 있게 만들어놓지를 않았다.

	var options = {
		events_source: 'events.json.php',
		view: 'month',
		tmpl_path: 'tmpls/',
		tmpl_cache: false,
		day: '2013-03-12',
		onAfterEventsLoad: function(events) {
			if(!events) {
				return;
			}
			var list = $('#eventlist');
			list.html('');

			$.each(events, function(key, val) {
				$(document.createElement('li'))
					.html('' + val.title + '')
					.appendTo(list);
			});
		},
		onAfterViewLoad: function(view) {
			$('.page-header h3').text(this.getTitle());
			$('.btn-group button').removeClass('active');
			$('button[data-calendar-view="' + view + '"]').addClass('active');
		},
		classes: {
			months: {
				general: 'label'
			}
		}
	};

보면 알 수 있지만, day 가 고정되어있다. index.html을 열면 매일 달력 날짜가 2013년 3월 12일에 고정되어있는 것이 그 이유이다.

	var today = new Date();
	var dd = today.getDate();
	var mm = today.getMonth()+1; //January is 0!
	var yyyy = today.getFullYear();

	if(dd<10) {
		dd='0'+dd
	} 

	if(mm<10) {
		mm='0'+mm
	} 
	var todayis = yyyy+'-'+mm+'-'+dd;

이 코드를 app.js에 추가하자. todayis가 오늘의 날짜를 나타내게 하는 코드다. day: '2013-03-12'를 day: todayis로 바꿔주기만 하면, day의 값는 오늘의 날짜를 가리키게 되고, 결과적으로 index.html을 열 때 요번달 달력이 나오게 된다. 이렇게, 날짜 관련 문제를 대부분 해결 할 수 있다. 이제 일정을 넣는 방법을 알아보자.

{
    "success": 1,
    "result": [
        {
            "id": 293,
            "title": "Event 1",
            "url": "http://example.com",
            "class": "event-important",
            "start": 12039485678000, // Milliseconds
            "end": 1234576967000 // Milliseconds
        },
        ...
    ]
}

이것이 맨 처음 나온 json 객체 예제이다. 이 소스는 약간만 수정하면 잘만 작동을 한다. 일단, 여기서 눈 여겨봐야할 점은 success : 1 과 result 값들이다. 뭔 의도인지 몰라도 개발자는 success:1 가 맨 처음에 있어야만, 이후의 json 객체들을 다 읽도록 하였다. result 값은 id, title, url, class, start, end 로 구성이 되어있다. id는 일정 구분을 하는 프라이머리키 (로 추정), title은 일정 제목, url은 일정 title을 클릭했을 때 리다이렉트 되는 주소이다. 이 때, http://를 안 붙이면 "현재 위치한 도메인" + "/" + url 값 으로 리다이렉트 된다. "url" : "250" 이고, 캘린더의 주소가 bengi.kr/index.html 이라면, bengi.kr/250으로 이동을 하는 것이다. class는 calendar.css에 정의된 컬러셋을 불러온다. event-important 는 빨간색으로, event-warning은 주황색으로 캘린더에 점이 찍혀져 나온다. (직접 해보면 이해가 쉽다) 뭐 다른 컬러셋 설정도 있으니, calendar.css를 뜯어볼 것을 추천한다. 또한, 당연하게도 css 파일을 수정해서 컬러셋을 추가할 수도 있다. start와 end는 timestamp로 일정 시작 시간과 일정 마감 시간 받아서 저장하는 부분인데, 이것을 손으로 계산하는 일은 엄청나게 귀찮은 일이라는 건 한 눈에 봐도 알 수 있다. Mysql에 붙여서 이 캘린더를 관리하는 이유가 이것 때문이다. Mysql 에서 timestamp 객체를 생성하고, 날짜와 시간을 지정해주면 밀리초 단위로 자동으로 변환시켜주니, 실제로 복잡한 계산을 할 필요는 없다.

<?php
$db    = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');
$start = $_REQUEST['from'] / 1000;
$end   = $_REQUEST['to'] / 1000;
$sql   = sprintf('SELECT * FROM events WHERE `datetime` BETWEEN %s and %s',
    $db--->quote(date('Y-m-d', $start)), $db->quote(date('Y-m-d', $end)));

$out = array();
foreach($db->query($sql) as $row) {
    $out[] = array(
        'id' => $row->id,
        'title' => $row->name,
        'url' => Helper::url($row->id),
        'start' => strtotime($row->datetime) . '000',
        'end' => strtotime($row->datetime_end) .'000'
    );
}

echo json_encode(array('success' => 1, 'result' => $out));
exit;

DB에 캘린더를 연동하는 예제 소스이다. 소스를 보면 알겠지만 ?> 가 존재하지 않는다. 일단 여기부터 낌새를 알아차려야하는데, 앞서 말했듯이 이 소스는 제대로 작동을 안한다. 또한, class 값을 안 긁어오기에 각 일정마다 색을 입히지를 못한다. PDO가 제대로 mysql에 붙지도 않는다. 제대로 mysql을 붙였다고 하더라도 sql 쿼리가 잘못되어 이 달의 모든 일정을 출력하지 못한다. 여러모로 골 때리는 일이 아닐 수 없다. 그래서, mysqli를 이용해서 DB를 붙이고, 코드를 다시 짜는 쪽으로 방향을 잡았다.


일단, app.js에서 어떤 파일을 끌고올지 설정을 하자. 디폴트 설정은 위에서 볼 수 있듯이 event.json.php이다. 그냥 귀찮다면, index.html있는 폴더에 event.json.php 파일을 만들면 된다.

<?php
$my_db = new mysqli("localhost",아이디,비밀번호,테이블이름);
$res =mysqli_query($my_db,"SELECT * FROM Calendar");

$out = array();
while($data = mysqli_fetch_array($res)) {
	$out[] = array(
		'id' => $data['id'],
		'title' => $data['name'],
		'url' => $data['url'],
		'start' => strtotime($data['datetime']).'000',
		'end' => strtotime($data['datetime_end']).'000',
		'class' => $data['class']

);
}
echo json_encode(array('success' => 1, 'result' => $out));
exit;
?>

요로코롬하게 입력을 하면 된다. 보면 알겠지만, Calendar 테이블에, id, name, url, datetime, datetime_end, class를 긁어오는 소스이다. 즉, mysql에 Calendar 테이블에 id, name, url, datetime, datetime_end, class 컬럼이 있어야하는 건 당연한 일 일 것이다. 필자의 경우 이렇게 테이블을 잡았다.



그리고 결과는 이렇다.


BELATED ARTICLES

more

COMMENT

  • won 2015.07.14 10:24 올려주신 글 잘 봤습니다.
    보고 따라해보니 달력 구현은 잘 되더라구요. 그런데 문제가 DB에 event를 생성했더니 실제 달력에는 16시간씩 밀려서 나오는 현상이 발생합니다. 혹시 무엇이 문제인지 알 수 있을까요? event.json.php 파일도 글에 있는 것과 동일하게 생성했는데...
  • Favicon of https://bengi.kr BlogIcon Bengi 2015.07.14 15:35 신고 저 같은 경우는 아예 문제가 없었는데, 음 아마 mysql을 붙이셨다면, mysql 설정에 문제가 있지 않나 싶습니다다. 시간대가 UTC/GMT +9으로 맞춰져 있으신지 확인부탁드립니다.
  • Favicon of https://bengi.kr BlogIcon Bengi 2015.07.14 15:38 신고 일단 리눅스나 윈도우에서 시간이 제대로 설정됬는지 확인하시는게 우선일 거 같습니다. 그리고 만약 거주하시는 위치가 한국이 아니시라면 이거 또한 고려사항으로....
  • 궁금해요.. 2015.07.16 16:06 zip파일을 받아서 열었는데 아예 calendar가 나오질 않네요...경로가 잘못되어서 그런지 확인해봤지만 경로는 정확하게 되어있는데..삽질하다가 결국 질문올리내요.ㅠ..ㅠ
  • Favicon of https://bengi.kr BlogIcon Bengi 2015.07.17 10:33 신고 서버에 올려보시고 확인해보세요. 서버에 올리면 잘 보이는데, 그냥 파일로 열어보면 캘린터가 안 보이는 문제가 있는거 같습니다.
  • Favicon of https://bengi.kr BlogIcon Bengi 2015.07.17 10:34 신고 XAMPP나 아파치 서버 설치하시고, 거기에 파일 올리고, 127.0.0.1 로 접속해보시면 될 거 같습니다.
  • 답변감사합니다. 2015.07.17 11:38 로컬서버에서 잘나오네요^^
  • 또 질문합니다... 2015.07.17 14:08 로컬에 올려서 확인한 결과 잘 나오는데..php파일을 만들어서 컨텐츠 영역에 넣으면 또 안나오네요.ㅠ.ㅠ
    js파일이나 css파일도 전부 링크 걸어주었는데...안나오는 이유를 모르겠네요...부트스트랩용 무료 배포 달력은 이게 제일 이쁘기도 하고 지금 개발중인 페이지에 딱 필요한데...생각보다 잘안되네요...도움 부탁드려요
  • Favicon of https://bengi.kr BlogIcon Bengi 2015.07.18 13:28 신고 일단 app.js 를 뜯어보시면 알겠지만 app.js는 무조건 events.json.php 파일의 내용을 긁어서 보여줍니다. 일단, 컨텐츠 영역에서 제대로 보이게 하고 싶으시다면, calendar.css 를 직접 긁어서 보여주는 부분을 아예 코딩 하셔야할 거 같습니다.
  • Favicon of https://bengi.kr BlogIcon Bengi 2015.07.18 13:32 신고 일단 php파일은 어찌 만드셨는지 올려주실 수 있으신가요? 영어만 적으면 스팸처리 되서 댓글이 차단처리 된거 같은데, 그 차단 다 풀었습니다.
  • 안녕하세요.. 2015.07.20 11:28 laravel로 작업중이라서 index.blade.php로 만들어서 작업중이구요...안나오는문제는 json파일에서 경로를 상대경로에서 절대경로로 변경해주니 달력이 나오더라구요..암튼 그문제로 엄청 애먹었네요...작업하다가 또 의문점 생기면 질문하겠습니다..답변 감사합니다...^^
  • dahee 2018.12.13 14:23 php 말고 jsp로도 작업 가능할까요?
  • 윤재만 2019.06.23 18:53 멋진 글 잘보고 갑니다.^^