UI-Calendar, a pure JS/CSS calendar
posted on April 24, 2015, 2:18 pm in
A pure JavaScript Calendar input element, acts like a form input and easy styling with CSS.
The Code
JavaScript
/*
* UI-Calendar (April 24 2015)
* Copyright 2015, http://codeeverywhere.ca
* Licensed under the MIT license.
*/
(function() {
var longName = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December'
];
var shortName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var createAndAddElement = function(el, className, text, appendTo) {
var el = document.createElement(el);
if (className.length > 0) {
el.className = className;
}
if (text.length > 0) {
text = document.createTextNode(text);
el.appendChild(text);
}
appendTo.appendChild(el);
};
var loadMonth = function(year, month, cal) {
var
month = month - 1, //since js dates are 0-11
t = new Date(), //today
isEmpty = month === undefined || year === undefined || month > 11 || month < 0 || year < 0,
month = isEmpty ? t.getMonth() : month,
year = isEmpty ? t.getFullYear() : year,
d = new Date(year, month, 1),
daysInCurMonth = new Date(year, month + 1, 0).getDate(),
nextMonth = (month + 1 + 12) % 12, //+12 because javascript doesn't like -1 % mod
nextMonthIsInYear = month == 11 ? year + 1 : year,
prevMonth = (month - 1 + 12) % 12,
prevMonthIsInYear = month === 0 ? year - 1 : year,
daysInPrevMonth = new Date(prevMonthIsInYear, prevMonth + 1, 0).getDate(),
inMonth = -1,
day = daysInPrevMonth - d.getDay() + 1,
dateString = '',
curMonth = longName[d.getMonth()] + ' ' + d.getFullYear(),
headings = ["S", "M", "T", "W", "H", "F", "S"];
var prev = {
year: prevMonthIsInYear,
month: prevMonth + 1 //set correct 1-12 scale
};
var next = {
year: nextMonthIsInYear,
month: nextMonth + 1 //set correct 1-12 scale
};
//delete children
while (cal.firstChild) {
cal.removeChild(cal.firstChild);
}
createAndAddElement("div", "ui-calendar-left", "❮ " + shortName[prev.month - 1], cal);
createAndAddElement("div", "ui-calendar-center", curMonth, cal);
createAndAddElement("div", "ui-calendar-right", shortName[next.month - 1] + " ❯", cal);
cal.getElementsByClassName("ui-calendar-left")[0]
.addEventListener("click", function() {
loadMonth(prev.year, prev.month, cal);
}, false);
cal.getElementsByClassName("ui-calendar-center")[0]
.addEventListener("click", function() {
loadMonth(2015, 4, cal);
}, false);
cal.getElementsByClassName("ui-calendar-right")[0]
.addEventListener("click", function() {
loadMonth(next.year, next.month, cal);
}, false);
createAndAddElement("div", "ui-calendar-clear", "", cal);
for (var x = 0; x < headings.length; x++)
createAndAddElement("div", "ui-calendar-heading", headings[x], cal);
createAndAddElement("div", "ui-calendar-clear", "", cal);
for (var x = 0; x < 6; x++) {
for (var y = 0; y <= 6; y++) {
var div = document.createElement("div");
if (inMonth == -1 && day == daysInPrevMonth + 1) {
//move to current month, set day = 1
inMonth = 0;
day = 1;
div.className = "ui-calendar-day";
} else if (inMonth === 0 && day === t.getDate() && month == t.getMonth()) {
//highlight today
div.className = "ui-calendar-day ui-calendar-today";
} else if (inMonth === 0 && day == t.getDate() + 1) {
div.className = "ui-calendar-day";
} else if (inMonth === 0 && day == daysInCurMonth + 1) {
//move to next month, set day = 1
inMonth = 1;
day = 1;
div.className = "ui-calendar-day ui-calendar-light";
} else if (inMonth == -1 || inMonth == 1) {
div.className = "ui-calendar-day ui-calendar-light";
} else {
div.className = "ui-calendar-day";
}
switch (inMonth) {
case -1:
dateString = prevMonthIsInYear + '-' + (prevMonth + 1) + '-' + day;
break;
case 0:
dateString = year + '-' + (month + 1) + '-' + day;
break;
case 1:
dateString = nextMonthIsInYear + '-' + (nextMonth + 1) + '-' + day;
break;
}
var text = document.createTextNode(day);
div.appendChild(text);
div.title = dateString;
cal.appendChild(div);
//add click
div.addEventListener("click", function() {
cal.parentNode.getElementsByTagName("input")[0].value = this.title;
cal.className = "ui-calendar-dropdown ui-calendar-hide";
}, false);
div = null;
day++;
}
createAndAddElement("div", "ui-calendar-clear", "", cal);
}
};
//------------------------
//find .ui-calendar elements
var uiCalendars = document.getElementsByClassName("ui-calendar");
for (var x = 0; x < uiCalendars.length; x++) {
var uiCalendar = uiCalendars[x];
var input = document.createElement("input");
input.type = "text";
input.name = uiCalendar.getAttribute("data-name");
uiCalendar.appendChild(input);
createAndAddElement("div", "ui-calendar-dropdown", "", uiCalendar);
var uiCalendarDropdown = uiCalendar.getElementsByClassName("ui-calendar-dropdown");
if (uiCalendarDropdown.length == 1) {
uiCalendarDropdown = uiCalendarDropdown[0];
uiCalendarDropdown.className = "ui-calendar-dropdown ui-calendar-hide";
loadMonth(0, 0, uiCalendarDropdown);
var input = uiCalendar.getElementsByTagName("input")[0];
input.addEventListener("click", function() {
this.parentNode
.getElementsByClassName("ui-calendar-dropdown")[0]
.className = "ui-calendar-dropdown ui-calendar-show";
}, false);
uiCalendar.getElementsByTagName("input")[0].value = "Please Select A Date";
}
uiCalendarDropdown = null;
uiCalendar = null;
}
})();
CSS
.ui-calendar{ position: relative; }
.ui-calendar > input{
font-size: 16px;
width: 247px;
padding: 5px;
}
.ui-calendar-show{ display: block; }
.ui-calendar-hide{ display: none; }
.ui-calendar-left, .ui-calendar-right{
display: inline-block;
width: 65px;
color: red;
text-align: center;
cursor: pointer;
}
.ui-calendar-center{
width: 115px;
display: inline-block;
text-align: center;
}
.ui-calendar-today{ color: red; }
.ui-calendar-dropdown{
border: 1px solid #bbbbbb;
padding-top: 5px;
width: 245px;
position: absolute;
background: white;
box-shadow: 0px 0px 8px #c0c0c0;
z-index: 9;
}
.ui-calendar-heading{
display: inline-block;
width: 35px;
height: 25px;
padding-top: 10px;
text-align: center;
margin: 0;
border-bottom: 1px solid #eaeaea;
color: #cccccc
}
.ui-calendar-day{
display: inline-block;
cursor: pointer;
width: 35px;
height: 25px;
padding-top: 10px;
text-align: center;
margin: 0;
border-radius: 25px;
}
.ui-calendar-day:hover{
color: #fff;
background: red;
}
.ui-calendar-clear{ clear: both; }
.ui-calendar-light{ color: #e2e2e2; }
example usage
Add the JS and CSS to your page, then use:
<div class="ui-calendar" data-name="abc"></div>
The data-name attribute is the input fields name.
Online Demo
Online demo: jsfiddle.net/5on6otga/1/