'use strict'; var refreshListenerAdded = false; var intervalId; function scrollToCurrentSlot() { var table = $('.dwm_main'); var timelineVertical = table.find('thead').data('timeline-vertical'); var container = table.parent(); var scrollTo, scrollable; scrollable = (timelineVertical) ? container.isHScrollable() : container.isVScrollable(); if (scrollable) { var slots = table.find('thead').data('slots'); var nowSlotIndices = Timeline.search(slots); if (nowSlotIndices.length > 1) { var index = Math.max(0, nowSlotIndices[0] - 1); } if (index > 0) { if (timelineVertical) { var cols = table.find('thead th:not(.first_last)'); scrollTo = cols.eq(index).offset().left - cols.eq(0).offset().left; container.scrollLeft(scrollTo); } else { var rows = table.find('tbody tr'); scrollTo = rows.eq(index).offset().top - rows.eq(0).offset().top; container.scrollTop(scrollTo); } } } } var sizeColumns = function() { var mainCols = $('.dwm_main thead tr:first-child th:visible').not('th.first_last, th.hidden_day'); mainCols.css('width', 100/mainCols.length + '%'); }; var refreshPage = function refreshPage() { var table = $('table.dwm_main'); if (!isHidden() && !table.hasClass('resizing') && (args.kiosk || !isMeteredConnection()) && !refreshPage.disabled) { var url = 'index.php'; var data = { refresh: 1, view: args.view, view_all: args.view_all, page_date: args.pageDate, area: args.area, room: args.room }; if (args.timetohighlight !== undefined) { data.timetohighlight = args.timetohighlight; } table.addClass('refreshable'); if(args.site) { data.site = args.site; } // If we're in kiosk mode add the kiosk parameter in the query string rather than as a POST // parameter to avoid an unnecessary redirection by the server (the server checks for a kiosk // in the query string and, if not found, will redirect to the kiosk URL). if (args.kiosk !== undefined) { url += '?kiosk=' + args.kiosk; } return $.post( url, data, function(result){ if (result && !isHidden() && !refreshPage.disabled) { var table = $('table.dwm_main'); if (!table.hasClass('resizing') && table.hasClass('refreshable')) { var dateHeading = $('.date_heading'); dateHeading.empty().html(result.date_heading); table.empty().html(result.inner_html); window.clearInterval(intervalId); intervalId = undefined; table.trigger('tableload'); } } }, 'json' ); } }; var refreshVisChanged = function refreshVisChanged() { var pageHidden = isHidden(); if (pageHidden !== null) { if (typeof intervalId !== 'undefined') { window.clearInterval(intervalId); intervalId = undefined; } if (!pageHidden) { refreshPage().done(function() { prefetch(); }); } } }; var Timeline = { timerRunning: null, clear: function() { $('.timeline').remove(); if (Timeline.timerRunning) { window.clearInterval(Timeline.timerRunning); Timeline.timerRunning = null; } }, getFirstNonZeroSlotSize: function() { var slotSize; var table = $('#day_main'); table.find('thead th').not('.first_last').each(function () { slotSize = $(this).outerWidth(); if (slotSize) { return false; } }); table.find('tbody tr').each(function () { slotSize = $(this).outerHeight(); if (slotSize) { return false; } }); return slotSize; }, search: function(slots, time) { function within(slots, time) { function getFirst(arr) { if (Array.isArray(arr)) { return getFirst(arr[0]); } return arr; } function getLast(arr) { if (Array.isArray(arr)) { return getLast(arr[arr.length - 1]); } return arr; } return ((getFirst(slots) <= time) && (getLast(slots) > time)); } function getIndices(slots, time) { var element; for (var i=slots.length - 1; i>=0; i--) { element = slots[i]; if (within(element, time)) { if (Array.isArray(element[0])) { getIndices(element, time); } result.push(i); break; } } } var result = []; if ((typeof time === 'undefined')) { time = Math.floor(Date.now() / 1000); } if ((typeof slots !== 'undefined') && within(slots, time)) { getIndices(slots, time); } return result; }, show: function () { if (isHidden()) { return; } $('.timeline').remove(); var now = Math.floor(Date.now() / 1000); var table = $('.dwm_main'); var container = table.parent(); var thead = table.find('thead'); var slots = thead.data('slots'); var timelineVertical = thead.data('timeline-vertical'); var timelineFull = thead.data('timeline-full'); var nowSlotIndices, slot, fraction, row, element; var slotSize, delay, timeline; var top, left, borderLeftWidth, borderRightWidth, width, height; var headers, headersFirstLast, headersNormal, headerFirstSize, headerLastSize; nowSlotIndices = Timeline.search(slots); if (nowSlotIndices.length > 1) { slot = slots; for (var i=nowSlotIndices.length - 1; i>=0; i--) { slot = slot[nowSlotIndices[i]]; } fraction = (now-slot[0]) / (slot[1]-slot[0]); header cells in because they are useful for working out the // dimensions of slots in the table. We can't rely on the cells in the because // they may have rowspans attached to them. ?> headers = table.find('thead tr').first().find('th'); if (timelineVertical) { row = table.find('tbody tr').eq(nowSlotIndices[1]); element = headers.not('.first_last').eq(nowSlotIndices[0]); borderLeftWidth = parseInt(element.css('border-left-width'), 10); slotSize = element.innerWidth(); left = element.offset().left - table.parent().offset().left; left = left + borderLeftWidth; left = left + fraction * slotSize; if (timelineFull) { var tbody = table.find('tbody'); top = tbody.offset().top - container.offset().top; height = tbody.height(); } else { top = row.offset().top - table.parent().offset().top; tag in a // booked cell. A bit of a hack, but difficult to see how to do it otherwise. ?> height = row.innerHeight() - 1; } timeline = $('
') .height(height) .css({ top: top + container.scrollTop() + 'px', left: left + container.scrollLeft() + 'px' }); table.after(timeline); } else { row = table.find('tbody tr').eq(nowSlotIndices[0]); if (timelineFull) { headersFirstLast = headers.filter('.first_last'); headersNormal = headers.not('.first_last'); borderLeftWidth = parseInt(headersNormal.first().css('border-left-width'), 10); borderRightWidth = parseInt(headersNormal.first().css('border-right-width'), 10); headerFirstSize = headersFirstLast.first().outerWidth(); headerLastSize = (headersFirstLast.length > 1) ? headersFirstLast.last().outerWidth() : 0; width = row.innerWidth() - (headerFirstSize + headerLastSize + borderLeftWidth + borderRightWidth); left = row.offset().left - table.parent().offset().left + borderLeftWidth + headerFirstSize; } else { element = headers.not('.first_last').eq(nowSlotIndices[1]); borderLeftWidth = parseInt(element.css('border-left-width'), 10); width = element.innerWidth(); left = element.offset().left - table.parent().offset().left + borderLeftWidth; } slotSize = row.outerHeight(); top = row.offset().top - table.parent().offset().top; top = top + fraction * slotSize; timeline = $('
') .width(width) .css({top: top + container.scrollTop() + 'px', left: left + container.scrollLeft() + 'px' }); table.after(timeline); } } if (Timeline.timerRunning === null) { if (typeof slotSize === 'undefined') { slotSize = Timeline.getFirstNonZeroSlotSize(); } if (slot && slotSize) { delay = (slot[1] - slot[0])/(2 * slotSize); delay = Math.round(delay * 1000); delay = Math.max(delay, 1000); } else { delay = 60000; } Timeline.timerRunning = window.setInterval(Timeline.show, delay); } } }; $(document).on('page_ready', function() { var table = $('table.dwm_main'); Timeline.clear(); table.on('tableload', function() { var refreshRate; sizeColumns(); if (args.kiosk) { refreshRate = ; } else { refreshRate = ; } if (refreshRate !== 0) { if (typeof intervalId === 'undefined') { intervalId = setInterval(refreshPage, refreshRate * 1000); } } var prefix = visibilityPrefix(); if (document.addEventListener && (prefix !== null) && !refreshListenerAdded) { document.addEventListener(prefix + "visibilitychange", refreshVisChanged); refreshListenerAdded = true; } if ((args.kiosk && ) || (!args.kiosk && )) { Timeline.show(); $(window).on('resize', function () { Timeline.show(); }); } var bottom = $('.dwm_main thead tr:first th:first').outerHeight(); $('.dwm_main thead tr:nth-child(2) th').css('top', bottom + 'px'); $('table.all_rooms td').on('mouseenter mouseleave', function(event) { $('table.all_rooms') .find('thead, tfoot') .find('th:nth-child(' + ($(this).index() + 1) + ')') .toggleClass('highlight', (event.type === 'mouseenter')); }); }).trigger('tableload'); const searchParams = new URLSearchParams(window.location.search); const top = searchParams.get('top'); const left = searchParams.get('left'); if ((top == null) && (left === null)) { const autoscroll = ; if (autoscroll) { scrollToCurrentSlot(); } } else { let tableContainer = table.parent(); if (top !== null) { tableContainer.scrollTop(top); } if (left !== null) { tableContainer.scrollLeft(left); } } });