Простой календарь Javascript с событиями

Готовый скрипт календаря с событиями.

html

Создаём файл calendar.html с таким содержимым.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Простой календарь Javascript с событиями</title>
<link href="calendar.css" rel="stylesheet">
<script async src="calendar.js"></script>
</head>
<body>
<div id="cal-wrap">
<!-- ВЫБОР ПЕРИОДА -->
<div id="cal-date">
<select id="cal-mth"></select>
<select id="cal-yr"></select>
</div>
<!-- КАЛЕНДАРЬ -->
<div id="cal-container"></div>
<!-- ФОРМА СОБЫТИЯ -->
<form id="cal-event">
<h1 id="evt-head"></h1>
<div id="evt-date"></div>
<textarea id="evt-details" required></textarea>
<input id="evt-close" type="button" value="Закрыть"/>
<input id="evt-del" type="button" value="Удалить"/>
<input id="evt-save" type="submit" value="Сохранить"/>
</form>
</div>
</body>
</html>

js

Создайте файл calendar.js с таким содержимым.

let cal = {
// ХАРАКТЕРИСТИКИ
// ОБЩИЙ КАЛЕНДАРЬ
sMon: false, // Неделя начинается в понедельник?
mName: ["Янв", "Фев", "Март", "Апр", "Май", "Июнь", "Июль", "Авг", "Сен", "Окт", "Ноя", "Дек"], // Названия месяцев
// КАЛЕНДАРНЫЕ ДАННЫЕ
data: null, // События за выбранный период
sDay: 0,
sMth: 0,
sYear: 0, // Текущий выбранный день, месяц, год
// ОБЩИЕ HTML-ЭЛЕМЕНТЫ
hMth: null,
hYear: null, // выбор месяца/года
hForm: null,
hfHead: null,
hfDate: null,
hfTxt: null,
hfDel: null, // форма события
// КАЛЕНДАРЬ НАЧАЛА
init : () => {
// ПОЛУЧИТЬ + УСТАНОВИТЬ ОБЩИЕ ЭЛЕМЕНТЫ HTML
cal.hMth = document.querySelector("#cal-mth");
cal.hYear = document.querySelector("#cal-yr");
cal.hForm = document.querySelector("#cal-event");
cal.hfHead = document.querySelector("#evt-head");
cal.hfDate = document.querySelector("#evt-date");
cal.hfTxt = document.querySelector("#evt-details");
cal.hfDel = document.querySelector("#evt-del");
document.querySelector("#evt-close").onclick = cal.close;
cal.hfDel.onclick = cal.del;
cal.hForm.onsubmit = cal.save;
// ДАТА СЕЙЧАС
let now = new Date(),
nowMth = now.getMonth(),
nowYear = parseInt(now.getFullYear());
// ДОБАВИТЬ ВЫБОР МЕСЯЦЕВ
for (let i=0; i<12; i++) {
let opt = document.createElement("option");
opt.value = i;
opt.innerHTML = cal.mName[i];
if (i==nowMth) { opt.selected = true; }
cal.hMth.appendChild(opt);
}
cal.hMth.onchange = cal.list;
// ДОБАВИТЬ ВЫБОР ГОДОВ
// Установим в диапазоне 10 лет. Измените это, как вам нравится.
for (let i=nowYear-10; i<=nowYear+10; i++) {
let opt = document.createElement("option");
opt.value = i;
opt.innerHTML = i;
if (i==nowYear) { opt.selected = true; }
cal.hYear.appendChild(opt);
}
cal.hYear.onchange = cal.list;
// СТАРТ - ВЫВОДА КАЛЕНДАРЯ
cal.list();
},
// СОЗДАТЬ КАЛЕНДАРЬ НА ВЫБРАННЫЙ МЕСЯЦ
list : () => {
// ОСНОВНЫЕ РАСЧЕТЫ - ДНИ В МЕСЯЦЕ, ДЕНЬ НАЧАЛА + КОНЕЦ
// Примечание. Январь равен 0, а декабрь — 11.
// Примечание. Вс – 0, а сб – 6.
cal.sMth = parseInt(cal.hMth.value); // выбранный месяц
cal.sYear = parseInt(cal.hYear.value); // выбранный год
let daysInMth = new Date(cal.sYear, cal.sMth+1, 0).getDate(), // количество дней в выбранном месяце
startDay = new Date(cal.sYear, cal.sMth, 1).getDay(), // первый день месяца
endDay = new Date(cal.sYear, cal.sMth, daysInMth).getDay(), // последний день месяца
now = new Date(), // текущая дата
nowMth = now.getMonth(), // текущий месяц
nowYear = parseInt(now.getFullYear()), // текущий год
nowDay = cal.sMth==nowMth && cal.sYear==nowYear ? now.getDate() : null ;
// ЗАГРУЗИТЬ ДАННЫЕ ИЗ ЛОКАЛЬНОГО ХРАНИЛИЩА
cal.data = localStorage.getItem("cal-" + cal.sMth + "-" + cal.sYear);
if (cal.data==null) {
localStorage.setItem("cal-" + cal.sMth + "-" + cal.sYear, "{}");
cal.data = {};
} else {
cal.data = JSON.parse(cal.data);
}
// ЧЕРТЕЖНЫЕ РАСЧЕТЫ
// Пустые квадраты перед началом месяца
let squares = [];
if (cal.sMon && startDay != 1) {
let blanks = startDay==0 ? 7 : startDay ;
for (let i=1; i }
if (!cal.sMon && startDay != 0) {
for (let i=0; i }
// Дни месяца
for (let i=1; i<=daysInMth; i++) { squares.push(i); }
// Пустые квадраты после окончания месяца
if (cal.sMon && endDay != 0) {
let blanks = endDay==6 ? 1 : 7-endDay;
for (let i=0; i }
if (!cal.sMon && endDay != 6) {
let blanks = endDay==0 ? 6 : 6-endDay;
for (let i=0; i }
// ВЫВЕСТИ HTML КАЛЕНДАРЬ
// Получить контейнер
let container = document.querySelector("#cal-container"),
cTable = document.createElement("table");
cTable.id = "calendar";
container.innerHTML = "";
container.appendChild(cTable);
// Первая строка - названия дней
let cRow = document.createElement("tr"),
days = ["Вс", "пн", "Вт", "Ср", "Чт", "пт", "Сб"];
if (cal.sMon) { days.push(days.shift()); }
for (let d of days) {
let cCell = document.createElement("td");
cCell.innerHTML = d;
cRow.appendChild(cCell);
}
cRow.classList.add("head");
cTable.appendChild(cRow);
// Дни в месяце
let total = squares.length;
cRow = document.createElement("tr");
cRow.classList.add("day");
for (let i=0; i let cCell = document.createElement("td");
if (squares[i]=="b") { cCell.classList.add("blank"); }
else {
if (nowDay==squares[i]) { cCell.classList.add("today"); }
cCell.innerHTML = `<div class="dd">${squares[i]}</div>`;
if (cal.data[squares[i]]) {
cCell.innerHTML += "<div class='evt'>" + cal.data[squares[i]] + "</div>";
}
cCell.onclick = () => { cal.show(cCell); };
}
cRow.appendChild(cCell);
if (i!=0 && (i+1)%7==0) {
cTable.appendChild(cRow);
cRow = document.createElement("tr");
cRow.classList.add("day");
}
}
// УДАЛИТЬ ЛЮБУЮ ПРЕДЫДУЩУЮ ДОБАВЛЕНИЕ/РЕДАКТИРОВАНИЕ СОБЫТИЙ DOCKET
cal.close();
},
// ПОКАЗАТЬ РЕДАКТИРОВАНИЕ СОБЫТИЙ ДЛЯ ВЫБРАННОГО ДНЯ
show : (el) => {
// ПОЛУЧИТЬ СУЩЕСТВУЮЩИЕ ДАННЫЕ
cal.sDay = el.getElementsByClassName("dd")[0].innerHTML;
let isEdit = cal.data[cal.sDay] !== undefined ;
// ОБНОВИТЬ ФОРМУ МЕРОПРИЯТИЯ
cal.hfTxt.value = isEdit ? cal.data[cal.sDay] : "" ;
cal.hfHead.innerHTML = isEdit ? "EDIT EVENT" : "ADD EVENT" ;
cal.hfDate.innerHTML = `${cal.sDay} ${cal.mName[cal.sMth]} ${cal.sYear}`;
if (isEdit) { cal.hfDel.classList.remove("ninja"); }
else { cal.hfDel.classList.add("ninja"); }
cal.hForm.classList.remove("ninja");
},
// СОБЫТИЕ ЗАКРЫТЬ
close : () => {
cal.hForm.classList.add("ninja");
},
// СОБЫТИЕ СОХРАНИТЬ
save : () => {
cal.data[cal.sDay] = cal.hfTxt.value;
localStorage.setItem(`cal-${cal.sMth}-${cal.sYear}`, JSON.stringify(cal.data));
cal.list();
return false;
},
// СОБЫТИЕ УДАЛИТЬ НА ВЫБРАННУЮ ДАТУ
del : () => { if (confirm("Delete event?")) {
delete cal.data[cal.sDay];
localStorage.setItem(`cal-${cal.sMth}-${cal.sYear}`, JSON.stringify(cal.data));
cal.list();
}}
};
window.addEventListener("load", cal.init);

css

Создайте файл calendar.css с таким содержимым.

/* вся страница */
#cal-wrap * {
font-family: arial, sans-serif;
}
.ninja {
display: none !important;
}
/* CONTAINER */
#cal-wrap {
max-width: 600px;
}
/* ВЫБОР ПЕРИОДА */
#cal-date {
display: flex;
}
#cal-mth, #cal-yr {
box-sizing: border-box;
padding: 10px 20px;
font-size: 1.2em;
border: 0;
}
/* КАЛЕНДАРЬ */
#calendar {
width: 100%;
border-collapse: collapse;
}
#calendar tr.head td {
font-weight: bold;
text-transform: uppercase;
color: #fff;
background: #f37070;
padding: 15px;
text-align: center;
}
#calendar tr.day td {
border: 1px solid #ddd;
width: 14.28%;
padding: 15px 5px;
vertical-align: top;
}
#calendar tr.day td:hover {
background: #fff9e4;
cursor: pointer;
}
#calendar tr td.blank {
background: #f5f5f5;
}
#calendar tr td.today {
background: #ffdede;
}
#calendar .dd {
font-size: 1.2em;
color: #999;
}
#calendar .evt {
margin-top: 5px;
font-size: 0.8em;
font-weight: bold;
overflow: hidden;
color: #ff5d5d;
}
/* ДОБАВИТЬ/РЕДАКТИРОВАТЬ СОБЫТИЕ */
#cal-event {
padding: 15px;
margin-top: 20px;
background: #f5f5f5;
border: 1px solid #ddd;
}
#cal-event h1 {
color: #333;
padding: 0;
margin: 0;
}
#evt-date {
color: #555;
margin: 10px 0;
}
#cal-event textarea {
display: block;
box-sizing: border-box;
width: 100%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ddd;
min-height: 100px;
}
#cal-event input[type=button], #cal-event input[type=submit] {
padding: 10px;
margin: 5px;
font-size: 1.2em;
border: 0;
background: #ea4c4c;
color: #fff;
}

Можете посмотреть и скачать пример.
Посмотреть
Скачать

Обсуждение закрыто.