Skip to content

Instantly share code, notes, and snippets.

@ermauliks
Last active October 19, 2019 22:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ermauliks/4cd5ba4dd9fede6a001e91e6a13ec4b1 to your computer and use it in GitHub Desktop.
Save ermauliks/4cd5ba4dd9fede6a001e91e6a13ec4b1 to your computer and use it in GitHub Desktop.
monthly calendar with pure javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style id="jsbin-css">
table td {
text-align: center;
}
table {
font-family: "arial";
}
.greyout {
color: grey;
}
.normal {
font-weight: bold;
}
.today {
color: white;
background-color: black;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
#texts {
text-align: center;
}
</style>
</head>
<body>
<div id='calendar' />
<script id="jsbin-javascript">
class Calendar {
constructor(selector) {
this.container = document.querySelector(selector);
this.container.innerHTML += this.prepareMarkup();
this.children = {
calendar: this.container.getElementsByClassName('calendarHolder')[0],
next: this.container.getElementsByClassName('next')[0],
prev: this.container.getElementsByClassName('prev')[0],
texts: document.getElementById('texts')
}
let year = (new Date()).getFullYear();
let month = (new Date()).getMonth();
this.prepareMonthTable(year, month);
this.assignPrevNext(year, month);
}
assignPrevNext(year, month) {
this.children.next.addEventListener('click', (e) => {
month++;
if (month > 12) {
year++;
month=0;
}
this.prepareMonthTable(year, month);
});
this.children.prev.addEventListener('click', (e) => {
month--;
if (month < 0) {
year--;
month=11;
}
this.prepareMonthTable(year, month);
});
}
prepareMarkup() {
return `
<div id="texts"></div>
<div class="container">
<div><button class="prev">prev</button></div>
<div class="calendarHolder"></div>
<div><button class="next">next</button></div>
</div>
`;
}
prepareMonthTable(year, month) {
this.children.texts.innerHTML = '';
this.children.texts.appendChild(document.createTextNode(`${month + 1} / ${year}`));
let table = document.createElement('table');
let tableBody = document.createElement('tbody');
let today = new Date().getDate();
let daysInMonth = 32 - new Date(year, month, 32).getDate();
let daysInPrevMonth = 32 - new Date(year, month - 1, 32).getDate();
let date = daysInPrevMonth - (new Date(year, month)).getDay() + 1;
let isCurrentMonth = false;
let classname;
for (let i = 0; i < 6; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < 7; j++) {
let td = document.createElement('td');
if (
(!isCurrentMonth && date > daysInPrevMonth) || // < prev
isCurrentMonth && date > daysInMonth // > next month
) {
date = 1; // reset the date if we reach to the current month
isCurrentMonth = !isCurrentMonth;
}
if (!isCurrentMonth) {
classname = 'greyout';
} else if (month === (new Date()).getMonth() && date === today) {
classname = 'today';
} else {
classname = 'normal';
}
td.classList.add(classname);
td.appendChild(document.createTextNode(date));
tr.appendChild(td);
date++;
}
tableBody.appendChild(tr);
}
table.appendChild(tableBody);
this.children.calendar.innerHTML = '';
this.children.calendar.appendChild(table);
}
}
new Calendar('#calendar');
</script>
<script id="jsbin-source-css" type="text/css">table td {
text-align: center;
}
table {
font-family: "arial";
}
.greyout {
color: grey;
}
.normal {
font-weight: bold;
}
.today {
color: white;
background-color: black;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
#texts {
text-align: center;
}
</script>
<script id="jsbin-source-javascript" type="text/javascript">class Calendar {
constructor(selector) {
this.container = document.querySelector(selector);
this.container.innerHTML += this.prepareMarkup();
this.children = {
calendar: this.container.getElementsByClassName('calendarHolder')[0],
next: this.container.getElementsByClassName('next')[0],
prev: this.container.getElementsByClassName('prev')[0],
texts: document.getElementById('texts')
}
let year = (new Date()).getFullYear();
let month = (new Date()).getMonth();
this.prepareMonthTable(year, month);
this.assignPrevNext(year, month);
}
assignPrevNext(year, month) {
this.children.next.addEventListener('click', (e) => {
month++;
if (month > 12) {
year++;
month=0;
}
this.prepareMonthTable(year, month);
});
this.children.prev.addEventListener('click', (e) => {
month--;
if (month < 0) {
year--;
month=11;
}
this.prepareMonthTable(year, month);
});
}
prepareMarkup() {
return `
<div id="texts"></div>
<div class="container">
<div><button class="prev">prev</button></div>
<div class="calendarHolder"></div>
<div><button class="next">next</button></div>
</div>
`;
}
prepareMonthTable(year, month) {
this.children.texts.innerHTML = '';
this.children.texts.appendChild(document.createTextNode(`${month + 1} / ${year}`));
let table = document.createElement('table');
let tableBody = document.createElement('tbody');
let today = new Date().getDate();
let daysInMonth = 32 - new Date(year, month, 32).getDate();
let daysInPrevMonth = 32 - new Date(year, month - 1, 32).getDate();
let date = daysInPrevMonth - (new Date(year, month)).getDay() + 1;
let isCurrentMonth = false;
let classname;
for (let i = 0; i < 6; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < 7; j++) {
let td = document.createElement('td');
if (
(!isCurrentMonth && date > daysInPrevMonth) || // < prev
isCurrentMonth && date > daysInMonth // > next month
) {
date = 1; // reset the date if we reach to the current month
isCurrentMonth = !isCurrentMonth;
}
if (!isCurrentMonth) {
classname = 'greyout';
} else if (month === (new Date()).getMonth() && date === today) {
classname = 'today';
} else {
classname = 'normal';
}
td.classList.add(classname);
td.appendChild(document.createTextNode(date));
tr.appendChild(td);
date++;
}
tableBody.appendChild(tr);
}
table.appendChild(tableBody);
this.children.calendar.innerHTML = '';
this.children.calendar.appendChild(table);
}
}
new Calendar('#calendar');</script></body>
</html>
table td {
text-align: center;
}
table {
font-family: "arial";
}
.greyout {
color: grey;
}
.normal {
font-weight: bold;
}
.today {
color: white;
background-color: black;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
#texts {
text-align: center;
}
class Calendar {
constructor(selector) {
this.container = document.querySelector(selector);
this.container.innerHTML += this.prepareMarkup();
this.children = {
calendar: this.container.getElementsByClassName('calendarHolder')[0],
next: this.container.getElementsByClassName('next')[0],
prev: this.container.getElementsByClassName('prev')[0],
texts: document.getElementById('texts')
}
let year = (new Date()).getFullYear();
let month = (new Date()).getMonth();
this.prepareMonthTable(year, month);
this.assignPrevNext(year, month);
}
assignPrevNext(year, month) {
this.children.next.addEventListener('click', (e) => {
month++;
if (month > 12) {
year++;
month=0;
}
this.prepareMonthTable(year, month);
});
this.children.prev.addEventListener('click', (e) => {
month--;
if (month < 0) {
year--;
month=11;
}
this.prepareMonthTable(year, month);
});
}
prepareMarkup() {
return `
<div id="texts"></div>
<div class="container">
<div><button class="prev">prev</button></div>
<div class="calendarHolder"></div>
<div><button class="next">next</button></div>
</div>
`;
}
prepareMonthTable(year, month) {
this.children.texts.innerHTML = '';
this.children.texts.appendChild(document.createTextNode(`${month + 1} / ${year}`));
let table = document.createElement('table');
let tableBody = document.createElement('tbody');
let today = new Date().getDate();
let daysInMonth = 32 - new Date(year, month, 32).getDate();
let daysInPrevMonth = 32 - new Date(year, month - 1, 32).getDate();
let date = daysInPrevMonth - (new Date(year, month)).getDay() + 1;
let isCurrentMonth = false;
let classname;
for (let i = 0; i < 6; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < 7; j++) {
let td = document.createElement('td');
if (
(!isCurrentMonth && date > daysInPrevMonth) || // < prev
isCurrentMonth && date > daysInMonth // > next month
) {
date = 1; // reset the date if we reach to the current month
isCurrentMonth = !isCurrentMonth;
}
if (!isCurrentMonth) {
classname = 'greyout';
} else if (month === (new Date()).getMonth() && date === today) {
classname = 'today';
} else {
classname = 'normal';
}
td.classList.add(classname);
td.appendChild(document.createTextNode(date));
tr.appendChild(td);
date++;
}
tableBody.appendChild(tr);
}
table.appendChild(tableBody);
this.children.calendar.innerHTML = '';
this.children.calendar.appendChild(table);
}
}
new Calendar('#calendar');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment