Last active
August 29, 2015 14:19
-
-
Save nesvand/062eaca65ecfaf5230c4 to your computer and use it in GitHub Desktop.
Google CLNDR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* @calendar styling */ | |
.events-list::-webkit-scrollbar { | |
-webkit-appearance: none; | |
width: 7px; | |
} | |
.events-list::-webkit-scrollbar-thumb { | |
border-radius: 4px; | |
background-color: rgba(0,0,0,.5); | |
-webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); | |
} | |
#calendar { | |
font-family: Asap, Helvetica, Arial; | |
margin: 0 auto; | |
width: 100%; | |
-moz-box-shadow: 4px 4px 0 rgba(120, 119, 119, 0.9); | |
-webkit-box-shadow: 4px 4px 0 rgba(120, 119, 119, 0.9); | |
box-shadow: 4px 4px 0 rgba(120, 119, 119, 0.9); | |
} | |
#calendar .clndr { | |
overflow: hidden; | |
border-bottom: 7px solid #71BBD2; | |
} | |
#calendar .clndr .controls { | |
background-color: #256681; | |
color: white; | |
} | |
#calendar .clndr .controls .clndr-previous-button, | |
#calendar .clndr .controls .clndr-next-button { | |
width: 15%; | |
padding-top: 5px; | |
padding-bottom: 5px; | |
display: inline-block; | |
text-align: center; | |
cursor: pointer; | |
-webkit-user-select: none; | |
/* Chrome/Safari */ | |
-moz-user-select: none; | |
/* Firefox */ | |
-ms-user-select: none; | |
/* IE10+ */ | |
-webkit-transition: background-color 0.5s; | |
-moz-transition: background-color 0.5s; | |
-ms-transition: background-color 0.5s; | |
-o-transition: background-color 0.5s; | |
transition: background-color 0.5s; | |
} | |
#calendar .clndr .controls .clndr-previous-button:hover, | |
#calendar .clndr .controls .clndr-next-button:hover { | |
background-color: #3E9EC6; | |
} | |
#calendar .clndr .controls .month { | |
width: 70%; | |
padding-top: 5px; | |
padding-bottom: 5px; | |
display: inline-block; | |
text-align: center; | |
text-transform: uppercase; | |
font-weight: 700; | |
letter-spacing: 1px; | |
} | |
#calendar .clndr .days-container { | |
position: relative; | |
width: 100%; | |
height: 265px; | |
display: inline-block; | |
} | |
#calendar .clndr .days-container .days { | |
position: absolute; | |
left: 0; | |
width: 100%; | |
height: 270px; | |
-webkit-transition: left 0.5s; | |
-moz-transition: left 0.5s; | |
-ms-transition: left 0.5s; | |
-o-transition: left 0.5s; | |
transition: left 0.5s; | |
background-color: #ebebeb; | |
} | |
#calendar .clndr .days-container .days .day, | |
#calendar .clndr .days-container .days .empty { | |
width: 14.2857%; | |
display: inline-block; | |
height: 40px; | |
padding: 1em 0; | |
font-size: 12px; | |
text-align: center; | |
color: #212121; | |
background-color: #EBEBEB; | |
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHZlcnNpb249IjEuMiIgYmFzZVByb2ZpbGU9InRpbnkiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjExNHB4IiBoZWlnaHQ9IjY2cHgiIHZpZXdCb3g9IjAgMCAxMTQgNjYiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwb2x5Z29uIGZpbGw9IiNFOEU4RTgiIHBvaW50cz0iMTE0LDAgMCw2NiAxMTQsNjYgIi8+PC9zdmc+); | |
background-size: cover; | |
background-position: center center; | |
border-right: 1px solid rgba(255, 255, 255, 0.5); | |
border-bottom: 1px solid rgba(255, 255, 255, 0.5); | |
} | |
#calendar .clndr .days-container .days .day.event, | |
#calendar .clndr .days-container .days .empty.event { | |
background-color: #fff; | |
background-image: none; | |
-webkit-transition: background-color 0.5s; | |
-moz-transition: background-color 0.5s; | |
-ms-transition: background-color 0.5s; | |
-o-transition: background-color 0.5s; | |
transition: background-color 0.5s; | |
cursor: pointer; | |
} | |
#calendar .clndr .days-container .days .day.event:hover, | |
#calendar .clndr .days-container .days .empty.event:hover { | |
background-color: #b8b8b8; | |
} | |
#calendar .clndr .days-container .days .day.event .day-number, | |
#calendar .clndr .days-container .days .empty.event .day-number { | |
padding-bottom: 4px; | |
border-bottom: 2px solid #3883A3; | |
} | |
#calendar .clndr .days-container .days .day.adjacent-month, | |
#calendar .clndr .days-container .days .empty.adjacent-month { | |
color: rgba(0, 0, 0, 0.3); | |
} | |
#calendar .clndr .days-container .days .empty { | |
height: 31px; | |
vertical-align: bottom; | |
} | |
#calendar .clndr .days-container .days .headers { | |
background-color: #3883A3; | |
padding-top: 5px; | |
padding-bottom: 5px; | |
} | |
#calendar .clndr .days-container .days .headers .day-header { | |
width: 14.2857%; | |
display: inline-block; | |
text-align: center; | |
color: white; | |
} | |
#calendar .clndr .days-container .events { | |
position: absolute; | |
left: 100%; | |
width: 100%; | |
height: 270px; | |
-webkit-transition: left 0.5s; | |
-moz-transition: left 0.5s; | |
-ms-transition: left 0.5s; | |
-o-transition: left 0.5s; | |
transition: left 0.5s; | |
background-color: #ebebeb; | |
} | |
#calendar .clndr .days-container .events .headers { | |
position: relative; | |
} | |
#calendar .clndr .days-container .events .event-header { | |
width: 100%; | |
background-color: #71BBD2; | |
padding-top: 5px; | |
padding-bottom: 5px; | |
text-align: center; | |
color: white; | |
} | |
#calendar .clndr .days-container .events .x-button { | |
position: absolute; | |
font-size: 80%; | |
top: 7px; | |
left: 20px; | |
cursor: pointer; | |
-webkit-transition: color 0.25s; | |
-moz-transition: color 0.25s; | |
-ms-transition: color 0.25s; | |
-o-transition: color 0.25s; | |
transition: color 0.25s; | |
} | |
#calendar .clndr .days-container .events .x-button:hover { | |
color: white; | |
} | |
#calendar .clndr .days-container .events .events-list { | |
overflow-y: scroll; | |
height: 240px; | |
} | |
#calendar .clndr .days-container .events .events-list .event { | |
padding-top: 1em; | |
padding-bottom: 1em; | |
padding-left: 10px; | |
border-bottom: 1px solid rgba(255, 255, 255, 0.5); | |
-webkit-transition: background-color 0.25s; | |
-moz-transition: background-color 0.25s; | |
-ms-transition: background-color 0.25s; | |
-o-transition: background-color 0.25s; | |
transition: background-color 0.25s; | |
} | |
#calendar .clndr .days-container .events .events-list .event:hover { | |
background-color: #f5f5f5; | |
} | |
#calendar .clndr .days-container .events .events-list .event a { | |
position: relative; | |
font-size: 12px; | |
letter-spacing: 1px; | |
background-color: transparent; | |
color: #212121; | |
text-decoration: none; | |
-webkit-transition: color 0.25s; | |
-moz-transition: color 0.25s; | |
-ms-transition: color 0.25s; | |
-o-transition: color 0.25s; | |
transition: color 0.25s; | |
} | |
#calendar .clndr .days-container .events .events-list .event a:hover { | |
background-color: transparent; | |
color: #256681; | |
} | |
#calendar .clndr .days-container.show-events .days { | |
left: -100%; | |
} | |
#calendar .clndr .days-container.show-events .events { | |
left: 0; | |
} | |
/* @calendar styling end */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script id="calendar-template" type="text/template"> | |
<div class="controls"> | |
<div class="clndr-previous-button">‹</div><div class="month"><%= month %></div><div class="clndr-next-button">›</div> | |
</div> | |
<div class="days-container"> | |
<div class="days"> | |
<div class="headers"> | |
<% _.each(daysOfTheWeek, function(day) { %><div class="day-header"><%= day %> <%= year %></div><% }); %> | |
</div> | |
<% _.each(days, function(day) { %><div class="<%= day.classes %>" id="<%= day.id %>"><span class="day-number"><%= day.day %></span></div><% }); %> | |
</div> | |
<div class="events"> | |
<div class="headers"> | |
<div class="x-button">x</div> | |
<div class="event-header">EVENTS</div> | |
</div> | |
<div class="events-list"> | |
<% _.each(eventsThisMonth, function(event) { %> | |
<div class="event"> | |
<a href="<%= event.url %>"><%= moment(event.date).format('MMMM Do') %>: <%= event.title %></a> | |
</div> | |
<% }); %> | |
</div> | |
</div> | |
</div> | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*********************************************************************************************************************/ | |
/* Google-powered CLNDR.js | |
/*********************************************************************************************************************/ | |
//Date.toISOString() polyfill | |
Date.prototype.toISOString || function() {function a(a) {return 10 > a ? "0" + a : a}Date.prototype.toISOString = function() {return this.getUTCFullYear() + "-" + a(this.getUTCMonth() + 1) + "-" + a(this.getUTCDate()) + "T" + a(this.getUTCHours()) + ":" + a(this.getUTCMinutes()) + ":" + a(this.getUTCSeconds()) + "." + (this.getUTCMilliseconds() / 1E3).toFixed(3).slice(2, 5) + "Z"}}(); | |
//Sort by Event Start Date, not by Event Created (using underscore.js as it is already required by CLNDR.js) | |
function sorter(input) { | |
var arr = []; | |
var returnArr = []; | |
for (var i in input) { | |
arr.push([input[i]]); | |
} | |
arr = _.sortBy(arr, function(el) { | |
return Date.parse(el[0].start.date); | |
}); | |
_.map(arr, function(el) { | |
return returnArr.push(el[0]); | |
}); | |
return returnArr; | |
} | |
// Cross Reload Cookie Saving | |
if (JSON && JSON.stringify && JSON.parse) var Session = Session || (function() { | |
// Get stored cookie data | |
var cookie = sniffCookie(); | |
function sniffCookie() { | |
var name = 'store'; | |
var result = document.cookie.match(new RegExp(name + '=([^;]+)')); | |
if (result) { | |
return JSON.parse(result[1]); | |
} | |
return {}; | |
} | |
function bakeCookie() { | |
var date = new Date(); | |
var expires; | |
date.setTime(date.getTime() + (5 * 60 * 1000)); // 5 minute cookie | |
expires = 'expires=' + date; | |
document.cookie = 'store=' + JSON.stringify(cookie) + '; ' + expires; | |
} | |
// page unload event | |
if (window.addEventListener) { | |
window.addEventListener('unload', bakeCookie, false); | |
} else if (window.attachEvent) { | |
window.attachEvent('onunload', bakeCookie); | |
} else { | |
window.onunload = bakeCookie; | |
} | |
// public methods | |
return { | |
// set a session variable | |
set: function(name, value) { | |
cookie[name] = value; | |
}, | |
// get a session value | |
get: function(name) { | |
return (cookie[name] ? cookie[name] : undefined); | |
}, | |
// clear session | |
clear: function() { | |
cookie = {}; | |
} | |
}; | |
})(); | |
function loadCalendar(e) { | |
if (e) { | |
$('#calendar').clndr({ | |
template: $('#calendar-template').html(), | |
events: e, | |
clickEvents: { | |
click: function(target) { | |
if (target.events.length) { | |
var daysContainer = $('#calendar').find('.days-container'); | |
daysContainer.toggleClass('show-events', true); | |
$('#calendar').find('.x-button').click(function() { | |
daysContainer.toggleClass('show-events', false); | |
}); | |
} | |
} | |
}, | |
adjacentDaysChangeMonth: true, | |
forceSixRows: true | |
}); | |
} | |
} | |
if ($('#home').length || $('#entertainment').length) { | |
var storedEvents = Session.get('events'); | |
if (storedEvents === undefined) { | |
var currDate = new Date(); | |
var timeMin = encodeURI('&timeMin=' + (new Date([currDate.getFullYear(), ('0' + ((currDate.getMonth() * 1) + 1)).slice(-2), '01'].join('-'))).toISOString()); | |
var googleCalendarURL = 'https://www.googleapis.com/calendar/v3/calendars/{calendar id}/events?singleEvents=true&key={API key}' + timeMin; // Only show calendar events starting from the current calendar month - repeated events displayed as individual events (singleEvents) | |
var calendarReq = new XMLHttpRequest(); | |
// Add timestamp to bypass cache | |
calendarReq.open('GET', googleCalendarURL + ((/\?/).test(googleCalendarURL) ? '&' : '?') + (new Date()).getTime(), true); | |
calendarReq.onreadystatechange = function() { | |
if (calendarReq.readyState == 4 && calendarReq.status >= 200 && calendarReq.status < 400) { | |
var calendarData = JSON.parse(calendarReq.responseText); | |
var calendarEvents = sorter(calendarData.items); | |
var len = calendarEvents.length; | |
var events = []; | |
var i; | |
for (i = 0; i < len; i++) { | |
var eventStartEnd = ''; | |
if (calendarEvents[i].start.dateTime) { | |
var startHour = moment(calendarEvents[i].start.dateTime).hour(); | |
var startMinute = ('0' + moment(calendarEvents[i].start.dateTime).minute()).slice(-2); | |
var endHour = moment(calendarEvents[i].end.dateTime).hour(); | |
var endMinute = ('0' + moment(calendarEvents[i].end.dateTime).minute()).slice(-2); | |
eventStartEnd = ' (' + startHour + ':' + startMinute + ' - ' + endHour + ':' + endMinute + ')'; | |
} | |
events.push({ | |
'date': calendarEvents[i].start.date, | |
'title': calendarEvents[i].summary + eventStartEnd, | |
'url': calendarEvents[i].htmlLink | |
}); | |
} | |
storedEvents = events; | |
loadCalendar(storedEvents); | |
Session.set('events', storedEvents); | |
} | |
}; | |
calendarReq.send(); | |
} else { | |
loadCalendar(storedEvents); | |
} | |
} | |
/*********************************************************************************************************************/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment