Skip to content

Instantly share code, notes, and snippets.

@CarsonSlovoka
Last active September 27, 2023 11:23
Show Gist options
  • Save CarsonSlovoka/7568603fa8bbc4fe287345991e1661e8 to your computer and use it in GitHub Desktop.
Save CarsonSlovoka/7568603fa8bbc4fe287345991e1661e8 to your computer and use it in GitHub Desktop.
example: simple calendar (class)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vote</title>
</head>
<body>
<form action="/vote/" method="post">
<label for="name">Name:</label><br>
<input type="text" id="name" name="name" required><br><br>
<label for="dates">Unavailable Dates:</label><br>
<textarea rows="3" cols="100" id="dates" name="dates" readonly></textarea><br>
<button type="button" onclick="calendar.toggle()">Select Unavailable Dates</button><br><br>
<input type="submit" value="Submit">
</form>
<div id="calendar-container"></div>
<script>
class Calendar {
static #SerialNumber = 0
static initCSSStyle() {
// 檢查有沒有定義
for (const stylesheet of document.styleSheets) {
for (const rule of stylesheet.cssRules) {
// rule.cssText // 會包含定義的所有內容
if (rule.selectorText.includes("table.calendar")) { // rule.selectorText: 就是css前面的名稱,例如 "rect:hover + .tooltip"
console.info("您已經嘗試自定義table.calendar的樣式,所以不再加入預設的style")
return
}
}
}
const css = `
table.calendar {
display: none;
position: absolute;
background-color: white;
border: 1px solid #ddd;
}
table.calendar th, table.calendar td {
width: 40px;
height: 40px;
text-align: center;
vertical-align: middle;
border: 1px solid #ddd;
}
table.calendar td.selected {
background-color: #00f;
color: #fff;
}
`
// 加入自定義css
const styleSheet = document.createElement("style")
styleSheet.innerText = css
document.head.appendChild(styleSheet)
}
constructor(container, currentDate) {
this.container = container;
this.currentDate = currentDate;
this.selectedDates = []
this.id = Calendar.#SerialNumber
Calendar.#SerialNumber++
this.table = document.createElement('table')
this.table.classList.add("calendar")
if (document.calendarMap === undefined) {
document.calendarMap = {}
}
document.calendarMap[`${this.id}`] = this
this.table.innerHTML = `
<thead>
<tr>
<th colspan="1"><button onclick="document.calendarMap[${this.id}].goToPreviousMonth()">&#9664;</button></th>
<th colspan="5" id="monthLabel"></th>
<th colspan="1"><button onclick="document.calendarMap[${this.id}].goToNextMonth()">&#9654;</button></th>
</tr>
<tr>
<th>Sun</th>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
</tr>
</thead>
<tbody>
</tbody>
`;
this.container.appendChild(this.table);
}
toggle() {
if (this.table.style.display === 'none' || this.table.style.display === '') {
this.table.style.display = 'block';
this.#render();
} else {
this.table.style.display = 'none';
}
}
goToPreviousMonth() {
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
this.#render();
}
goToNextMonth() {
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
this.#render();
}
#render() {
var tbody = this.table.tBodies[0];
tbody.innerHTML = '';
var startDate = new Date(Date.UTC(this.currentDate.getFullYear(), this.currentDate.getMonth(), 1));
var endDate = new Date(Date.UTC(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 0));
var row = tbody.insertRow();
for (var d = startDate; d <= endDate; d.setDate(d.getDate() + 1)) {
if (row.cells.length === 7) {
row = tbody.insertRow();
}
var cell = row.insertCell();
cell.innerText = d.getDate();
cell.dataset.date = d.toISOString().slice(0, 10);
cell.onclick = (e)=>this.#toggleDate(e)
if (this.selectedDates.includes(cell.dataset.date)) {
cell.classList.add('selected');
}
}
document.getElementById('monthLabel').textContent = this.currentDate.toLocaleDateString('default', { month: 'long', year: 'numeric' });
}
onToggleDate() {
}
#toggleDate(event) {
var cell = event.target;
var date = cell.dataset.date;
if (cell.classList.contains('selected')) {
cell.classList.remove('selected');
this.selectedDates.splice(this.selectedDates.indexOf(date), 1);
} else {
cell.classList.add('selected');
this.selectedDates.push(date);
}
this.onToggleDate()
}
}
Calendar.initCSSStyle()
const calendar = new Calendar(document.getElementById('calendar-container'), new Date());
calendar.onToggleDate = ()=> {
document.getElementById('dates').value = calendar.selectedDates.join(', ');
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment