Skip to content

Instantly share code, notes, and snippets.

@13twelve
Created January 31, 2017 18:54
Show Gist options
  • Save 13twelve/2d4ba846e9818232fd2528ae5c7b2c60 to your computer and use it in GitHub Desktop.
Save 13twelve/2d4ba846e9818232fd2528ae5c7b2c60 to your computer and use it in GitHub Desktop.
.calendar {
@include font__ui;
}
.calendar__title {
display: block;
padding: 19px 45px;
font-weight: normal;
text-align: center;
}
.calendar .icon__arrow--right,
.calendar .icon__arrow--left {
position: absolute;
top: 30px;
right: 20px;
opacity: .2;
&:hover {
opacity: 1;
}
}
.calendar .icon__arrow--left {
right: auto;
left: 20px;
}
.calendar table {
width: 100%;
text-align: center;
table-layout: fixed;
color: $color__text--label;
}
.calendar thead th {
padding-bottom: 10px;
font-weight: normal;
}
.calendar__today {
color: $color__text--subtle;
}
.calendar table a {
display: inline-block;
width: 30px;
height: 30px;
background-color: $color__highlight;
color: $color__black;
line-height: 33px;
border-radius: 50%;
@include breakpoint-up(medium) {
width: 40px;
height: 40px;
line-height: 40px;
}
&:hover {
background-color: $color__separator;
color: $color__text--label;
}
}
<script>A17.importantDates = ["20160609","20160614"];</script>
<div class="calendar" data-behavior="calendar" data-filters-dd>
<b class="calendar__title" data-calendar-title></b>
<table>
<thead>
<tr>
<th title="Sunday">S</th>
<th title="Monday">M</th>
<th title="Tuesday">T</th>
<th title="Wednesday">W</th>
<th title="Thursday">T</th>
<th title="Friday">F</th>
<th title="Saturday">S</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<a href="#" class="icon icon__arrow--right" data-calendar-next>Next</a>
<a href="#" class="icon icon__arrow--left" data-calendar-prev>Prev</a>
</div>
A17.Behaviors.calendar = function(el){
var today = new Date();
var today_date = today.getDate();
var today_month = today.getMonth();
var today_year = today.getFullYear();
var search_url = '/events';
var current_month;
var current_year;
var months = [];
var month_length = [];
var days_html = '';
var important_dates = A17.importantDates || [];
var important_dates_l = important_dates.length;
for (var i = 0; i < important_dates_l; i++) {
var important_date = important_dates[i];
var type_of_important_date = (typeof important_date).toLowerCase();
if (type_of_important_date !== 'object') {
if (type_of_important_date === 'number') {
type_of_important_date = type_of_important_date.toString();
}
important_dates[i] = {
year: parseInt(important_date.substring(0,4)),
month: parseInt(important_date.substring(4,6) - 1),
date: parseInt(important_date.substring(6,8))
};
} else {
important_dates.splice(i, 1);
}
}
// give the months some names
months[0] = 'January';
months[1] = 'February';
months[2] = 'March';
months[3] = 'April';
months[4] = 'May';
months[5] = 'June';
months[6] = 'July';
months[7] = 'August';
months[8] = 'September';
months[9] = 'October';
months[10] = 'November';
months[11] = 'December';
// how many days in each month
month_length[0] = 31;
month_length[1] = 28; // will be updated in generate calendar func for leap years
month_length[2] = 31;
month_length[3] = 30;
month_length[4] = 31;
month_length[5] = 30;
month_length[6] = 31;
month_length[7] = 31;
month_length[8] = 30;
month_length[9] = 31;
month_length[10] = 30;
month_length[11] = 31;
function generate_calendar(year, month) {
// update vars
current_month = month;
current_year = year;
// JS this date
var the_date = new Date(year, month);
// is leap year?
var is_leap_year = (new Date(year, 1, 29).getMonth() === 1);
// update length of February as required
month_length[1] = (is_leap_year) ? 29 : 28;
// what day within the week is the first day of the month?
var first_day_of_month = new Date(year, month).getDay();
// we want to loop a multiple of 7 days and add spaces around the actual starting day
var loop_month_length = month_length[month] + first_day_of_month;
// make that loop length a multiple of 7
while(loop_month_length % 7 > 0) {
loop_month_length++;
}
// check against important dates this month in this year
var this_month_important_dates = '';
var this_month_important_dates_regex = false;
if (important_dates.length > 0) {
for (var i = 0; i < important_dates_l; i++) {
if (month === important_dates[i].month && year === important_dates[i].year) {
this_month_important_dates = this_month_important_dates + ':' + important_dates[i].date + ':|';
}
}
if (this_month_important_dates.length > 0) {
this_month_important_dates = this_month_important_dates.slice(0, -1);
// make regex for testing
this_month_important_dates_regex = new RegExp(this_month_important_dates);
}
}
// generate HTML
// open new tr
days_html = '<tr>';
// now loop
for (var i = 1; i <= loop_month_length; i++) {
var this_day = '';
var td_className = '';
// the gaps for if a month doesn't start on monday and to make the total TDs a multiple of 7
if (i <= first_day_of_month || i > (month_length[month] + first_day_of_month)) {
this_day = '&nbsp;';
} else {
// normalize date
var current_date = (i - first_day_of_month);
// is this today?
if (current_date === today_date && month === today_month && year === today_year) {
td_className = 'calendar__today';
}
// see if we match an important date
// using regex for speed and so I don't have to do another loop in a loop
if (this_month_important_dates_regex && this_month_important_dates_regex.test(':' + current_date + ':')) {
var url_month = (month + 1);
url_month = (url_month < 10) ? '0' + url_month : url_month.toString();
var url_day = (current_date < 10) ? '0' + current_date : current_date.toString();
this_day = '<a href="'+ search_url + '?date=' + year.toString() + url_month + url_day + '" data-date="' + year.toString() + url_month + url_day + '">' + current_date + '</a>';
}
// lastly, this must be a day with no events
if (this_day === '') {
this_day = current_date;
}
}
// update HTML string, adding new table rows when needed
days_html = days_html + '<td class="' + td_className + '">' + this_day + '</td>\n' + ((i !== 0 && i !== loop_month_length && i % 7 === 0) ? '</tr>\n<tr>\n' : '');
}
// close that last tr
days_html += '</tr>';
// insert the html
$('[data-calendar-title]',el)[0].textContent = months[month] + ' ' + year;
$('tbody',el)[0].innerHTML = days_html;
// set up clicks from links
$('table a',el).on('click',function(event){
var date = this.getAttribute("data-date") || false;
if (date) {
event.preventDefault();
$(document).trigger("filter_event",{
date: date
});
}
});
}
function normalise_yearMonth(){
// if months over 11 (December), we must be wanting January a year later
if (current_month > 11) {
current_month = 0;
current_year++;
}
// if months under 0 (January), we must be wanting December last year
if (current_month < 0) {
current_month = 11;
current_year--;
}
}
// click events for next/prev buttons
$('[data-calendar-next]',el).on('click',function(event){
event.preventDefault();
event.stopPropagation();
current_month++;
normalise_yearMonth();
generate_calendar(current_year, current_month);
});
$('[data-calendar-prev]',el).on('click',function(event){
event.preventDefault();
event.stopPropagation();
current_month--;
normalise_yearMonth();
generate_calendar(current_year, current_month);
});
// default to showing the current months calendar
generate_calendar(today.getFullYear(), today.getMonth());
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment