Add the Chronological
This commit is contained in:
129
js/calendar-widget.js
Normal file
129
js/calendar-widget.js
Normal file
@@ -0,0 +1,129 @@
|
||||
/* global window, document, fetch, URLSearchParams */
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Luxtools = window.Luxtools || (window.Luxtools = {});
|
||||
|
||||
function findCalendarRoot(target) {
|
||||
var el = target;
|
||||
while (el && el !== document) {
|
||||
if (el.classList && el.classList.contains('luxtools-calendar') && el.getAttribute('data-luxtools-calendar') === '1') {
|
||||
return el;
|
||||
}
|
||||
el = el.parentNode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getNextMonth(year, month, direction) {
|
||||
var cursor = new Date(year, month - 1, 1);
|
||||
cursor.setMonth(cursor.getMonth() + direction);
|
||||
return {
|
||||
year: cursor.getFullYear(),
|
||||
month: cursor.getMonth() + 1
|
||||
};
|
||||
}
|
||||
|
||||
function parseCalendarFromHtml(html) {
|
||||
if (!html) return null;
|
||||
|
||||
var wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = html;
|
||||
|
||||
return wrapper.querySelector('div.luxtools-calendar[data-luxtools-calendar="1"]');
|
||||
}
|
||||
|
||||
function setCalendarBusy(calendar, busy) {
|
||||
if (!calendar) return;
|
||||
|
||||
if (busy) {
|
||||
calendar.setAttribute('data-luxtools-loading', '1');
|
||||
} else {
|
||||
calendar.removeAttribute('data-luxtools-loading');
|
||||
}
|
||||
|
||||
var buttons = calendar.querySelectorAll('button.luxtools-calendar-nav-button');
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
buttons[i].disabled = !!busy;
|
||||
}
|
||||
}
|
||||
|
||||
function fetchCalendarMonth(calendar, year, month) {
|
||||
var ajaxUrl = calendar.getAttribute('data-luxtools-ajax-url') || '';
|
||||
if (!ajaxUrl) return Promise.reject(new Error('Missing calendar ajax url'));
|
||||
|
||||
var baseNs = calendar.getAttribute('data-base-ns') || 'chronological';
|
||||
var params = new URLSearchParams({
|
||||
call: 'luxtools_calendar_month',
|
||||
year: String(year),
|
||||
month: String(month),
|
||||
base: baseNs
|
||||
});
|
||||
|
||||
var url = ajaxUrl + (ajaxUrl.indexOf('?') >= 0 ? '&' : '?') + params.toString();
|
||||
|
||||
return fetch(url, {
|
||||
method: 'GET',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
}).then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Calendar request failed: ' + response.status);
|
||||
}
|
||||
return response.text();
|
||||
});
|
||||
}
|
||||
|
||||
function navigateCalendarMonth(calendar, direction) {
|
||||
var year = parseInt(calendar.getAttribute('data-current-year') || '', 10);
|
||||
var month = parseInt(calendar.getAttribute('data-current-month') || '', 10);
|
||||
if (!year || !month) return;
|
||||
|
||||
var next = getNextMonth(year, month, direction);
|
||||
setCalendarBusy(calendar, true);
|
||||
|
||||
fetchCalendarMonth(calendar, next.year, next.month)
|
||||
.then(function (html) {
|
||||
var replacement = parseCalendarFromHtml(html);
|
||||
if (!replacement) {
|
||||
throw new Error('Calendar markup missing in response');
|
||||
}
|
||||
|
||||
calendar.replaceWith(replacement);
|
||||
})
|
||||
.catch(function () {
|
||||
var fallbackLink = calendar.querySelector('a.luxtools-calendar-month-link');
|
||||
if (fallbackLink && fallbackLink.href) {
|
||||
window.location.href = fallbackLink.href;
|
||||
}
|
||||
})
|
||||
.finally(function () {
|
||||
setCalendarBusy(calendar, false);
|
||||
});
|
||||
}
|
||||
|
||||
function onCalendarClick(event) {
|
||||
var target = event.target;
|
||||
if (!target || !target.classList || !target.classList.contains('luxtools-calendar-nav-button')) return;
|
||||
|
||||
var calendar = findCalendarRoot(target);
|
||||
if (!calendar) return;
|
||||
|
||||
var direction = parseInt(target.getAttribute('data-luxtools-dir') || '0', 10);
|
||||
if (direction !== -1 && direction !== 1) return;
|
||||
|
||||
event.preventDefault();
|
||||
navigateCalendarMonth(calendar, direction);
|
||||
}
|
||||
|
||||
function initCalendarWidgets() {
|
||||
document.addEventListener('click', onCalendarClick, false);
|
||||
}
|
||||
|
||||
Luxtools.CalendarWidget = {
|
||||
init: initCalendarWidgets
|
||||
};
|
||||
})();
|
||||
38
js/main.js
38
js/main.js
@@ -8,6 +8,7 @@
|
||||
var OpenService = Luxtools.OpenService;
|
||||
var GalleryThumbnails = Luxtools.GalleryThumbnails;
|
||||
var Scratchpads = Luxtools.Scratchpads;
|
||||
var CalendarWidget = Luxtools.CalendarWidget;
|
||||
|
||||
// ============================================================
|
||||
// Click Handlers
|
||||
@@ -79,12 +80,49 @@
|
||||
});
|
||||
}
|
||||
|
||||
function initChronologicalEventTimes() {
|
||||
var nodes = document.querySelectorAll('.luxtools-event-time[data-luxtools-start]');
|
||||
if (!nodes || nodes.length === 0) return;
|
||||
|
||||
var formatter;
|
||||
try {
|
||||
formatter = new Intl.DateTimeFormat(undefined, {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
} catch (e) {
|
||||
formatter = null;
|
||||
}
|
||||
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var node = nodes[i];
|
||||
var raw = node.getAttribute('data-luxtools-start') || '';
|
||||
if (!raw) continue;
|
||||
|
||||
var date = new Date(raw);
|
||||
if (isNaN(date.getTime())) continue;
|
||||
|
||||
var label;
|
||||
if (formatter) {
|
||||
label = formatter.format(date);
|
||||
} else {
|
||||
var hh = String(date.getHours()).padStart(2, '0');
|
||||
var mm = String(date.getMinutes()).padStart(2, '0');
|
||||
label = hh + ':' + mm;
|
||||
}
|
||||
|
||||
node.textContent = label;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Initialize
|
||||
// ============================================================
|
||||
document.addEventListener('click', onClick, false);
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
if (GalleryThumbnails && GalleryThumbnails.init) GalleryThumbnails.init();
|
||||
initChronologicalEventTimes();
|
||||
if (CalendarWidget && CalendarWidget.init) CalendarWidget.init();
|
||||
}, false);
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
if (Scratchpads && Scratchpads.init) Scratchpads.init();
|
||||
|
||||
Reference in New Issue
Block a user