Skip to content

Instantly share code, notes, and snippets.

@netsi1964
Created January 5, 2016 08:27
Show Gist options
  • Save netsi1964/82f18735fec6777eb79e to your computer and use it in GitHub Desktop.
Save netsi1964/82f18735fec6777eb79e to your computer and use it in GitHub Desktop.
Building a calendar

Building a calendar

I wanted to exercise my raw javascript and css - no Bootstrap, no jQuery, no AngularJS - all by myself. So here goes: A calendar build using basic* web technologi. *) I however used SCSS, trying to create the css faster and more flexible.

A Pen by Sten Hougaard on CodePen.

License.

<div class="container"></div>
/*global $, localStorage, angular, alert, document, console, confirm, require */
/*jshint unused:false */
/*jshint plusplus: false, devel: true, nomen: true, indent: 4, maxerr: 50 */
// Methods
Date.prototype.addDays = function (days) {
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
};
var dateStart = new Date(2016, 0, 1);
var dateEnd = dateStart.addDays(365);
Date.prototype.getComparableString = function (seperator) {
seperator = (typeof seperator !== "undefined") ? seperator : "-";
var d = new Date();
return this.getFullYear() + seperator + this.getMonth() + seperator + this.getDate();
};
function createElement(tag, attributes, value) {
var ele = document.createElement(tag);
for (var name in attributes) {
var attr = document.createAttribute(name);
attr.value = attributes[name];
ele.setAttributeNode(attr);
if (typeof value !== "undefined") {
ele.innerHTML = value;
}
}
return ele;
}
function extend(objSource, objExtend) {
for (var attr in objExtend) {
objSource[attr] = objExtend[attr];
}
return objSource;
}
function generateDay(date, iRelativeWeek, extraClass, text, iDayOfWeek) {
var sClass = "day" + ((typeof extraClass !== "undefined") ? " " + extraClass : "");
var month = (typeof date.getMonth === "function") ? " " + monNames[date.getMonth()] : "";
if (sClass.indexOf("past") === -1) {
var past = (typeof date.getMonth === "function") ? ((today - date > iDay) ? " past" : "") : "";
sClass += past;
}
sClass += month;
var options = {
"class": sClass,
"data-dayofweek": (typeof iDayOfWeek !== "undefined") ? iDayOfWeek : date.getDay(),
"data-relativeweek": iRelativeWeek,
"data-month": month
};
text = (typeof text !== "undefined") ? text : iDayOfWeek;
return createElement("li", options, text);
}
function addDays(calendar, dateStart, dateEnd) {
for (var i = dateStart.valueOf(); i < dateEnd.valueOf(); i += iDay) {
var thisDay = new Date(i);
var iDayOfWeek = thisDay.getDay();
var extraClass = "";
if (todayCompareable === thisDay.getComparableString()) {
extraClass = "today";
}
var day = generateDay(thisDay, iRelativeWeek, extraClass, thisDay.getDate());
calendar.appendChild(day);
iRelativeWeek += (iNewWeekOnDay == iDayOfWeek) ? 1 : 0;
}
}
// Properties
var iSecond = 1000;
var iMinute = iSecond * 60;
var iHour = iMinute * 60;
var iDay = iHour * 24;
var iWeek = iDay * 7;
var iMonth = iDay * 31;
var iYear = iDay * 365;
var container = document.querySelector(".container");
var log = document.querySelector(".log");
var dayNames = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
var monNames = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
var today = new Date();
var todayCompareable = today.getComparableString();
var temp = [6, 0, 1, 2, 3, 4, 5];
// Setup
var bMondayFirst = true;
var iNewWeekOnDay = (bMondayFirst) ? 0 : 6;
var calendar = createElement("ul", {
"class": "calendar" + ((bMondayFirst) ? " mondayFirst" : "")
});
var iRelativeWeek = 0;
// Create header
for (var dow = 0; dow < 7; dow++) {
var day = generateDay("", -1, "header", dayNames[dow], dow);
calendar.appendChild(day);
}
// Create days before current day in current week
var past = [];
var testDate = dateStart;
var iDayOfWeek = temp[testDate.getDay()];
for (var i = iDayOfWeek; i >= 0; i--) {
past.push(testDate);
testDate -= iDay;
}
for (var i = past.length - 1; i > 0; i--) {
var thisDay = new Date(past[i]);
var iDayOfWeek = thisDay.getDay();
var day = generateDay(thisDay, iRelativeWeek, "past", thisDay.getDate());
calendar.appendChild(day);
}
// Make sure that end will be on a sunday
var iDayOfWeek = new Date(dateEnd.valueOf() + iDay).getDay();
if (iDayOfWeek < 7) {
dateEnd = dateEnd.valueOf() + (7 - iDayOfWeek) * iDay;
}
// Create main timespan
addDays(calendar, dateStart, dateEnd);
// Year
var year = createElement("h1", {
"class": "year"
}, dateStart.getFullYear());
container.appendChild(year);
container.appendChild(calendar);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
@import url(http://fonts.googleapis.com/css?family=Roboto:400,900);
$yearHeight: 60px;
$dayHeight: 35px;
$dayWidth: 35px;
$maxWeeks: 120;
$headerHeight: $dayHeight*.75;
$dayToTakeMonth: 4; /* How many days for a month to claim a row as its month?*/
$bgcolor: rgba(68,97,157,1);
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serif;
font-weight: bold;
background: black;
padding: 0;
margin: 0;
}
.container {
position: relative;
width: $dayWidth*8;
background: $bgcolor;
border-width: 0;
height: $maxWeeks*$dayHeight/7+$yearHeight;
}
.container .calendar {
position: absolute;
width: $dayWidth*7;
margin: 0;
padding: 0;
}
.day {
display: inline-block;
list-style: none;
margin: 0;
padding: ($dayHeight*.25) 0;
position: absolute;
text-align: center;
width: $dayWidth;
height: $dayHeight;
}
.today {
background-color: rgba(255,165,0,.9) !Important;
/*rgba(80,24,137,1) */
color: black;
}
.today:before {
opacity: 1;
width: 0;
left: 0;
-webkit-transition: all .7s ease;
}
.today:hover:after {
-webkit-transition: all .7s ease;
content: "Today";
position: absolute;
top: 0;
left: -60px;
background-color: rgba(0,0,0,.4);
z-index: 21;
padding: ($dayHeight*.25) 5px;
text-shadow: none;
letter-spacing: 1px;
font-weight: normal;
width: auto;
}
.past {
color: rgba(120,120,120,.51);
}
/* week relative to top position*/
@for $i from 0 through 55 {
[data-relativeweek="#{$i}"] {
top: ($dayHeight*$i+$headerHeight)+$yearHeight;
}
}
/* x position of day*/
@for $i from 1 through 7 {
.mondayFirst [data-dayofweek="#{$i % 7}"] {
left: ($dayWidth*$i);
}
}
/* header*/
@for $i from 0 through 6 {
[data-dayofweek="#{$i % 7}"].header {
left: $dayWidth*$i+$dayWidth;
}
}
/* month */
.jan, .jan[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(153,204,255,1) ;
}
.feb, .feb[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(204,255,255,1);
}
.mar, .mar[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(51,204,204,1);
}
.apr, .apr[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(204,255,204,1);
}
.may, .may[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(153,204,0,1);
}
.jun, .jun[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(255,255,153,1);
}
.jul, .jul[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(255,204,0,1);
}
.aug, .aug[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(255,153,0,1);
}
.sep, .sep[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(255,102,0,1);
}
.oct, .oct[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(255,128,128,1);
}
.nov, .nov[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(204,153,255,1);
}
.dec, .dec[data-dayofweek='#{$dayToTakeMonth}']:before {
background-color: rgba(204,204,255,1);
}
/* header */
.header {
text-transform: uppercase;
font-size: .70em;
font-weight: bold;
top: $yearHeight;
background: black;
color: white;
padding: 6px 0 0;
height: $headerHeight;
position: absolute;
left: 0;
z-index: 10;
}
.header:nth-child(n+6) {
background-color: rgba(24,137,80,1);
color: white;
}
.day[data-dayofweek='#{$dayToTakeMonth}']:before {
content: attr(data-month);
position: absolute;
left: -($dayWidth*$dayToTakeMonth)-1;
top: 0;
width: $dayWidth;
color: black;
font-weight: normal;
text-transform: capitalize;
font-size: smaller;
padding: ($dayHeight*.25) 0;
height: ($dayHeight - ($dayHeight*.25)*2);
}
.year {
position: absolute;
top: -30px;
color: yellow;
right: 10px;
z-index: 20;
font-size: 48px;
opacity: .8;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment