PageSourceSearch

https://awigverein.de/wp-content/plugins/termin-kalender/js/gutenberg_block_calendar_frontend.js?ver=1.3.4

js awigverein.de collected 2026-10-07 04:16:56 UTC 18,751 bytes, 355 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function () {
2    jQuery(function ($) {
3 //------------------------------------------------------------------------------------------------
4 //------------------------------------------------------------------------------------------------
5        // Find all calendar instances
6        $('.frontend_kalender[data-instance]').each(function() {
7            if (!window.TerminKalender.ter_kal_calendars) {
8                window.TerminKalender.ter_kal_calendars = {};
9            }
10            const $wrapper = $(this);
11            const instance_id = $wrapper.data('instance');
12            const show_time = $wrapper.data('show_time') || 'start_end';
13            // ter_kal_CHANGE: Initialize active filters from block settings
14            if (!window.TerminKalender.active_filters) {
15                window.TerminKalender.active_filters = {};
16            }
17            const hiddenCategories = $wrapper.data('hidden-categories') || [];
18            window.TerminKalender.active_filters[instance_id] = new Set(hiddenCategories);
19            const hide_buttons = $wrapper.data('hide-buttons') === 1; // ter_kal_CHANGE: Read hide buttons flag
20
21        var ter_kal_lang = terminKalenderData.ter_kal_lang;
22        const INPUT_FORMAT = 'YYYY-MM-DDTHH:mm';
23        if (terminKalenderData.TERMIN_KALENDER_PRO_ON == 'on' && terminKalenderData.is_user_logged_in == 1 ) {
24            var pro_button_login_link = '';
25            var pro_button_login = '';
26        }   else if (terminKalenderData.is_user_logged_in == 0 ) {
27            var pro_button_login_link = terminKalenderData.calendar_login_link;
28            var proLoginButton = 'LoginButton';
29        }
30            var calendarEl = document.getElementById('ter_kal_simple_calendar_' + instance_id);
31        if (!calendarEl) {
32            return;
33        }
34//------------------------------------------------------------------------------------------------
35        var ter_kal_simple_calendar = new FullCalendar.Calendar(calendarEl, {
36            // Native FullCalendar responsive settings
37            height: 'auto',           // Grows/shrinks based on content
38            contentHeight: 'auto',
39            handleWindowResize: true, // Automatically adjusts on window resize (default: true)
40            windowResizeDelay: 100,   // Debounce resize (ms)
41            // For compact display:
42            expandRows: false,        // Rows only as tall as needed
43            dayMaxEvents: 3,          // Show max 3 events, rest as "+2 more"
44            // Responsive view switching:
45        /*    windowResize: function(view) {
46                if (window.innerWidth < 500) {
47                    ter_kal_simple_calendar.changeView('listWeek'); // Switch to list on mobile
48                }
49            },*/
50            locale: ter_kal_lang,
51            customButtons: {
52                LoginButton: {
53                  text: terminKalenderData.strings.calendar_login ,
54                  click: function() { window.location.href = pro_button_login_link; }
55                }
56              },
57            footerToolbar: {
58    			left: proLoginButton,
59    			center: '',
60                right: '',
61    		},
62            headerToolbar: {
63                left: 'prev,next,today',
64                center: 'title',
65                    right: 'multiMonthYear,dayGridMonth,timeGridWeek,listYear',
66            },
67            editable: false,
68                timeZone: 'UTC',
69            eventDisplay: 'block',
70		    firstDay: 1,
71		    weekNumbers: true,
72                navLinks: true,
73            dayMaxEventRows: 4,
74            eventMaxStack: 3,
75                listDayFormat: { weekday: 'long', day: 'numeric', month: 'long' },
76                listDaySideFormat: false,
77            events: terminKalenderData.TERMIN_KALENDER_DATEN ,
78            eventDidMount: function(info) {
79                $(info.el).attr('title', info.event.title);
80            },
81            viewDidMount: function(info) {
82                if (info.view.type === 'multiMonthYear') {
83                    ter_kal_simple_calendar.setOption('dayMaxEventRows', 3);
84                }
85                if (info.view.type === 'dayGridMonth') {
86                    ter_kal_simple_calendar.setOption('dayMaxEventRows', 4);
87                }
88            },
89            eventClick: function (info) {
90                    openEventDialog(info.event, instance_id, show_time);
91            }
92        });
93//------------------------------------------------------------------------------------------------
94       // window.ter_kal_simple_calendar = ter_kal_simple_calendar;
95        ter_kal_simple_calendar.render();
96        // ter_kal_CHANGE: Store instance globally by instance_id
97        window.TerminKalender.ter_kal_calendars[instance_id] = ter_kal_simple_calendar;
98            // Detect if running in widget area
99/*            const isInWidget = $wrapper.closest('.widget-area, .sidebar, aside').length > 0;
100            if (isInWidget) {
101                ter_kal_simple_calendar.setOption('height', 'auto');
102                ter_kal_simple_calendar.setOption('contentHeight', 400);
103            }*/
104//------------------------------------------------------------------------------------------------
105            // Initialize event dialog native listeners
106            const dialogEl = document.getElementById('event-dialog-' + instance_id);
107            if (dialogEl) {
108                // Close button click
109                const closeBtn = dialogEl.querySelector('.ter_kal_dialog_close');
110                if (closeBtn) {
111                    closeBtn.addEventListener('click', () => dialogEl.close());
112                }
113                // Backdrop click to close
114                dialogEl.addEventListener('click', (e) => {
115                    const rect = dialogEl.getBoundingClientRect();
116                    // Fallback close check for backdrop click
117                    const isInDialog = (rect.top <= e.clientY && e.clientY <= rect.top + rect.height &&
118                                        rect.left <= e.clientX && e.clientX <= rect.left + rect.width);
119                    if (!isInDialog) {
120                        dialogEl.close();
121                    }
122                });
123                // On close event, blur fullcalendar
124                dialogEl.addEventListener('close', () => {
125                    $('.fc-view-outer *').blur();
126                });
127            }
128
129//------------------------------------------------------------------------------------------------
130            window.TerminKalender.openEventDialogFrontend = window.TerminKalender.openEventDialogFrontend || {};
131            window.TerminKalender.openEventDialogFrontend[instance_id] = function(event, id, time) {
132                openEventDialog(event, id, time);
133            };
134
135            function openEventDialog(event, instance_id, show_time) {
136                const dialog_selector = '#event-dialog-' + instance_id;
137                const dialogEl = document.getElementById('event-dialog-' + instance_id);
138                if (!dialogEl) return;
139
140                const ter_kal_link = window.location.href;
141
142                // Generate buttons
143                const buttonsObj = window.TerminKalender.share_buttons_calendar_ical(event, 'frontent_calendar', ter_kal_link);
144                const footerEl = document.getElementById('event-footer-' + instance_id);
145                window.TerminKalender.render_dialog_footer_buttons(dialogEl, footerEl, event, 'frontent_calendar', ter_kal_link);
146
147                if (dialogEl.open) {
148                    dialogEl.close();
149                }
150            $('#event-form').attr('data-event-id', event ? event.id : '');
151
152            var categoryData    = event ? event.extendedProps.category : null;
153            var details         = event ? event.extendedProps.details : '';
154            var location        = event ? event.extendedProps.location : '';
155            var title           = event ? event.title : '';
156            var dayName         = moment.utc(event.start).format('dddd');
157            var utcStart_kurz   = moment.utc(event.start).format('D MMMM YYYY');
158            var utcEnd_kurz     = moment.utc(event.end).format('D MMMM YYYY');
159            var utcStart_kurzStd = moment.utc(event.start).format('HH:mm');
160            var utcEnd_kurzStd   = ' - ' + moment.utc(event.end).format('HH:mm');
161            var event_allday_string =  terminKalenderData.strings.all_day ;
162            var freq                = event.extendedProps.freq ? event.extendedProps.freq : '' ;
163            if (freq) {
164               var freq_translated  = terminKalenderData.strings[freq] ;
165               var until            = event.extendedProps.until ? event.extendedProps.until  : '';
166               var utcEnd_kurz      = moment.utc(until).format('D MMMM YYYY');
167               var utcEnd_kurzStd   = ' - ' + moment.utc(until).format('HH:mm');
168            } else {
169               var freq_translated  = ' ' ;
170            }
171            //-----------------------------------------------------------------------------
172            //                 var isImplicitAllDay = event.end && moment.utc(event.end).diff(moment.utc(event.start), 'hours') === 24;
173
174            var isImplicitAllDay = utcStart_kurzStd === '00:00' &&
175                                   moment.utc(event.end).format('HH:mm') === '00:00' &&
176                                   moment.utc(event.end).diff(moment.utc(event.start), 'days') === 1;
177
178            if (event.allDay || isImplicitAllDay) {
179                utcStart_kurzStd = event_allday_string;
180                utcEnd_kurzStd = '';
181            }
182
183            // Zeige nur Startdatum wenn Enddatum ungültig, leer, identisch oder implizites Ganztags-Event
184            var hasValidEnd = utcEnd_kurz &&
185                              utcEnd_kurz !== 'Invalid date' &&
186                              utcEnd_kurz.trim() !== '' &&
187                              utcEnd_kurz !== utcStart_kurz &&
188                              !isImplicitAllDay;
189
190            // Update instance-specific elements
191//-----------------------------------------------------------------------------
192            if (location) {     // event_location
193                location ='<button type="button" class="bootstrap_button bootstrap_dark" onclick="window.open(\'https://www.google.com/maps/search/?api=1&query=' +
194                encodeURIComponent(location) + '\')">'+ terminKalenderData.strings.event_location + location + '</button>';
195                $('#event-location_link-' + instance_id).html( location );
196            } else {
197                $('#event-location_link-' + instance_id).html('');
198            }
199//-----------------------------------------------------------------------------
200            var utcTage = hasValidEnd ? utcStart_kurz + ' - ' + utcEnd_kurz : utcStart_kurz;
201            //-----------------------------------------------------------------------------
202            $('#event-time-' + instance_id).html('<b>' + dayName + ',</b> ' + utcTage +
203            '<br>' + freq_translated + ' <b><span class="utc_std">' + utcStart_kurzStd + ' <span class="utc_std_end"> ' + utcEnd_kurzStd  + '</span></span></b> ' );
204//-----------------------------------------------------------------------------
205            $('#event-title-' + instance_id).text( title );
206            $('#event-details-html-' + instance_id).html( details );
207//-----------------------------------------------------------------------------
208                // Apply category styling
209                applyDialogStyles(categoryData, 'event', dialog_selector);
210//--------------------------------------------------------------------------
211            // Handle show_time visibility
212                var $dialog = $(dialog_selector);
213            if (show_time == 'hide') {
214                    $dialog.find('.utc_std').hide();
215            } else if (show_time == 'start') {
216                    $dialog.find('.utc_std_end').hide();
217            } else  {
218                    $dialog.find('.utc_std').show();
219            }
220//--------------------------------------------------------------------------
221                dialogEl.showModal();
222        } // end open event dialog
223        //---------------------------------------------------------------------------
224        //---------------------------------------------------------------------------
225//------------------------------------------------------------------------------------------------
226//------------------------------------------------------------------------------------------------
227            function applyDialogStyles(category, dialogType, dialog_selector) {
228                const dialogEl = document.querySelector(dialog_selector);
229                if (!dialogEl) return;
230                
231                const header = dialogEl.querySelector('.ter_kal_dialog_header');
232                const title = dialogEl.querySelector('.ter_kal_dialog_title');
233                
234                if (category) {
235                    if (header) {
236                        header.style.backgroundColor = category.backgroundColor;
237                        header.style.color = category.textColor;
238                    }
239                    if (dialogType === 'event' && title) {
240                        title.innerHTML = '<span class="dialog_title_icon dashicons ' + category.icon + '"></span>' +
241                                          '<span style="vertical-align:middle;">' + (category.label || terminKalenderData.strings.new_category) + '</span>';
242                    }
243                } else {
244                    if (header) {
245                        header.style.backgroundColor = '';
246                        header.style.color = '';
247                    }
248                    if (dialogType === 'event' && title) {
249                        title.innerHTML = '<span>' + terminKalenderData.strings.event_title + '</span>';
250                    } else if (dialogType === 'category' && title) {
251                        title.innerHTML = '<span>' + terminKalenderData.strings.new_category + '</span>';
252                    }
253                }
254            }
255
256        loadCategories(instance_id);
257//------------------------------------------------------------------------------------------------
258//------------------------------------------------------------------------------------------------
259        //  Add category filtering to frontend calendar
260        function loadCategories(instance_id) {
261            var categories = terminKalenderData.TERMIN_KALENDER_KATEGORIEN,
262                $catSelect = $('#event-category_' + instance_id),
263                $catRow = $('#kategoriezeile_' + instance_id);
264
265            $catSelect.empty();
266            $catRow.empty();
267
268            // ter_kal_CHANGE: Get initial hidden categories
269            var activeFilters = window.TerminKalender.active_filters[instance_id];
270
271
272            $.each(categories, function (i, cat) {
273                // Überspringe die "To Do" Kategorie komplett
274                if (cat.label === 'To Do') {
275                    return true; 
276                }
277                $('<option>')
278                    .val(cat.label)
279                    .text(cat.label)
280                    .data('category', cat)
281                    .appendTo($catSelect);
282
283                var $btn = $('<div class="category-button">')
284                    .css({ backgroundColor: cat.backgroundColor, color: cat.textColor })
285                    .data('category-label', cat.label) // ter_kal_CHANGE: Store label for filtering
286                    .addClass(activeFilters.has(cat.label) ? 'ter_kal_filtered' : '')
287                    .css('display', (hide_buttons && activeFilters.has(cat.label)) ? 'none' : '')
288                    .append(
289                        $('<span class="dashicons ' + cat.icon + '"></span>'),
290                        $('<span class="tk_kalender_button_text">').text(cat.label)
291                    )
292                    // ter_kal_CHANGE: Add click handler to toggle category filter
293                    .on('click', function() {
294                        var label = $(this).data('category-label');
295                        if (activeFilters.has(label)) {
296                            activeFilters.delete(label);
297                            $(this).removeClass('ter_kal_filtered');
298                        } else {
299                            activeFilters.add(label);
300                            $(this).addClass('ter_kal_filtered');
301                        }
302
303                        ter_kal_applyEventFilter(instance_id);
304                    });
305
306                $catRow.append($btn);
307            });
308
309            // ter_kal_CHANGE: Apply initial filter after calendar renders
310            if (activeFilters.size > 0) {
311                ter_kal_applyEventFilter(instance_id);
312            }
313
314            if (typeof callback === 'function') {
315                callback();
316            }
317
318            localStorage.setItem('termin_kalender_kategorien', JSON.stringify(categories));
319        }
320
321
322        // ter_kal_CHANGE: Use CSS classNames to preserve event styling (CORRECTED LOGIC)
323        function ter_kal_applyEventFilter(instance_id) {
324            var calendar = window.TerminKalender.ter_kal_calendars[instance_id];
325            if (!calendar) return;
326
327            var activeFilters = window.TerminKalender.active_filters[instance_id];
328
329            calendar.getEvents().forEach(function(event) {
330                var eventCategory = event.extendedProps.category ? event.extendedProps.category.label : null;
331
332                // ter_kal_CHANGE: Hide matched categories (clicked buttons are filtered OUT)
333                if (activeFilters.size === 0 || !activeFilters.has(eventCategory)) {
334                    // Show: remove hidden class
335                    event.setProp('classNames', event.classNames.filter(c => c !== 'ter-kal-hidden'));
336                } else {
337                    // Hide: add hidden class when category IS in activeFilters
338                    if (!event.classNames.includes('ter-kal-hidden')) {
339                        event.setProp('classNames', [...event.classNames, 'ter-kal-hidden']);
340                    }
341                }
342            });
343        }
344
345    //---------------------------------------------------------------------------
346    //---------------------------------------------------------------------------
347    }); // end each calendar instance
348    //---------------------------------------------------------------------------
349    //---------------------------------------------------------------------------
350
351  }); // end jQuery
352
353}); // document.addEventListener
354//---------------------------------------------------------------------------
355//---------------------------------------------------------------------------

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.