Skip to content

Commit 4dcbf4e

Browse files
committed
Created new calendarMonthViewType
1 parent c9c802e commit 4dcbf4e

6 files changed

Lines changed: 149 additions & 17 deletions

File tree

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ const calendar = new SimpleCalendar(calendarElement, {
116116
| `eventClick` | function | `null` | Callback for event clicks |
117117
| `stateChange` | function | `null` | Callback when calendar state changes |
118118
| `showBackground` | boolean | `false` | Show background colors |
119+
| `calendarMonthViewType` | string | `'MultiDay'` | Month view type: 'MultiDay' (show events) or 'SingleDay' (event backgrounds only) |
119120
| `headerBackgroundColor` | string | `null` | Custom header background color |
120121
| `bodyBackgroundColor` | string | `null` | Custom body background color |
121122
| `showTimeInEvent` | boolean | `true` | Display time in events |
@@ -148,6 +149,51 @@ const calendar = new SimpleCalendar(calendarElement, {
148149
}
149150
```
150151

152+
## Month View Types
153+
154+
SimpleCalendarJs supports two distinct month view modes:
155+
156+
### MultiDay Mode (Default)
157+
Shows events as text overlays on calendar days. This is the traditional calendar view where event titles are displayed within the day cells.
158+
159+
```javascript
160+
const calendar = new SimpleCalendar('#calendar', {
161+
calendarMonthViewType: 'MultiDay', // Default
162+
data: [
163+
{
164+
start: '2024-11-15',
165+
end: '2024-11-17',
166+
title: 'Conference',
167+
backgroundColor: '#007bff'
168+
}
169+
]
170+
});
171+
```
172+
173+
### SingleDay Mode
174+
Shows event presence through background colors only. Day numbers are centered and no event text is displayed. This provides a clean, minimalist view that highlights which days have events.
175+
176+
```javascript
177+
const calendar = new SimpleCalendar('#calendar', {
178+
calendarMonthViewType: 'SingleDay',
179+
data: [
180+
{
181+
start: '2024-11-15',
182+
end: '2024-11-17',
183+
title: 'Conference', // Title not displayed in SingleDay mode
184+
backgroundColor: '#e0e0e0' // Custom color or defaults to gray variations
185+
}
186+
]
187+
});
188+
```
189+
190+
**SingleDay Mode Features:**
191+
- Day numbers are centered in the cell
192+
- Event backgrounds use subtle gray variations by default
193+
- No event text is displayed for a clean appearance
194+
- Custom `backgroundColor` values in events are respected
195+
- Ideal for overview calendars or when space is limited
196+
151197
## UI Customization
152198

153199
### Visibility Controls
@@ -367,6 +413,7 @@ The state object contains:
367413
- `showTodayButton`: Today button visibility setting
368414
- `showMonthYear`: Month/year navigation visibility setting
369415
- `showModeButtons`: Mode buttons visibility setting
416+
- `calendarMonthViewType`: Month view type ('MultiDay' or 'SingleDay')
370417

371418
## Framework Integration
372419

css/SimpleCalendarJs.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,3 +1298,33 @@ html[data-bs-theme="dark"] .simple-calendar .view-dropdown-item.active {
12981298
[data-bs-theme="dark"] .simple-calendar .outside .sc_date {
12991299
color: #6b7280 !important;
13001300
}
1301+
1302+
/* ================================================
1303+
SINGLEDAY MODE STYLING
1304+
================================================ */
1305+
1306+
/* SingleDay mode: Center the day digits in calendar cells */
1307+
.simple-calendar .calendar-day.single-day-mode {
1308+
text-align: center;
1309+
vertical-align: middle;
1310+
position: relative;
1311+
}
1312+
1313+
.simple-calendar .calendar-day.single-day-mode .sc_date {
1314+
position: absolute;
1315+
top: 50%;
1316+
left: 50%;
1317+
transform: translate(-50%, -50%);
1318+
margin: 0;
1319+
line-height: 1;
1320+
}
1321+
1322+
/* Default background for days with events in SingleDay mode */
1323+
.simple-calendar .calendar-day.single-day-mode.has-events {
1324+
background-color: rgba(0, 0, 0, 0.08) !important; /* Light gray tint */
1325+
}
1326+
1327+
/* Dark mode default background for days with events */
1328+
[data-bs-theme="dark"] .simple-calendar .calendar-day.single-day-mode.has-events {
1329+
background-color: rgba(255, 255, 255, 0.12) !important; /* Light white tint in dark mode */
1330+
}

index.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ <h5>Calendar Properties</h5>
6666
<div class="card-body">
6767
<div class="mb-3">
6868
<div class="form-check form-switch">
69-
<input class="form-check-input" type="checkbox" id="showBackground" checked>
69+
<input class="form-check-input" type="checkbox" id="showBackground">
7070
<label class="form-check-label" for="showBackground">Show Background</label>
7171
</div>
7272
</div>
@@ -132,6 +132,13 @@ <h5>Calendar Properties</h5>
132132
<option value="day">Day</option>
133133
</select>
134134
</div>
135+
<div class="mb-3">
136+
<label for="calendarMonthViewType" class="form-label">Month View Type</label>
137+
<select class="form-select" id="calendarMonthViewType">
138+
<option value="MultiDay" selected>MultiDay (Show Events)</option>
139+
<option value="SingleDay">SingleDay (Event Backgrounds)</option>
140+
</select>
141+
</div>
135142
<div class="mb-3">
136143
<label for="calendarMonth" class="form-label">Month</label>
137144
<select class="form-select" id="calendarMonth">

js/SimpleCalendarJs.js

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ const template = `{{
141141
{{ for (i = 0; i < 7; i++) { }}
142142
{{ console.log(date.toDateCssClass());}}
143143
{{ if (thedate > last) { dayclass = nextmonthcss; } else if (thedate >= first) { dayclass = thismonthcss; } }}
144-
<td class="calendar-day {{: dayclass }} {{: thedate.toDateCssClass() }} {{: today.toDateCssClass() === thedate.toDateCssClass() ? 'currentdate sc_today_date':'' }} {{: daycss[i] }} js-cal-option add-day" data-date="{{: LiteralDate.toDateString(thedate) }}">
144+
<td class="calendar-day {{: dayclass }} {{: thedate.toDateCssClass() }} {{: today.toDateCssClass() === thedate.toDateCssClass() ? 'currentdate sc_today_date':'' }} {{: daycss[i] }} {{: mode === 'month' && calendarMonthViewType === 'SingleDay' ? 'single-day-mode' : '' }} js-cal-option add-day" data-date="{{: LiteralDate.toDateString(thedate) }}">
145145
<div class="sc_date">{{: thedate.getDate() }}</div>
146146
{{ thedate.setDate(thedate.getDate() + 1);}}
147147
@@ -440,6 +440,7 @@ class SimpleCalendar {
440440
lastmonthcss: "outside",
441441
nextmonthcss: "outside",
442442
mode: "month",
443+
calendarMonthViewType: "MultiDay", // 'SingleDay' or 'MultiDay'
443444
useShortDays: false,
444445
showTimeInEvent: true,
445446
showBackground: false,
@@ -953,20 +954,26 @@ class SimpleCalendar {
953954
if (this.options.mode === 'year') {
954955
this.yearAddEvents(this.options.data, this.options.date.getFullYear());
955956
} else if (this.options.mode === 'month' || this.options.mode === 'week') {
956-
// Sort events so multi-day events are rendered first (at the top)
957-
const sortedEvents = [...this.options.data].sort((a, b) => {
958-
const aIsMultiDay = a.end && !LiteralDate.isEqual(a.start, a.end);
959-
const bIsMultiDay = b.end && !LiteralDate.isEqual(b.start, b.end);
960-
961-
// Multi-day events first, then by start date
962-
if (aIsMultiDay && !bIsMultiDay) return -1;
963-
if (!aIsMultiDay && bIsMultiDay) return 1;
957+
if (this.options.mode === 'month' && this.options.calendarMonthViewType === 'SingleDay') {
958+
// SingleDay mode: Only apply background colors to days with events, don't render events
959+
this.applySingleDayBackgrounds(this.options.data);
960+
} else {
961+
// MultiDay mode (default): Render events normally
962+
// Sort events so multi-day events are rendered first (at the top)
963+
const sortedEvents = [...this.options.data].sort((a, b) => {
964+
const aIsMultiDay = a.end && !LiteralDate.isEqual(a.start, a.end);
965+
const bIsMultiDay = b.end && !LiteralDate.isEqual(b.start, b.end);
966+
967+
// Multi-day events first, then by start date
968+
if (aIsMultiDay && !bIsMultiDay) return -1;
969+
if (!aIsMultiDay && bIsMultiDay) return 1;
970+
971+
// If both are same type, sort by start date
972+
return LiteralDate.parse(a.start) - LiteralDate.parse(b.start);
973+
});
964974

965-
// If both are same type, sort by start date
966-
return LiteralDate.parse(a.start) - LiteralDate.parse(b.start);
967-
});
968-
969-
sortedEvents.forEach((event, index) => this.monthAddEvent(index, event));
975+
sortedEvents.forEach((event, index) => this.monthAddEvent(index, event));
976+
}
970977
} else {
971978
this.options.data.forEach((event, index) => this.dayAddEvent(index, event));
972979
}
@@ -1124,6 +1131,34 @@ class SimpleCalendar {
11241131
}
11251132
}
11261133

1134+
applySingleDayBackgrounds(events) {
1135+
// SingleDay mode: Apply background colors to days with events, don't render actual events
1136+
events.forEach((event) => {
1137+
const eventStart = LiteralDate.parse(event.start);
1138+
const eventEnd = event.end ? LiteralDate.parse(event.end) : eventStart;
1139+
1140+
// Iterate through all days the event spans
1141+
let currentDate = new Date(eventStart);
1142+
while (currentDate <= eventEnd) {
1143+
const dayClass = LiteralDate.toCssClass(currentDate);
1144+
const dayElement = Dom.select('.' + dayClass, this.element);
1145+
1146+
if (dayElement) {
1147+
// Add a CSS class to indicate this day has events
1148+
dayElement.classList.add('has-events');
1149+
1150+
// Apply background color from event if specified
1151+
if (event.backgroundColor) {
1152+
dayElement.style.backgroundColor = event.backgroundColor;
1153+
}
1154+
}
1155+
1156+
// Move to next day
1157+
currentDate.setDate(currentDate.getDate() + 1);
1158+
}
1159+
});
1160+
}
1161+
11271162
yearAddEvents(events, year) {
11281163
const counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
11291164
events.forEach((v) => {

js/script.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function initializeCalendar() {
3232

3333
var currentYear = parseInt(yearControl?.value) || new Date().getFullYear();
3434
var currentMonth = parseInt(monthControl?.value) || new Date().getMonth();
35-
var calendarDate = new Date(currentYear, currentMonth, 1);
35+
var calendarDate = new Date();
3636

3737
const calendarElement = document.querySelector('#calendar');
3838
if (!calendarElement) {
@@ -53,6 +53,7 @@ function initializeCalendar() {
5353
showNavigation: document.querySelector('#showNavigation')?.checked !== false,
5454
theme: document.querySelector('#themeMode')?.value || 'auto',
5555
showBackground: document.querySelector('#showBackground')?.checked || false,
56+
calendarMonthViewType: document.querySelector('#calendarMonthViewType')?.value || 'MultiDay',
5657
headerBackgroundColor: document.querySelector('#headerBgColor')?.value,
5758
bodyBackgroundColor: document.querySelector('#bodyBgColor')?.value,
5859
useShortDays: document.querySelector('#useShortDays')?.checked || false,
@@ -132,6 +133,14 @@ function setupPropertyControls() {
132133
});
133134
}
134135

136+
// Month view type selector
137+
const monthViewTypeSelector = document.querySelector('#calendarMonthViewType');
138+
if (monthViewTypeSelector) {
139+
monthViewTypeSelector.addEventListener('change', function() {
140+
refreshCalendar();
141+
});
142+
}
143+
135144
// Month and year selectors
136145
addEventListeners('#calendarMonth, #calendarYear', 'change', function() {
137146
refreshCalendar();
@@ -235,6 +244,10 @@ function syncSandboxControls(state) {
235244
const themeControl = document.querySelector('#themeMode');
236245
if (themeControl) themeControl.value = state.theme;
237246

247+
// Update month view type selector to match calendar state
248+
const monthViewTypeControl = document.querySelector('#calendarMonthViewType');
249+
if (monthViewTypeControl) monthViewTypeControl.value = state.calendarMonthViewType || 'MultiDay';
250+
238251
// Update month and year to match calendar state
239252
if (state.date) {
240253
const monthControl = document.querySelector('#calendarMonth');

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "simple-calendar-js",
3-
"version": "1.0.13",
3+
"version": "1.0.14",
44
"description": "A clean, modern, and feature-rich JavaScript calendar component with zero dependencies. Responsive design and intuitive navigation.",
55
"main": "js/SimpleCalendarJs.js",
66
"style": "css/SimpleCalendarJs.css",

0 commit comments

Comments
 (0)