Created
August 11, 2022 07:11
-
-
Save Akifcan/0fb4fa1bfe3fb68d8bf2e8c9d78713a6 to your computer and use it in GitHub Desktop.
Calendar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Document</title> | |
<style> | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
font-family: sans-serif; | |
} | |
body { | |
display: grid; | |
place-items: center; | |
min-height: 100vh; | |
} | |
.calendar { | |
width: 275px; | |
} | |
.calendar header { | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
} | |
.calendar .day-names { | |
margin-block: 1rem; | |
display: grid; | |
grid-template-columns: repeat(7, 1fr); | |
text-align: center; | |
} | |
.calendar .days { | |
margin-block: 1rem; | |
text-align: center; | |
display: grid; | |
grid-template-columns: repeat(7, 1fr); | |
gap: .4rem; | |
} | |
.calendar .days .day { | |
cursor: pointer; | |
background-color: #dedede; | |
height: 30px; | |
display: grid; | |
place-items: center; | |
border-radius: .5rem; | |
} | |
.calendar .days .day.active { | |
background-color: blue !important; | |
color: white !important; | |
} | |
.calendar .days .day.clicked { | |
background-color: gray; | |
color: white; | |
} | |
.calendar .days .day.between { | |
background-color: gray; | |
opacity: .5; | |
color: white; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="calendar" id="calendar"> | |
<header> | |
<button id="prev">prev</button> | |
<h3 id="current-day">July 2022</h3> | |
<button id="next">next</button> | |
</header> | |
<div class="day-names"> | |
<p>Mon</p> | |
<p>Tue</p> | |
<p>Wed</p> | |
<p>Thru</p> | |
<p>Fri</p> | |
<p>Sat</p> | |
<p>Sun</p> | |
</div> | |
<div class="days"> | |
</div> | |
</div> | |
<script> | |
const calendar = document.getElementById("calendar") | |
calendar.addEventListener('daysPicked', (e) => { | |
console.log(e.detail) | |
}) | |
function initCalendar(date, initialDay = new Date()) { | |
const calendar = document.getElementById("calendar") | |
const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] | |
let startDay | |
let endDay | |
let clicked = false | |
const daysElement = document.querySelector(".days") | |
daysElement.innerHTML = "" | |
const prevButton = document.getElementById("prev") | |
const nextButton = document.getElementById("next") | |
const current = document.getElementById("current-day") | |
prevButton.addEventListener("click", () => { | |
initCalendar(new Date(date.setMonth(date.getMonth() - 1)), initialDay) | |
}, { once: true }) | |
nextButton.addEventListener("click", () => { | |
initCalendar(new Date(date.setMonth(date.getMonth() + 1)), initialDay) | |
}, { once: true }) | |
let currentDate = date | |
current.textContent = `${months[currentDate.getMonth()]} - ${currentDate.getFullYear()}` | |
const days = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate() | |
const skipDays = new Date(date.getFullYear(), date.getMonth(), 1).getDay() - 1 | |
function traverseDays(start, end) { | |
document.querySelectorAll(".between").forEach(x => x.classList.remove("between")) | |
for (let x = startDay + 1; x < end; x++) { | |
document.getElementById(x).classList.add("between") | |
} | |
} | |
for (let i = 1; i <= skipDays; i++) { | |
const day = document.createElement("div") | |
day.classList.add("day") | |
daysElement.appendChild(day) | |
} | |
for (let i = 1; i <= days; i++) { | |
const day = document.createElement("div") | |
day.classList.add("day") | |
day.textContent = i | |
day.id = i | |
daysElement.appendChild(day) | |
day.addEventListener("click", () => { | |
calendar.querySelectorAll(".clicked").forEach(x => x.classList.remove("clicked")) | |
const id = Number(day.id) | |
if (!startDay) { | |
startDay = i | |
} else if (!endDay) { | |
endDay = i | |
} | |
if (startDay && endDay) { | |
if (id > startDay) { | |
endDay = id | |
} else { | |
startDay = id | |
} | |
const event = new CustomEvent('daysPicked', { | |
detail: { | |
start: new Date(currentDate.getFullYear(), currentDate.getMonth(), startDay), | |
end: new Date(currentDate.getFullYear(), currentDate.getMonth(), endDay) | |
} | |
}) | |
traverseDays(startDay, endDay) | |
calendar.dispatchEvent(event) | |
} | |
if (document.getElementById(startDay)) { | |
document.getElementById(startDay).classList.add("clicked") | |
} | |
if (document.getElementById(endDay)) { | |
document.getElementById(endDay).classList.add("clicked") | |
} | |
}) | |
day.addEventListener("mouseover", () => { | |
if (typeof startDay != "undefined" && typeof endDay != "undefined") { | |
return | |
} | |
if (!endDay && startDay) { | |
if (startDay > Number(day.id)) { | |
traverseDays(Number(day.id), startDay) | |
return | |
} | |
} | |
traverseDays(startDay, Number(day.id)) | |
}) | |
if (i === initialDay.getDate() && currentDate.getFullYear() === initialDay.getFullYear() && currentDate.getMonth() === initialDay.getMonth()) { | |
day.classList.add("active") | |
} | |
} | |
} | |
initCalendar(new Date(), new Date(2022, 7, 17)) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment