PageSourceSearch

https://fc-germania-bieber.de/wp-content/plugins/eventprime-event-…/js/ep-frontend-events.js?ver=4.3.5.0

js fc-germania-bieber.de collected 2026-10-02 20:21:07 UTC 127,496 bytes, 2,960 lines download raw bytes

1jQuery(function ($) {
2    // initialize the select2 on click on the filter
3    $(document).on('click', '.ep-filter-bar-toggle-filter', function () {
4        // close other filters first
5        $('.ep-filter-bar-filter-container').each(function () {
6            let select2_id = $(this).find('.ep-filter-dropdown-created').attr('data-select2-id');
7            if (select2_id) {
8                $(this).find('.ep-filter-bar-filter-close').trigger('click');
9            }
10        });
11        // hide if cost slide visible
12        if ($('#ep-cost-filter-bar-container').css('display') == 'block') {
13            $('#ep-cost-filter-bar-container').hide();
14        }
15
16        let $id = this.id;
17        $('#' + $id + '-container').show();
18        if ($id != 'ep-cost-filter-bar-container') {
19            $('#' + $id + '-container .ep-filter-dropdown-created').select2();
20            $('#' + $id + '-container .ep-filter-dropdown-created').select2('open');
21            if ($('.select2-container').length > 0) {
22                $('.select2-container').addClass('ep-event-bottom-filter-list');
23            }
24        }
25    });
26
27    // close and destroy select2 
28    $(document).on('click', '.ep-filter-bar-filter-close', function () {
29        let $id = $(this).closest('.ep-filter-bar-filter-container').id;
30        $(this).closest('.ep-filter-bar-filter-container').find('.ep-filter-dropdown-created').select2('destroy');
31        $(this).closest('.ep-filter-bar-filter-container').hide();
32    });
33
34    // show event calendar
35
36    $(document).ready(function () {
37        ep_load_calendar_view();
38    });
39
40    // Load More
41    // $(document).on('click','#ep-loadmore-events',function(e){
42    $(document).on('click', '.ep-loadmore-events', function (e) {
43        var max_page = $(this).data('max');
44        var section_id = $(this).data('section_id');
45        $('.ep-spinner-' + section_id).addClass('ep-is-active');
46        $('#ep-loadmore-events').prop("disabled", true);
47        var paged = $('#ep-events-paged-' + section_id).val();
48        var display_style = $('#ep-events-style-' + section_id).val();
49        var limit = $('#ep-events-limit-' + section_id).val();
50        var order = $('#ep-events-order-' + section_id).val();
51        var event_types_ids = $('#ep-events-types-ids-' + section_id).val();
52        var event_venues_ids = $('#ep-events-venues-ids-' + section_id).val();
53        var event_cols = $('#ep-events-cols-' + section_id).val();
54        var i_events = $('#ep-events-i-events-' + section_id).val();
55        // var search = $('#ep-events-search').val();
56        var formData = new FormData();
57        formData.append('action', 'ep_load_more_events');
58        formData.append('paged', paged);
59        formData.append('display_style', display_style);
60        formData.append('limit', limit);
61        formData.append('order', order);
62        formData.append('event_types_ids', event_types_ids);
63        formData.append('event_venues_ids', event_venues_ids);
64        formData.append('event_cols', event_cols);
65        formData.append('i_events', i_events);
66        formData.append('event_search_params', JSON.stringify(event_search_params));
67        // formData.append('search',search);
68        if ($('#ep_keyword').length && $('#ep_keyword').val() != '') {
69            formData.append('keyword', $('#ep_keyword').val());
70            formData.append('ep_search', true);
71        }
72        formData.append('event_atts', JSON.stringify(em_front_event_object.event_attributes));
73
74        $('.ep-register-response').html();
75        $.ajax({
76            type: "POST",
77            url: eventprime.ajaxurl,
78            data: formData,
79            contentType: false,
80            processData: false,
81            success: function (response) {
82                $('.ep-spinner-' + section_id).removeClass('ep-is-active');
83                $('#ep-loadmore-events').prop("disabled", false);
84                $('#ep-events-paged-' + section_id).val(response.data.paged);
85                if (response.data.paged >= max_page) {
86                    $('.ep-events-load-more-' + section_id).hide();
87                }
88                // $( '#ep_events_front_views_' + display_style ).append(response.data.html);
89                $('.ep_events_front_views_' + display_style + '_' + section_id).append(response.data.html);
90                if (display_style === 'staggered_grid') {
91                    var container = document.querySelector('#ep_events_front_views_staggered_grid');
92                    if (container) {
93                        var msnry;
94                        imagesLoaded(container, function () {
95                            msnry = new Masonry(container, {
96                                itemSelector: '#ep_events_front_views_staggered_grid .ep-event-card'
97                            });
98                        });
99                    }
100                }
101                //Removed in 3.3.5
102                epCard_width_adjust(".ep-event-card");
103
104                if (eventprime.global_settings.events_no_of_columns === 4) {
105                    jQuery(".ep-event-card").addClass(["ep-card-col-3"]).removeClass(["ep-card-col-4", "ep-card-col-6", "ep-card-col-12"]);
106                }
107                if (eventprime.global_settings.events_no_of_columns === 3) {
108                    jQuery(".ep-event-card").addClass(["ep-card-col-4"]).removeClass(["ep-card-col-3", "ep-card-col-6", "ep-card-col-12"]);
109                }
110
111                if (eventprime.global_settings.events_no_of_columns === 2) {
112                    jQuery(".ep-event-card").addClass(["ep-card-col-6"]).removeClass(["ep-card-col-3", "ep-card-col-4", "ep-card-col-12"]);
113                }
114
115                if (eventprime.global_settings.events_no_of_columns === 1) {
116                    jQuery(".ep-event-card").addClass(["ep-card-col-12"]).removeClass(["ep-card-col-3", "ep-card-col-4", "ep-card-col-6"]);
117                }
118
119            }
120        });
121    });
122    /**
123     * Event Filters start
124     */
125    var event_search_params = [];
126    // event view filter
127    $(document).ready(function (e) {
128        var filter_value = localStorage.getItem("ep_calendar_date");
129        if (filter_value !== null && filter_value !== '') {
130            jQuery('#filter-date-from').val(filter_value);
131            let param = {label: 'From', key: 'date_from', value: filter_value, text: filter_value};
132            event_applied_filters_render_content(param);
133            event_filters_selection_update(event_search_params, param);
134
135            let param2 = {label: 'To', key: 'date_to', value: filter_value, text: filter_value};
136            event_applied_filters_render_content(param2);
137            event_filters_selection_update(event_search_params, param2);
138
139            let param3 = {label: 'Days', key: 'days', value: 'all', text: 'All Days'};
140            event_applied_filters_render_content(param3);
141            event_filters_selection_update(event_search_params, param3);
142
143            let display_style = $('#ep-events-style').val();
144            event_applied_filters(display_style, event_search_params);
145
146            localStorage.removeItem('ep_calendar_date');
147        }
148    });
149    $(document).on('click', '.ep_event_view_filter', function () {
150        let view_name = $(this).data('event_view');
151        $('.ep_event_view_filter').removeClass('ep-active-view');
152        $(this).addClass('ep-active-view');
153        event_applied_filters(view_name, event_search_params);
154    });
155
156    $(document).on('click', '.ep-clear-filter', function () {
157        var parentEle = $(this).parent().attr('id');
158        var filter_key = $(this).parent().data('key');
159        event_filters_selection_remove(event_search_params, filter_key);
160        $('#' + parentEle).remove();
161        var view_name = $('#ep-events-style').val();
162        event_applied_filters(view_name, event_search_params);
163        if ($("#ep-search-filters").css("visibility") === "visible") {
164            $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
165        }
166        $(".ep-search-filter-overlay").hide();
167    });
168    // keyword search
169    /*$( document ).on( 'click', '#ep_event_find_events_btn', function() {
170     $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
171     $(".ep-search-filter-overlay").hide();
172     let search_keyword = $( '#ep_event_keyword_search' ).val();
173     //if(search_keyword) {
174     // sanitize the input first
175     /*
176     let post_data = {
177     action   : 'ep_sanitize_input_field_data',
178     security : em_front_event_object._nonce,
179     input_val: search_keyword,
180     };
181     $.ajax({
182     type    : "POST",
183     url     : eventprime.ajaxurl,
184     data    : post_data,
185     success : function( response ) {
186     if( response.success ) {
187     //search_keyword = response.data;
188     // render html
189     let param = { label: 'Keyword', key: 'keyword', value: search_keyword };
190     if( search_keyword ) {
191     // update html
192     event_applied_filters_render_content( param );
193     event_filters_selection_update(event_search_params, param);    
194     }
195     //event_search_params.push( param );
196     let display_style = $('#ep-events-style').val();
197     event_applied_filters( display_style, event_search_params );
198     /* } else{
199     show_toast( 'error', response.data.message );
200     return false;
201     }
202     }
203     });
204     // }
205     
206     });
207     */
208
209    function runEventSearch() {
210        $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
211        $(".ep-search-filter-overlay").hide();
212
213        const search_keyword = $('#ep_event_keyword_search').val();
214
215        const param = {label: 'Keyword', key: 'keyword', value: search_keyword};
216        if (search_keyword) {
217            event_applied_filters_render_content(param);
218            event_filters_selection_update(event_search_params, param);
219        }
220
221        const display_style = $('#ep-events-style').val();
222        event_applied_filters(display_style, event_search_params);
223    }
224
225    // Click on "Find Events"
226    $(document).on('click', '#ep_event_find_events_btn', function (e) {
227        e.preventDefault();
228        runEventSearch();
229    });
230
231    // Press Enter inside the keyword input
232    $(document).on('keydown', '#ep_event_keyword_search', function (e) {
233        if (e.key === 'Enter' || e.keyCode === 13 || e.which === 13) {
234            e.preventDefault(); // prevent form/page submit
235            runEventSearch();
236        }
237    });
238
239    // Optional: if the input is inside a form
240    // (change #ep_event_search_form to your actual form id if different)
241    $(document).on('submit', '#ep_event_search_form', function (e) {
242        e.preventDefault();
243        runEventSearch();
244    });
245
246    $(document).on('click', '.ep-filters-days', function () {
247        let filter_value = $(this).data('key');
248        let filter_text = $(this).text();
249        if (filter_value) {
250            // render html
251            let param = {label: 'Days', key: 'days', value: filter_value, text: filter_text};
252            // update html
253            event_applied_filters_render_content(param);
254            event_filters_selection_update(event_search_params, param);
255            let display_style = $('#ep-events-style').val();
256            event_applied_filters(display_style, event_search_params);
257        }
258    });
259
260    $(document).on('change', '#filter-date-from', function () {
261        let filter_value = $('#filter-date-from').val();
262        if (filter_value !== '') {
263            let param = {label: 'From', key: 'date_from', value: filter_value, text: filter_value};
264            event_applied_filters_render_content(param);
265            event_filters_selection_update(event_search_params, param);
266        }
267        let date_filter_value = $('#filter-date-days').val();
268        let filter_end_date_value = $('#filter-date-to').val();
269        let filter_text = $("#filter-date-days").find("option[value='" + $("#filter-date-days").val() + "']").text();
270        if (date_filter_value !== '' && filter_end_date_value !== '') {
271            $('#filter-date-days-section').show(500);
272            let param = {label: 'Days', key: 'days', value: date_filter_value, text: filter_text};
273            event_applied_filters_render_content(param);
274            event_filters_selection_update(event_search_params, param);
275        } else if (date_filter_value !== '' && filter_end_date_value === '') {
276            $('#filter-date-days-section').hide(500);
277            event_filters_selection_remove(event_search_params, 'days');
278        }
279    });
280
281    $(document).on('change', '#filter-date-to', function () {
282        let filter_value = $('#filter-date-to').val();
283        if (filter_value) {
284            let param = {label: 'To', key: 'date_to', value: filter_value, text: filter_value};
285            event_applied_filters_render_content(param);
286            event_filters_selection_update(event_search_params, param);
287        }
288
289        let date_filter_value = $('#filter-date-days').val();
290        let filter_start_date_value = $('#filter-date-from').val();
291        let filter_text = $("#filter-date-days").find("option[value='" + $("#filter-date-days").val() + "']").text();
292        if (date_filter_value !== '' && filter_start_date_value !== '') {
293            $('#filter-date-days-section').show(500);
294            let param = {label: 'Days', key: 'days', value: date_filter_value, text: filter_text};
295            event_applied_filters_render_content(param);
296            event_filters_selection_update(event_search_params, param);
297        } else if (date_filter_value !== '' && filter_start_date_value === '') {
298            $('#filter-date-days-section').hide(500);
299            event_filters_selection_remove(event_search_params, 'days');
300        }
301    });
302
303    $(document).on('change', '#filter-date-days', function () {
304        let filter_value = $('#filter-date-days').val();
305        if (filter_value) {
306            let param = {label: 'Days', key: 'days', value: filter_value, text: filter_value};
307            event_applied_filters_render_content(param);
308            event_filters_selection_update(event_search_params, param);
309        }
310    });
311
312    $(document).on('change', '#ep-filter-types', function () {
313        let filter_text = $("#ep-filter-types").find("option[value='" + $("#ep-filter-types").val() + "']").text();
314        let filter_value = $('#ep-filter-types').val();
315        if (filter_value !== '') {
316            // render html
317            let param = {label: em_front_event_object.event_types, key: 'event_types', value: filter_value, text: filter_text};
318            // update html
319            event_applied_filters_render_content(param);
320            //event_search_params.push( param );
321            event_filters_selection_update(event_search_params, param);
322            //let display_style = $('#ep-events-style').val();
323            //event_applied_filters( display_style, event_search_params );
324        }
325    });
326
327    $(document).on('change', '#ep-filter-venues', function () {
328        let filter_text = $("#ep-filter-venues").find("option[value='" + $("#ep-filter-venues").val() + "']").text();
329        let filter_value = $('#ep-filter-venues').val();
330        if (filter_value !== '') {
331            // render html
332            let param = {label: em_front_event_object.venues, key: 'event_venues', value: filter_value, text: filter_text};
333            // update html
334            event_applied_filters_render_content(param);
335            event_filters_selection_update(event_search_params, param);
336            //let display_style = $('#ep-events-style').val();
337            //event_applied_filters( display_style, event_search_params );
338
339        }
340    });
341
342    $(document).on('change', '#ep-filter-performer', function () {
343        //let filter_text = $("#ep-filter-performer").find("option[value='" + $("#ep-filter-performer").val() + "']").text();
344        let filter_value = $('#ep-filter-performer').val();
345        if (filter_value.length == 0) {
346            event_filters_selection_remove(event_search_params, 'event_performers');
347            $('#ep_event_performers').remove();
348        } else if (filter_value.length > 0) {
349            // render html
350            let param = {label: em_front_event_object.performers, key: 'event_performers', value: filter_value, text: filter_value.length + ' Selected'};
351            // update html
352            event_applied_filters_render_content(param);
353            event_filters_selection_update(event_search_params, param);
354            //let display_style = $('#ep-events-style').val();
355            //event_applied_filters( display_style, event_search_params );
356
357        }
358    });
359
360    $(document).on('change', '#ep-filter-org', function () {
361        //let filter_text = $("#ep-filter-performer").find("option[value='" + $("#ep-filter-performer").val() + "']").text();
362        let filter_value = $('#ep-filter-org').val();
363        if (filter_value.length == 0) {
364            event_filters_selection_remove(event_search_params, 'event_performers');
365            $('#ep_event_organizers').remove();
366        } else if (filter_value.length > 0) {
367            // render html
368            let param = {label: em_front_event_object.organizers, key: 'event_organizers', value: filter_value, text: filter_value.length + ' Selected'};
369            // update html
370            event_applied_filters_render_content(param);
371            event_filters_selection_update(event_search_params, param);
372        }
373    });
374
375    if ($('#ep-filter-event-tags').length) {
376        $(document).on('change', '#ep-filter-event-tags', function () {
377            let filter_value = $('#ep-filter-event-tags').val();
378            //console.log(filter_value)
379            if (filter_value.length == 0) {
380                event_filters_selection_remove(event_search_params, 'event_tags');
381                $('#ep_event_tags').remove();
382            } else if (filter_value.length > 0) {
383                // render html
384                // let param = { label: ep_custom_dash_pub_obj.event_tags_events_lising_fliter_placeholder, key:'event_tags', value: filter_value, text: filter_value.length+' Selected' };
385                let selectedTexts = [];
386                filter_value.forEach(function (val) {
387                    let text = $('#ep-filter-event-tags option[value="' + val + '"]').text();
388                    if (text) {
389                        selectedTexts.push(text.trim());
390                    }
391                });
392                let selectedTextsString = selectedTexts.join(', ');
393                let param = {label: ep_custom_dash_pub_obj.event_tags_events_lising_fliter_placeholder, key: 'event_tags', value: filter_value, text: selectedTextsString};
394                // update html
395                event_applied_filters_render_content(param);
396                event_filters_selection_update(event_search_params, param);
397            }
398        });
399    }
400
401    // edit timezone
402    $(document).on('click', '#ep-user-profile-timezone-edit', function () {
403        $(this).hide();
404        $('.ep-user-profile-timezone-list').show();
405    });
406
407    // save the user timezone
408    $(document).on('click', '#ep_user_profile_timezone_save', function () {
409        let time_zone = $('#ep_user_profile_timezone_list').val();
410        if (time_zone) {
411            $('.ep-event-loader').show();
412            let data = {
413                action: 'ep_update_user_timezone',
414                security: em_front_event_object._nonce,
415                time_zone: time_zone,
416                reload: 1
417            };
418            $.ajax({
419                type: "POST",
420                url: eventprime.ajaxurl,
421                data: data,
422                success: function (response) {
423                    $('.ep-event-loader').hide();
424                    if (response == -1) {
425                        show_toast('error', em_front_event_object.nonce_error);
426                        return false;
427                    }
428                    if (response.success == false) {
429                        show_toast('error', response.data.error);
430                        return false;
431                    } else {
432                        show_toast('success', response.data.message);
433                        setTimeout(function () {
434                            location.reload();
435                        }, 1000);
436                    }
437                }
438            });
439        }
440    });
441
442});
443
444document.addEventListener("DOMContentLoaded", function (event) {
445    jQuery(document).ready(function () {
446        var container = document.querySelector('#ep_events_front_views_staggered_grid');
447        if (container) {
448            var msnry;
449            imagesLoaded(container, function () {
450                msnry = new Masonry(container, {
451                    itemSelector: '#ep_events_front_views_staggered_grid .ep-event-card'
452                });
453            });
454        }
455
456        if (!eventprime.global_settings.events_no_of_columns) {
457            epCard_width_adjust(".ep-event-card");
458        }
459
460        //Event FilterBar for Smaller Screen
461
462        epSearch_width_adjust(".ep-event-views-col");
463        epSearch_bar_width_adjust(".ep-search-filter-bar");
464
465        jQuery('.ep-event-loader').hide();
466    });
467});
468
469function event_applied_filters(event_view_name, event_search_params) {
470    //if( view || ( event_search_params && event_search_params.length > 0 ) ) {
471    jQuery('.ep-event-loader').show();
472    //console.log(event_view_name);
473    //console.log(event_search_params);
474    let formData = new FormData();
475    formData.append('action', 'ep_filter_event_data');
476    formData.append('event_search_params', JSON.stringify(event_search_params));
477    formData.append('display_style', event_view_name);
478    formData.append('event_atts', JSON.stringify(em_front_event_object.event_attributes));
479    jQuery.ajax({
480        type: "POST",
481        url: eventprime.ajaxurl,
482        data: formData,
483        contentType: false,
484        processData: false,
485        success: function (response) {
486            jQuery('.ep-event-loader').hide();
487            if (response.success) {
488                if (response.data.html) {
489                    // check for view
490                    let existing_display_style = jQuery('#ep-events-style').val();
491                    let event_container_id = 'ep_events_front_views_' + existing_display_style;
492                    if (existing_display_style != event_view_name) { //change the view
493                        jQuery('#ep-events-style').val(event_view_name);
494                        let old_event_class = 'ep-event-list-' + existing_display_style + '-container';
495                        let new_event_class = 'ep-event-list-' + event_view_name + '-container';
496                        jQuery('.ep-events').removeClass(old_event_class).addClass(new_event_class);
497                        event_container_id = 'ep_events_front_views_' + event_view_name;
498                        jQuery('.' + new_event_class).attr('id', event_container_id);
499                        jQuery('#ep-events-content-container').html(response.data.html);
500                        if (event_view_name == 'month') {
501                            ep_render_calendar_view(response.data.cal_events, JSON.stringify(event_search_params));
502                        }
503                        if (event_view_name === 'masonry' || event_view_name === 'staggered_grid') {
504                            var container = document.querySelector('#ep_events_front_views_masonry');
505                            if (container) {
506                                var msnry;
507                                imagesLoaded(container, function () {
508                                    msnry = new Masonry(container, {
509                                        itemSelector: '#ep_events_front_views_masonry .ep-event-card',
510                                    });
511                                });
512                            } else {
513                                var container = document.querySelector('#ep_events_front_views_staggered_grid');
514                                if (container) {
515                                    var msnry;
516                                    imagesLoaded(container, function () {
517                                        msnry = new Masonry(container, {
518                                            itemSelector: '#ep_events_front_views_staggered_grid .ep-event-card',
519                                        });
520                                    });
521                                }
522                            }
523                        }
524                    } else {
525                        jQuery('#ep-events-content-container').html(response.data.html);
526                        if (event_view_name == 'month') {
527                            ep_render_calendar_view(response.data.cal_events, JSON.stringify(event_search_params));
528                        }
529                    }
530
531                    if (event_search_params && event_search_params.length > 0) {
532                        jQuery('#ep_event_various_filters_section').fadeIn(500);
533                        if (event_search_params.length == 1) {
534                            jQuery('#ep_total_filters_applied').html(event_search_params.length + ' ' + em_front_event_object.filter_applied_text);
535                        } else {
536                            jQuery('#ep_total_filters_applied').html(event_search_params.length + ' ' + em_front_event_object.filters_applied_text);
537                        }
538                    } else {
539                        jQuery('#ep_event_various_filters_section').hide();
540                    }
541                    epCard_width_adjust(".ep-event-card");
542                    if (eventprime.global_settings.events_no_of_columns === 4) {
543                        jQuery(".ep-event-card").addClass(["ep-card-col-3"]).removeClass(["ep-card-col-4", "ep-card-col-6", "ep-card-col-12"]);
544                    }
545                    if (eventprime.global_settings.events_no_of_columns === 3) {
546                        jQuery(".ep-event-card").addClass(["ep-card-col-4"]).removeClass(["ep-card-col-3", "ep-card-col-6", "ep-card-col-12"]);
547                    }
548
549                    if (eventprime.global_settings.events_no_of_columns === 2) {
550                        jQuery(".ep-event-card").addClass(["ep-card-col-6"]).removeClass(["ep-card-col-3", "ep-card-col-4", "ep-card-col-12"]);
551                    }
552
553                    if (eventprime.global_settings.events_no_of_columns === 1) {
554                        jQuery(".ep-event-card").addClass(["ep-card-col-12"]).removeClass(["ep-card-col-3", "ep-card-col-4", "ep-card-col-6"]);
555                    }
556                }
557            }
558        }
559    });
560
561    //}
562
563
564}
565
566function event_applied_filters_render_content(param) {
567    let filter_html = '';
568    var value = param.text ? param.text : param.value;
569    if (jQuery('#ep_' + param.key).length > 0) {
570        filter_html += '<button type="button" class="ep-btn ep-text-dark">';
571        filter_html += '<strong class="ep-text-small">' + param.label + ': </strong>';
572        filter_html += '<span class="ep-text-small">' + value + '</span>';
573        filter_html += '</button>';
574        filter_html += '<button type="button" class="ep-btn ep-text-primary ep-clear-filter">';
575        filter_html += '<span class="material-icons-outlined ep-fs-6">close</span>';
576        filter_html += '</button>';
577        jQuery('#ep_' + param.key).html(filter_html);
578    } else {
579        filter_html += '<div data-key="' + param.key + '" id="ep_' + param.key + '" class="ep-btn-group ep-btn-group-sm ep-bg-primary ep-bg-opacity-10 ep-rounded-1 ep-mb-2 ep-mr-1" role="group" aria-label="' + param.label + '">';
580        filter_html += '<button type="button" class="ep-btn ep-text-dark ep-border-0">';
581        filter_html += '<strong class="ep-text-small">' + param.label + ': </strong>';
582        filter_html += '<span class="ep-text-small">' + value + '</span>';
583        filter_html += '</button>';
584        filter_html += '<button type="button" class="ep-btn ep-text-primary ep-clear-filter ep-border-0">';
585        filter_html += '<span class="material-icons-outlined ep-fs-6">close</span>';
586        filter_html += '</button>';
587        filter_html += '</div>';
588        // append html
589        jQuery('#ep_applied_filters_section').append(filter_html);
590    }
591}
592
593function event_filters_selection_update(event_search_params, param) {
594    var found = false;
595    for (const i of event_search_params) {
596        if (i.key == param.key) {
597            found = true;
598            i.value = param.value;
599        }
600    }
601    if (found === false) {
602        event_search_params.push(param);
603    }
604}
605
606function event_filters_selection_remove(event_search_params, key) {
607    for (var i = 0; i < event_search_params.length; i++) {
608        if (event_search_params[i].key == key) {
609            event_search_params.splice(i, 1);
610            if (key === 'date_from') {
611                jQuery('#filter-date-from').val('');
612            } else if (key === 'date_to') {
613                jQuery('#filter-date-from').val('');
614            } else if (key === 'days') {
615                jQuery('#filter-date-days').val('');
616            } else if (key === 'event_types') {
617                jQuery('#ep-filter-types').val(null);
618            } else if (key === 'event_venues') {
619                jQuery('#ep-filter-venues').select2("val", "");
620            } else if (key === 'event_performers') {
621                jQuery('#filter_performer').select2("val", "");
622            } else if (key === 'event_organizers') {
623                jQuery('#ep-filter-org').select2();
624            }
625            break;
626        }
627    }
628}
629
630function ep_render_calendar_view(cal_events, search_param = '')
631{
632    ep_load_calendar_view(search_param);
633}
634
635function columnHeaderFormat(format) {
636    var calFormat = {weekday: 'short'};
637    if (format == 'dddd') {
638        calFormat = {weekday: 'long'};
639    }
640    if (format == 'ddd D/M') {
641        calFormat = {weekday: 'long', day: 'numeric', month: 'numeric', omitCommas: true};
642    }
643    if (format == 'ddd M/D') {
644        calFormat = {weekday: 'long', month: 'numeric', day: 'numeric', omitCommas: true};
645    }
646    return calFormat;
647}
648
649function epCard_width_adjust(cardClass) {
650    $ = jQuery;
651    jQuery(".ep-event-card").removeClass(["ep-card-col-", "ep-card-col-1", "ep-card-col-2", "ep-card-col-3", "ep-card-col-4", "ep-card-col-5"]);
652    kfWidth = $("#ep-events-content-container").innerWidth();
653
654    if (kfWidth < 720) {
655        $("#ep-events-content-container").addClass("ep-narrow");
656    }
657    switch (true) {
658        case kfWidth <= 500:
659            $(cardClass).addClass("ep-card-col-12");
660
661        case kfWidth <= 650:
662            $(cardClass).addClass("ep-card-col-6");
663
664            break;
665        case kfWidth <= 850:
666            $(cardClass).addClass("ep-card-col-4");
667
668            break;
669        case kfWidth <= 1150:
670            $(cardClass).addClass("ep-card-col-3");
671
672            break;
673        case kfWidth <= 1280:
674            $(cardClass).addClass("ep-card-col-3");
675
676            break;
677        case kfWidth > 1280:
678            $(cardClass).addClass("ep-card-col-3 ep-default");
679
680            break;
681        default:
682            $(cardClass).addClass("ep-card-col-3 ep-default");
683            break;
684    }
685}
686function epSearch_width_adjust(searchFilterClass) {
687    $ = jQuery;
688    jQuery(".ep-event-views-col").removeClass(["ep-box-col-4"]);
689    searchWidth = $("#ep_event_search_form").innerWidth();
690    //console.log(searchWidth);
691    switch (true) {
692
693        case searchWidth <= 650:
694            $(searchFilterClass).addClass("ep-box-col-12");
695
696        default:
697            $(searchFilterClass).addClass("ep-box-col-4 ep-default");
698            break;
699    }
700}
701function epSearch_bar_width_adjust(searchBarFilterClass) {
702    $ = jQuery;
703    jQuery(".ep-search-filter-bar").removeClass(["ep-box-col-8"]);
704    searchWidth = $("#ep_event_search_form").innerWidth();
705    switch (true) {
706
707        case searchWidth <= 650:
708            $(searchBarFilterClass).addClass("ep-box-col-12");
709
710        default:
711            $(searchBarFilterClass).addClass("ep-box-col-8 ep-default");
712            break;
713    }
714}
715
716
717// on window resize
718jQuery(window).resize(function () {
719
720    if (jQuery("#ep-events-content-container").length > 0) {
721        jQuery(".ep-event-card").removeClass(["ep-card-col-", "ep-card-col-12", "ep-card-col-6", "ep-card-col-4", "ep-card-col-3", "ep-card-col-2"]);
722        epCard_width_adjust(".ep-event-card");
723    }
724    if (eventprime.global_settings.events_no_of_columns === 4) {
725        jQuery(".ep-event-card").addClass(["ep-card-col-3"]).removeClass(["ep-card-col-4", "ep-card-col-6", "ep-card-col-12"]);
726    }
727
728    if (eventprime.global_settings.events_no_of_columns === 3) {
729        jQuery(".ep-event-card").addClass(["ep-card-col-4"]).removeClass(["ep-card-col-3", "ep-card-col-6", "ep-card-col-12"]);
730        ;
731    }
732
733    if (eventprime.global_settings.events_no_of_columns === 2) {
734        jQuery(".ep-event-card").addClass(["ep-card-col-6"]).removeClass(["ep-card-col-3", "ep-card-col-4", "ep-card-col-12"]);
735    }
736
737    if (eventprime.global_settings.events_no_of_columns === 1) {
738        jQuery(".ep-event-card").addClass(["ep-card-col-12"]).removeClass(["ep-card-col-3", "ep-card-col-4", "ep-card-col-6"]);
739        ;
740    }
741
742    epCalViewWidhth();
743
744});
745
746// check calendar view width
747function epCalViewWidhth() {
748    $ = jQuery;
749    calAreaWidht = $("#ep-events-content-container").innerWidth();
750    if (calAreaWidht <= 620) {
751        $("#ep-events-content-container").addClass("ep-narrow");
752        $("#ep-events-content-container").removeClass("ep-wide");
753
754        //Event Search Filter
755        $('.ep-event-views-col').removeClass('ep-justify-content-end');
756        $('.ep-event-views-col').addClass('ep-justify-content-center');
757    } else {
758        $("#ep-events-content-container").removeClass("ep-narrow");
759        $("#ep-events-content-container").addClass("ep-wide");
760
761        //Event Search Filter
762        $('.ep-event-views-col').removeClass('ep-justify-content-center');
763    }
764}
765
766function formatDate(date, locale, pattern = 'MMMM, YYYY') {
767    if (!(date instanceof Date) || isNaN(date)) {
768        return ''; // Handle invalid date
769    }
770
771    // Construct the formatted date using Intl.DateTimeFormat options
772    var options = {year: 'numeric', month: 'long', day: 'numeric'};
773    var formatter = new Intl.DateTimeFormat(locale, options);
774    var formattedDate = formatter.format(date);
775
776    // Extract the month index using the format method
777    var monthIndex = date.getMonth();
778
779    var monthNames = getMonthNames(locale);
780
781    var formattedPattern = pattern.toString()
782            .replace('YYYY', date.getFullYear())
783            .replace('MMMM', monthNames[monthIndex])
784            .replace('DD', date.getDate());
785
786    return formattedPattern;
787}
788
789
790function getMonthNames(locale) {
791    // Use Intl.DateTimeFormat to get month names for the specified locale
792    var monthNames = [];
793    for (var i = 0; i < 12; i++) {
794        var formattedMonth = new Date(2000, i, 1).toLocaleDateString(locale, {month: 'long'});
795        monthNames.push(formattedMonth);
796    }
797    return monthNames;
798}
799
800jQuery(document).ready(function () {
801    // Check if the user is using a mobile device
802    setTimeout(function () {
803        const calAreaWidht = jQuery("#ep-events-content-container").innerWidth();
804        var isMobile = /iPhone|iPad|iPod|Android|webOS|BlackBerry|Windows Phone/i.test(navigator.userAgent);
805        if (isMobile || calAreaWidht <= 720) {
806            // Remove href attribute for event table a tag
807            jQuery('#ep_event_calendar.fc table.fc-scrollgrid-sync-table .fc-daygrid-event').removeAttr('href');
808        }
809    }, 3000);
810});
811
812
813function ep_load_calendar_view(search_param = '')
814{
815
816    // set initial view
817    let default_view = 'dayGridMonth';
818    let calendar_views = {
819        'month': 'dayGridMonth',
820        'week': 'dayGridWeek',
821        'day': 'dayGridDay',
822        'listweek': 'listWeek',
823    };
824    if (eventprime.global_settings.default_cal_view) {
825        if (em_front_event_object.view) {
826            default_view = calendar_views[em_front_event_object.view];
827        } else {
828            default_view = calendar_views[eventprime.global_settings.default_cal_view];
829        }
830    }
831    // set initial date
832    let cal_initial_date = new Date();
833    if (eventprime.global_settings.enable_default_calendar_date == 1) {
834        if (eventprime.global_settings.default_calendar_date && eventprime.global_settings.default_calendar_date != '') {
835            cal_initial_date = eventprime.global_settings.default_calendar_date;
836        }
837    }
838    // hide prev and next month rows
839    let hide_calendar_rows = true;
840    if (eventprime.global_settings.hide_calendar_rows == 1) {
841        hide_calendar_rows = false;
842    }
843    // set calendar right view options
844    let right_views = [];
845    if (eventprime.global_settings.front_switch_view_option) {
846        if (eventprime.global_settings.front_switch_view_option.indexOf('month') > -1) {
847            right_views.push('dayGridMonth');
848        }
849        if (eventprime.global_settings.front_switch_view_option.indexOf('week') > -1) {
850            right_views.push('dayGridWeek');
851        }
852        if (eventprime.global_settings.front_switch_view_option.indexOf('day') > -1) {
853            right_views.push('dayGridDay');
854        }
855        if (eventprime.global_settings.front_switch_view_option.indexOf('listweek') > -1) {
856            right_views.push('listWeek');
857        }
858    }
859    if (right_views && right_views.length > 0) {
860        right_views = right_views.toString();
861    } else {
862        right_views = '';
863    }
864    // set column header format
865    let calendar_column_header_format = eventprime.global_settings.calendar_column_header_format;
866    let column_header_format = 'long';
867    if (calendar_column_header_format == 'ddd') {
868        column_header_format = 'short';
869    }
870    // set day max events
871    let day_max_events = eventprime.global_settings.show_max_event_on_calendar_date;
872    if (!day_max_events) {
873        day_max_events = 2;
874    }
875    // set 12 and 24 hours
876    let hour12 = true;
877    if (eventprime.global_settings.time_format == 'HH:mm') {
878        hour12 = false;
879    }
880    var calendarEl = document.getElementById('ep_event_calendar');
881    var element = jQuery('#ep_hidden_args').val();
882    // if (element !== null) {
883    if (element) {
884        var args = element;
885        // Do something with args
886    } else if (em_front_event_object.event_attributes) {
887        var args = JSON.stringify(em_front_event_object.event_attributes);
888    } else {
889        var args = '';
890    }
891
892    if (calendarEl) {
893        const use24h = window.em_front_event_object && em_front_event_object.timeformat === 'HH:mm';
894        var calendar = new FullCalendar.Calendar(calendarEl, {
895            headerToolbar: {
896                left: 'prevYear,prev,next,nextYear today',
897                center: 'title',
898                right: right_views
899            },
900            // views: {
901            //     listWeek: { buttonText: 'Agenda' }
902            // },
903            buttonText: {
904                listWeek: em_front_event_object.list_week_btn_text,
905            },
906            initialDate: cal_initial_date,
907            initialView: default_view,
908            navLinks: true, // can click day/week names to navigate views
909            dayMaxEvents: day_max_events, // allow "more" link when too many events
910            editable: false,
911            timeZone: 'local',
912            eventTimeFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
913            slotLabelFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
914            height: "auto",
915            events: function (info, successCallback, failureCallback) {
916                // Calculate the start and end dates of the current month
917                jQuery('.ep-event-loader').show();
918                $.ajax({
919                    url: eventprime.ajaxurl, // Replace with your events API endpoint
920                    method: 'POST',
921                    data: {
922                        action: 'ep_get_calendar_event',
923                        security: em_front_event_object._nonce,
924                        start: info.startStr,
925                        end: info.endStr,
926                        args: args,
927                        search_param: search_param
928
929                    },
930                    success: function (data) {
931
932
933
934                        if (data.data) {
935                            const pad = n => String(n).padStart(2, '0');
936
937                            const toISO = (dateStr, timeStr) => {
938                                // timeStr like "11:45 PM" or "12:00 AM"
939                                const d = new Date(`${dateStr} ${timeStr}`);
940                                const y = d.getFullYear();
941                                const m = pad(d.getMonth() + 1);
942                                const da = pad(d.getDate());
943                                const h = pad(d.getHours());
944                                const mi = pad(d.getMinutes());
945                                return `${y}-${m}-${da}T${h}:${mi}:00`;
946                            };
947
948                            const addOneDayISODate = (dateStr) => {
949                                const d = new Date(`${dateStr}T00:00:00`);
950                                d.setDate(d.getDate() + 1);
951                                return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
952                            };
953
954                            const isDateOnly = (s) => typeof s === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(s);
955
956                            const normalized = data.data.map(e => {
957                                // Map WP field to FullCalendar
958                                e.allDay = (e.all_day === 1 || e.all_day === '1' || e.all_day === true);
959                                e.hideStartTime = !e.start_time; // true if start_time is blank
960                                e.hideEndTime = !e.end_time;   // true if end_time is blank
961                                // START: add time if missing for timed events
962                                if (isDateOnly(e.start) && !e.allDay && e.start_time) {
963                                    e.start = toISO(e.start, e.start_time);
964                                }
965                                // END: add time if missing for timed events
966                                if (isDateOnly(e.end) && !e.allDay && e.end_time) {
967                                    e.end = toISO(e.end, e.end_time);
968                                }
969                                
970
971                                return e;
972                            });
973
974                            successCallback(normalized);
975                        }
976
977                        setTimeout(function () {
978                            jQuery('.ep-event-loader').hide();
979                        }, 400);
980                        // jQuery('.ep-event-loader').hide();
981                    },
982                    error: function () {
983                        failureCallback();
984                    }
985                });
986            },
987
988            showNonCurrentDates: hide_calendar_rows,
989            fixedWeekCount: hide_calendar_rows,
990            nextDayThreshold: '00:00',
991            eventTimeFormat: {
992                hour: '2-digit',
993                minute: '2-digit',
994                hour12: hour12,
995                meridiem: 'short'
996            },
997            firstDay: em_front_event_object.start_of_week,
998            locale: em_front_event_object.local,
999            eventContent(arg) {
1000                const s = arg.event.extendedProps.display_start_time || '';
1001                const e = arg.event.extendedProps.display_end_time || '';
1002                let timeLabel = '';
1003
1004                if (arg.isStart && arg.isEnd && s && e)
1005                    timeLabel = `${s} – ${e}`;
1006                else if (arg.isStart && s)
1007                    timeLabel = s;
1008                else if (arg.isEnd && e)
1009                    timeLabel = e;
1010                else
1011                    timeLabel = ''; // middle day: no "00:00"
1012
1013                const timeEl = document.createElement('div');
1014                timeEl.className = 'fc-event-time';
1015                timeEl.textContent = timeLabel;
1016
1017                const titleEl = document.createElement('div');
1018                titleEl.className = 'fc-event-title';
1019                titleEl.textContent = arg.event.title || '';
1020
1021                return {domNodes: [timeEl, titleEl]};
1022            },
1023
1024            titleFormat: {year: 'numeric', month: 'long', day: 'numeric'},
1025            dayHeaderFormat: {weekday: column_header_format},
1026            eventDidMount: function (info) {
1027                console.log(info);
1028                let light_bg_color = '';
1029                if (info.event.extendedProps.hasOwnProperty('bg_color')) {
1030                    var epColorRgb = info.event.extendedProps.bg_color;
1031                    var avoid = "rgb";
1032                    var eprgbRemover = epColorRgb.replace(avoid, '');
1033                    var emColor_bg = eprgbRemover.substring(eprgbRemover.indexOf('(') + 1, eprgbRemover.indexOf(')'))
1034                    info.el.style.backgroundColor = `rgba(${emColor_bg},1)`;
1035                    light_bg_color = info.el.style.backgroundColor;
1036                    info.el.style.borderColor = `rgba(${emColor_bg},1)`;
1037                }
1038                var textColor = light_bg_color;
1039                if (info.event.extendedProps.hasOwnProperty('type_text_color')) {
1040                    textColor = info.event.extendedProps.type_text_color;
1041                }
1042                if (info.event.extendedProps.hasOwnProperty('event_text_color')) {
1043                    textColor = info.event.extendedProps.event_text_color;
1044                }
1045
1046                var fc_time = info.el.querySelector('.fc-event-time');
1047                if (fc_time) {
1048                    fc_time.style.color = textColor;
1049                    if (em_front_event_object.hide_time_on_front_calendar == 1) {
1050                        fc_time.textContent = '';
1051                        fc_time.style.color = '';
1052                    }
1053                }
1054
1055                if (textColor) {
1056                    var fc_time = info.el.querySelector('.fc-time');
1057                    if (fc_time) {
1058                        fc_time.style.color = textColor;
1059                        if (em_front_event_object.hide_time_on_front_calendar == 1) {
1060                            fc_time.textContent = '';
1061                            fc_time.style.color = '';
1062                        }
1063                    }
1064                    var fc_title = info.el.querySelector('.fc-event-title');
1065                    if (fc_title) {
1066                        fc_title.style.color = textColor;
1067                    }
1068                    var fc_list_time = info.el.querySelector('.fc-event-time');
1069                    if (fc_list_time) {
1070                        fc_list_time.style.color = textColor;
1071                    }
1072                    var fc_list_title = info.el.querySelector('.fc-list-item-title');
1073                    if (fc_list_title) {
1074                        fc_list_title.style.color = textColor;
1075                    }
1076                    var fc_list_event_time = info.el.querySelector('.fc-list-event-time');
1077                    if (fc_list_event_time) {
1078                        fc_list_event_time.style.color = textColor;
1079                    }
1080                    var fc_list_event_dot = info.el.querySelector('.fc-list-event-dot');
1081                    if (fc_list_event_dot) {
1082                        fc_list_event_dot.style.color = textColor;
1083                    }
1084                    var fc_list_event_title = info.el.querySelector('.fc-list-event-title');
1085                    if (fc_list_event_title) {
1086                        fc_list_event_title.style.color = textColor;
1087                    }
1088                }
1089
1090                // --- per-event time hiding/rewriting ---
1091                const {hideStartTime, hideEndTime} = info.event.extendedProps || {};
1092                const hour12 = (eventprime.global_settings.time_format !== 'HH:mm');
1093
1094                // format helper
1095                const fmt = d => {
1096                    if (!d)
1097                        return '';
1098                    try {
1099                        return new Intl.DateTimeFormat(em_admin_calendar_event_object.local, {
1100                            hour: '2-digit', minute: '2-digit', hour12
1101                        }).format(d);
1102                    } catch (e) {
1103                        // fallback
1104                        const pad = n => String(n).padStart(2, '0');
1105                        return d.getHours() + ':' + pad(d.getMinutes());
1106                    }
1107                };
1108
1109                // nodes present across views (dayGrid/timeGrid/list)
1110                const nDayTime = info.el.querySelector('.fc-event-time');
1110       // dayGrid/timeGrid
1111                const nListTime = info.el.querySelector('.fc-list-event-time');  // list
1112                // In some themes, dayGrid uses '.fc-time' alias as well:
1113                const nAltTime = info.el.querySelector('.fc-time');
1114
1115                // Build the desired time label
1116                const startText = hideStartTime ? '' : info.event.extendedProps.display_start_time; //fmt(info.event.start);
1117                
1118                // For end: if end is null, we won't show anything anyway
1119                const endText = hideEndTime ? '' : info.event.extendedProps.display_end_time; //fmt(info.event.end);
1120
1121                let label = '';
1122                if (startText && endText) {
1123                    label = startText + ' – ' + endText;
1124                } else if (startText && !endText) {
1125                    label = startText;                 // show only start
1126                } else if (!startText && endText) {
1127                    label = endText;                   // show only end
1128                } else {
1129                    label = '';                        // both hidden → no label
1130                }
1131
1132                // Apply the label (or hide node completely)
1133                const applyLabel = node => {
1134                    if (!node)
1135                        return;
1136                    if (label) {
1137                        node.textContent = label;
1138                        node.style.display = '';
1139                    } else {
1140                        node.textContent = '';
1141                        // node.style.display = 'none';
1142                    }
1143                };
1144
1145                applyLabel(nDayTime);
1146                applyLabel(nAltTime);
1147                applyLabel(nListTime);
1148
1149                // If you *also* globally hide times via a setting, keep your existing guard:
1150                if (em_front_event_object.hide_time_on_front_calendar == 1) {
1151                    if (nDayTime)
1152                        nDayTime.style.display = 'none';
1153                    if (nAltTime)
1154                        nAltTime.style.display = 'none';
1155                    if (nListTime)
1156                        nListTime.style.display = 'none';
1157                }
1158                // --- per-event time hiding/rewriting end---
1159
1160
1161                if (em_front_event_object.hide_time_on_front_calendar == 1) {
1162
1163                    $(info.el).find('.fc-event-time').hide();
1164                    $(info.el).find('.fc-list-event-time').hide();
1165
1166                }
1167                
1168                const isList = info.view && String(info.view.type).startsWith('list');
1169                if(isList)
1170                {
1171                    $(info.el).find('.fc-event-time').hide();
1172                }
1173                $(info.el).append(info.event.extendedProps.popup_html);
1174                // 1) FC variables (work across views/themes)
1175                const bg = info.event.extendedProps.bg_color || '';
1176                if (textColor) info.el.style.setProperty('--fc-event-text-color', textColor);
1177                if (bg) {
1178                  info.el.style.setProperty('--fc-event-bg-color', bg);
1179                  info.el.style.setProperty('--fc-event-border-color', bg);
1180                }
1181
1182                // 2) Also push inline color to common wrappers used by week view
1183                const mainNodes = info.el.querySelectorAll(
1184                  '.fc-event-main, .fc-event-main-frame, .fc-event-title, .fc-event-time, .fc-time'
1185                );
1186                mainNodes.forEach(n => { n.style.color = textColor; });
1187
1188                const anchor = info.el.matches('a') ? info.el : info.el.querySelector('a');
1189                if (anchor) anchor.style.color = textColor;
1190
1191                // 3) list view dot needs background
1192                const dot = info.el.querySelector('.fc-list-event-dot');
1193                if (dot && bg) { dot.style.backgroundColor = bg; dot.style.borderColor = bg; }
1194
1195            },
1196            eventMouseEnter: function (info) {
1197                let pop_block = info.el.querySelector('.ep_event_detail_popup');
1198                pop_block.style.display = 'block';
1199            },
1200            eventMouseLeave: function (info) {
1201                let pop_block = info.el.querySelector('.ep_event_detail_popup');
1202                pop_block.style.display = 'none';
1203            },
1204            eventClick: function (info) {
1205                var eventObj = info.event;
1206                if (eventObj.url) {
1207                    let open_event_in_new_tab = info.event.extendedProps.open_event_in_new_tab;
1208                    if (open_event_in_new_tab == 1) {
1209                        window.open(eventObj.url);
1210                        info.jsEvent.preventDefault();
1211                    }
1212                }
1213            },
1214        });
1215
1216        if (!document.getElementById('ep-fc-color-fix')) {
1217            const st = document.createElement('style');
1218            st.id = 'ep-fc-color-fix';
1219            st.textContent = `
1220              #ep_event_calendar .fc-event,
1221              #ep_event_calendar .fc-event .fc-event-main,
1222              #ep_event_calendar .fc-event .fc-event-title,
1223              #ep_event_calendar .fc-event .fc-event-time,
1224              #ep_event_calendar .fc-event .fc-time,
1225              #ep_event_calendar .fc-event a {
1226                color: var(--fc-event-text-color) !important;
1227              }
1228              #ep_event_calendar .fc-list-event-dot {
1229                background-color: var(--fc-event-bg-color) !important;
1230                border-color: var(--fc-event-bg-color) !important;
1231              }
1232            `;
1233            document.head.appendChild(st);
1234          }
1235
1236        calendar.render();
1237
1238        let calAreaWidht = $("#ep-events-content-container").innerWidth();
1239        if (calAreaWidht <= 720) {
1240            calendar.setOption('dayHeaderFormat', {weekday: 'short'});
1241        } else {
1242            calendar.setOption('dayHeaderFormat', {weekday: column_header_format});
1243        }
1244
1245        // custom class on the toolbal title
1246        let cal_title_class = 'ep-calendar-title-short';
1247
1248        let calendar_title_format = "MMMM, YYYY";
1249        if (typeof eventprime.global_settings.calendar_title_format !== 'undefined') {
1250            calendar_title_format = eventprime.global_settings.calendar_title_format;
1251        }
1252
1253        if (calendar_title_format.search('DD') > -1) {
1254            cal_title_class = 'ep-calendar-title-full';
1255        }
1256        $('#ep_event_calendar .fc-header-toolbar .fc-toolbar-title').addClass(cal_title_class);
1257    }
1258
1259    /*
1260     * Select Filter Box
1261     */
1262    $("#filter-date-from").datepicker({
1263        dateFormat: eventprime.datepicker_format,
1264        beforeShow: function () {
1265            let date_to = $('#filter-date-to').val();
1266            if (date_to) {
1267                $("#filter-date-from").datepicker("option", {
1268                    maxDate: date_to // set max date to to date
1269                });
1270            }
1271            $('#ui-datepicker-div').addClass('ep-ui-cal-wrap');
1272        },
1273    });
1274    $('.ep-trigger-date-from').click(function (e) {
1275        $("#filter-date-from").datepicker('show');
1276    });
1277    $("#filter-date-to").datepicker({
1278        dateFormat: eventprime.datepicker_format,
1279        beforeShow: function () {
1280            let date_from = $('#filter-date-from').val();
1281            if (date_from) {
1282                $("#filter-date-to").datepicker("option", {
1283                    minDate: date_from // set min date to from date
1284                });
1285            }
1286            $('#ui-datepicker-div').addClass('ep-ui-cal-wrap');
1287        },
1288    });
1289    $('.ep-trigger-date-to').click(function (e) {
1290        $("#filter-date-to").datepicker('show');
1291    });
1292
1293    $('#ep-filter-venues, #ep-filter-types').select2();
1294    $('#ep-filter-org').select2({
1295        placeholder: em_front_event_object.organizers,
1296        multiple: true,
1297        //templateSelection: set_organizers_query,
1298        allowClear: true
1299    });
1300    $('#ep-filter-performer').select2({
1301        placeholder: em_front_event_object.performers,
1302        multiple: true,
1303        //templateSelection: set_performers_query,
1304        allowClear: true
1305    });
1306
1307    // event filter list toggle
1308    if ($('#ep-event-view-selector').length > 0) {
1309        $('#ep-event-view-selector, .ep-box-dropdown-overlay').click(function () {
1310            $('.ep-event-views-content').slideToggle();
1311            $('#ep-event-view-selector').toggleClass('ep-box-dropdown-open');
1312        });
1313    }
1314
1315    //datepicker
1316    $('.epDatePicker').datepicker({
1317        changeYear: true,
1318        changeMonth: true,
1319        dateFormat: eventprime.datepicker_format,
1320        gotoCurrent: true,
1321        showButtonPanel: true,
1322    });
1323
1324    $("#ep_event_keyword_search").on('click', function () {
1325        $("#ep-search-filters").css("animation", "ep-searchfilters 1s forwards normal 1");
1326        $(".ep-search-filter-overlay").show();
1327        jQuery("#ep_event_find_events_btn").addClass("ep-z-index-3").removeClass("ep-z-index-1");
1328    });
1329
1330    $(".ep-search-filter-overlay").on('click', function () {
1331        if ($("#ep-search-filters").css("visibility") === "visible") {
1332            $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
1333        }
1334        $(".ep-search-filter-overlay").hide();
1335        jQuery("#ep_event_find_events_btn").addClass("ep-z-index-1").removeClass("ep-z-index-3");
1336    });
1337    $("#ep_filter_next_weekend, #ep_filter_next_week, #ep_filter_next_month, #ep_filter_online").on('click', function () {
1338        if ($("#ep-search-filters").css("visibility") === "visible") {
1339            $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
1340        }
1341        $(".ep-search-filter-overlay").hide();
1342    });
1343
1344
1345    /* let ep_mcontainer = document.querySelector( '#ep_events_front_views_staggered_grid' );
1346     if ( ep_mcontainer ) {
1347     let msnry;
1348     imagesLoaded( ep_mcontainer, function() {
1349     msnry = new Masonry( ep_mcontainer, {
1350     itemSelector: '#ep_events_front_views_staggered_grid .ep-event-card',
1351     });
1352     });
1353     } */
1354
1355    epCalViewWidhth();
1356
1357    ///  Event square card Image Setting start
1358
1359    var styleElement = jQuery("<style>");
1360
1361    // Set the text content to include dynamic variables in :root
1362    var styleContent = ":root {\n";
1363
1364    if (eventprime.global_settings.events_image_visibility_options) {
1365        styleContent += " --ep-imageCardObjectFit: " + eventprime.global_settings.events_image_visibility_options + ";\n";
1366    } else {
1367        styleContent += " --ep-imageCardObjectFit: " + 'cover' + ";\n";
1368    }
1369    if (eventprime.global_settings.events_image_height) {
1370        styleContent += "  --ep-imageCardHeight: " + eventprime.global_settings.events_image_height + "px" + ";\n";
1371    } else {
1372        styleContent += " --ep-imageCardHeight: " + '140' + "px" + ";\n";
1373    }
1374
1375    styleContent += "}\n";
1376    styleElement.text(styleContent);
1377
1378    //  Append the <style> element to the <head> of the document
1379    jQuery("head").append(styleElement);
1380
1381    //   Event square card Image Setting end
1382}
1383
1384
1385function ep_load_calendar_view_new(search_param = '') {
1386
1387    // set initial view
1388    let default_view = 'dayGridMonth';
1389    let calendar_views = {
1390        'month': 'dayGridMonth',
1391        'week': 'dayGridWeek',
1392        'day': 'dayGridDay',
1393        'listweek': 'listWeek',
1394    };
1395    if (eventprime.global_settings.default_cal_view) {
1396        if (em_front_event_object.view) {
1397            default_view = calendar_views[em_front_event_object.view];
1398        } else {
1399            default_view = calendar_views[eventprime.global_settings.default_cal_view];
1400        }
1401    }
1402
1403    // set initial date
1404    let cal_initial_date = new Date();
1405    if (eventprime.global_settings.enable_default_calendar_date == 1) {
1406        if (eventprime.global_settings.default_calendar_date && eventprime.global_settings.default_calendar_date !== '') {
1407            cal_initial_date = eventprime.global_settings.default_calendar_date;
1408        }
1409    }
1410
1411    // hide prev and next month rows
1412    let hide_calendar_rows = true;
1413    if (eventprime.global_settings.hide_calendar_rows == 1) {
1414        hide_calendar_rows = false;
1415    }
1416
1417    // set calendar right view options
1418    let right_views = [];
1419    if (eventprime.global_settings.front_switch_view_option) {
1420        if (eventprime.global_settings.front_switch_view_option.indexOf('month') > -1)
1421            right_views.push('dayGridMonth');
1422        if (eventprime.global_settings.front_switch_view_option.indexOf('week') > -1)
1423            right_views.push('dayGridWeek');
1424        if (eventprime.global_settings.front_switch_view_option.indexOf('day') > -1)
1425            right_views.push('dayGridDay');
1426        if (eventprime.global_settings.front_switch_view_option.indexOf('listweek') > -1)
1427            right_views.push('listWeek');
1428    }
1429    right_views = (right_views && right_views.length > 0) ? right_views.toString() : '';
1430
1431    // set column header format
1432    let calendar_column_header_format = eventprime.global_settings.calendar_column_header_format;
1433    let column_header_format = 'long';
1434    if (calendar_column_header_format == 'ddd') {
1435        column_header_format = 'short';
1436    }
1437
1438    // set day max events
1439    let day_max_events = eventprime.global_settings.show_max_event_on_calendar_date;
1440    if (!day_max_events)
1441        day_max_events = 2;
1442
1443    // 12/24-hour mode (single source of truth)
1444    const use24h = (eventprime.global_settings.time_format === 'HH:mm');
1445
1446    var calendarEl = document.getElementById('ep_event_calendar');
1447    var element = jQuery('#ep_hidden_args').val();
1448    var args = '';
1449    if (element) {
1450        args = element;
1451    } else if (em_front_event_object.event_attributes) {
1452        args = JSON.stringify(em_front_event_object.event_attributes);
1453    }
1454
1455    if (calendarEl) {
1456        var calendar = new FullCalendar.Calendar(calendarEl, {
1457            headerToolbar: {
1458                left: 'prevYear,prev,next,nextYear today',
1459                center: 'title',
1460                right: right_views
1461            },
1462            buttonText: {
1463                listWeek: em_front_event_object.list_week_btn_text,
1464            },
1465            initialDate: cal_initial_date,
1466            initialView: default_view,
1467            navLinks: true,
1468            dayMaxEvents: day_max_events,
1469            editable: false,
1470            timeZone: 'local',
1471
1472            // FC’s own formats (affects timeGrid/list/headers). Keep only one block.
1473            eventTimeFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
1474            slotLabelFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
1475
1476            height: "auto",
1477
1478            events: function (info, successCallback, failureCallback) {
1479                jQuery('.ep-event-loader').show();
1480                $.ajax({
1481                    url: eventprime.ajaxurl,
1482                    method: 'POST',
1483                    data: {
1484                        action: 'ep_get_calendar_event',
1485                        security: em_front_event_object._nonce,
1486                        start: info.startStr,
1487                        end: info.endStr,
1488                        args: args,
1489                        search_param: search_param
1490                    },
1491                    success: function (data) {
1492                        if (data && data.data) {
1493                            const pad = n => String(n).padStart(2, '0');
1494
1495                            const toISO = (dateStr, timeStr) => {
1496                                // timeStr like "11:45 PM" or "12:00 AM"
1497                                const d = new Date(`${dateStr} ${timeStr}`);
1498                                const y = d.getFullYear();
1499                                const m = pad(d.getMonth() + 1);
1500                                const da = pad(d.getDate());
1501                                const h = pad(d.getHours());
1502                                const mi = pad(d.getMinutes());
1503                                return `${y}-${m}-${da}T${h}:${mi}:00`;
1504                            };
1505
1506                            const addOneDayISODate = (dateStr) => {
1507                                const d = new Date(`${dateStr}T00:00:00`);
1508                                d.setDate(d.getDate() + 1);
1509                                return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
1510                            };
1511
1512                            const isDateOnly = (s) => typeof s === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(s);
1513
1514                            const normalized = data.data.map(e => {
1515                                // Map WP field to FullCalendar
1516                                e.allDay = (e.all_day === 1 || e.all_day === '1' || e.all_day === true);
1517
1518                                // convenience flags
1519                                e.hideStartTime = !e.start_time;
1520                                e.hideEndTime = !e.end_time;
1521
1522                                // If start/end are date-only but this is a timed event, attach the time
1523                                if (isDateOnly(e.start) && !e.allDay && e.start_time) {
1524                                    e.start = toISO(e.start, e.start_time);
1525                                }
1526                                if (isDateOnly(e.end) && !e.allDay && e.end_time) {
1527                                    e.end = toISO(e.end, e.end_time);
1528                                }
1529
1530                                // True all-day: make end exclusive (next day)
1531                                if (e.allDay) {
1532                                    if (!isDateOnly(e.start) && typeof e.event_start_date === 'string') {
1533                                        e.start = e.event_start_date; // YYYY-MM-DD
1534                                    }
1535                                    const baseEnd = isDateOnly(e.end) ? e.end
1536                                            : (typeof e.event_end_date === 'string' ? e.event_end_date : e.start);
1537                                    e.end = addOneDayISODate(baseEnd);
1538                                }
1539
1540                                return e;
1541                            });
1542
1543                            successCallback(normalized);
1544                        }
1545
1546                        setTimeout(function () {
1547                            jQuery('.ep-event-loader').hide();
1548                        }, 400);
1549                    },
1550                    error: function () {
1551                        failureCallback();
1552                    }
1553                });
1554            },
1555
1556            showNonCurrentDates: hide_calendar_rows,
1557            fixedWeekCount: hide_calendar_rows,
1558            nextDayThreshold: '00:00',
1559
1560            // Custom label for chips: use display_* times from PHP; avoid 00:00 on continuation days
1561            eventContent(arg) {
1562                const s = arg.event.extendedProps.display_start_time || '';
1563                const e = arg.event.extendedProps.display_end_time || '';
1564                let timeLabel = '';
1565
1566                if (arg.isStart && arg.isEnd && s && e)
1567                    timeLabel = `${s} – ${e}`;
1568                else if (arg.isStart && s)
1569                    timeLabel = s;
1570                else if (arg.isEnd && e)
1571                    timeLabel = e;
1572                else
1573                    timeLabel = ''; // middle day segment
1574
1575                const timeEl = document.createElement('div');
1576                timeEl.className = 'fc-event-time';
1577                timeEl.textContent = timeLabel;
1578
1579                const titleEl = document.createElement('div');
1580                titleEl.className = 'fc-event-title';
1581                titleEl.textContent = arg.event.title || '';
1582
1583                return {domNodes: [timeEl, titleEl]};
1584            },
1585
1586            titleFormat: {year: 'numeric', month: 'long', day: 'numeric'},
1587            dayHeaderFormat: {weekday: column_header_format},
1588
1589            eventDidMount: function (info) {
1590                // --- colors only ---
1591                let light_bg_color = '';
1592                if (info.event.extendedProps.hasOwnProperty('bg_color')) {
1593                    var epColorRgb = info.event.extendedProps.bg_color; // e.g., "rgb( 230,230,250 )"
1594                    var emColor_bg = epColorRgb.substring(epColorRgb.indexOf('(') + 1, epColorRgb.indexOf(')'));
1595                    info.el.style.backgroundColor = `rgba(${emColor_bg},1)`;
1596                    info.el.style.borderColor = `rgba(${emColor_bg},1)`;
1597                    light_bg_color = info.el.style.backgroundColor;
1598                }
1599
1600                var textColor = light_bg_color;
1601                if (info.event.extendedProps.hasOwnProperty('type_text_color')) {
1602                    textColor = info.event.extendedProps.type_text_color;
1603                }
1604                if (info.event.extendedProps.hasOwnProperty('event_text_color')) {
1605                    textColor = info.event.extendedProps.event_text_color;
1606                }
1607
1608                // apply text colors to known nodes (no time rewriting here)
1609                const selectors = [
1610                    '.fc-event-time',
1611                    '.fc-time',
1612                    '.fc-event-title',
1613                    '.fc-list-event-time',
1614                    '.fc-list-item-title',
1615                    '.fc-list-event-title',
1616                    '.fc-list-event-dot'
1617                ];
1618                selectors.forEach(q => {
1619                    const n = info.el.querySelector(q);
1620                    if (n && textColor)
1621                        n.style.color = textColor;
1622                });
1623
1624                // Global hide (if enabled)
1625                if (em_front_event_object.hide_time_on_front_calendar == 1) {
1626                    const a = info.el.querySelector('.fc-event-time');
1627                    const b = info.el.querySelector('.fc-list-event-time');
1628                    if (a)
1629                        a.style.display = 'none';
1630                    if (b)
1631                        b.style.display = 'none';
1632                }
1633
1634                // append popup
1635                $(info.el).append(info.event.extendedProps.popup_html);
1636            },
1637
1638            eventMouseEnter: function (info) {
1639                let pop_block = info.el.querySelector('.ep_event_detail_popup');
1640                if (pop_block)
1641                    pop_block.style.display = 'block';
1642            },
1643            eventMouseLeave: function (info) {
1644                let pop_block = info.el.querySelector('.ep_event_detail_popup');
1645                if (pop_block)
1646                    pop_block.style.display = 'none';
1647            },
1648            eventClick: function (info) {
1649                var eventObj = info.event;
1650                if (eventObj.url) {
1651                    let open_event_in_new_tab = info.event.extendedProps.open_event_in_new_tab;
1652                    if (open_event_in_new_tab == 1) {
1653                        window.open(eventObj.url);
1654                        info.jsEvent.preventDefault();
1655                    }
1656                }
1657            },
1658        });
1659
1660        calendar.render();
1661
1662        let calAreaWidht = $("#ep-events-content-container").innerWidth();
1663        if (calAreaWidht <= 720) {
1664            calendar.setOption('dayHeaderFormat', {weekday: 'short'});
1665        } else {
1666            calendar.setOption('dayHeaderFormat', {weekday: column_header_format});
1667        }
1668
1669        // custom class on the toolbar title
1670        let cal_title_class = 'ep-calendar-title-short';
1671        let calendar_title_format = "MMMM, YYYY";
1672        if (typeof eventprime.global_settings.calendar_title_format !== 'undefined') {
1673            calendar_title_format = eventprime.global_settings.calendar_title_format;
1674        }
1675        if (calendar_title_format.search('DD') > -1) {
1676            cal_title_class = 'ep-calendar-title-full';
1677        }
1678        $('#ep_event_calendar .fc-header-toolbar .fc-toolbar-title').addClass(cal_title_class);
1679    }
1680
1681    /*
1682     * Select Filter Box
1683     */
1684    $("#filter-date-from").datepicker({
1685        dateFormat: eventprime.datepicker_format,
1686        beforeShow: function () {
1687            let date_to = $('#filter-date-to').val();
1688            if (date_to) {
1689                $("#filter-date-from").datepicker("option", {maxDate: date_to});
1690            }
1691            $('#ui-datepicker-div').addClass('ep-ui-cal-wrap');
1692        },
1693    });
1694    $('.ep-trigger-date-from').click(function (e) {
1695        $("#filter-date-from").datepicker('show');
1696    });
1697    $("#filter-date-to").datepicker({
1698        dateFormat: eventprime.datepicker_format,
1699        beforeShow: function () {
1700            let date_from = $('#filter-date-from').val();
1701            if (date_from) {
1702                $("#filter-date-to").datepicker("option", {minDate: date_from});
1703            }
1704            $('#ui-datepicker-div').addClass('ep-ui-cal-wrap');
1705        },
1706    });
1707    $('.ep-trigger-date-to').click(function (e) {
1708        $("#filter-date-to").datepicker('show');
1709    });
1710
1711    $('#ep-filter-venues, #ep-filter-types').select2();
1712    $('#ep-filter-org').select2({
1713        placeholder: em_front_event_object.organizers,
1714        multiple: true,
1715        allowClear: true
1716    });
1717    $('#ep-filter-performer').select2({
1718        placeholder: em_front_event_object.performers,
1719        multiple: true,
1720        allowClear: true
1721    });
1722
1723    // event filter list toggle
1724    if ($('#ep-event-view-selector').length > 0) {
1725        $('#ep-event-view-selector, .ep-box-dropdown-overlay').click(function () {
1726            $('.ep-event-views-content').slideToggle();
1727            $('#ep-event-view-selector').toggleClass('ep-box-dropdown-open');
1728        });
1729    }
1730
1731    // datepicker
1732    $('.epDatePicker').datepicker({
1733        changeYear: true,
1734        changeMonth: true,
1735        dateFormat: eventprime.datepicker_format,
1736        gotoCurrent: true,
1737        showButtonPanel: true,
1738    });
1739
1740    $("#ep_event_keyword_search").on('click', function () {
1741        $("#ep-search-filters").css("animation", "ep-searchfilters 1s forwards normal 1");
1742        $(".ep-search-filter-overlay").show();
1743        jQuery("#ep_event_find_events_btn").addClass("ep-z-index-3").removeClass("ep-z-index-1");
1744    });
1745
1746    $(".ep-search-filter-overlay").on('click', function () {
1747        if ($("#ep-search-filters").css("visibility") === "visible") {
1748            $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
1749        }
1750        $(".ep-search-filter-overlay").hide();
1751        jQuery("#ep_event_find_events_btn").addClass("ep-z-index-1").removeClass("ep-z-index-3");
1752    });
1753    $("#ep_filter_next_weekend, #ep_filter_next_week, #ep_filter_next_month, #ep_filter_online").on('click', function () {
1754        if ($("#ep-search-filters").css("visibility") === "visible") {
1755            $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
1756        }
1757        $(".ep-search-filter-overlay").hide();
1758    });
1759
1760    epCalViewWidhth();
1761
1762    //  Event square card Image Setting start
1763    var styleElement = jQuery("<style>");
1764    var styleContent = ":root {\n";
1765    if (eventprime.global_settings.events_image_visibility_options) {
1766        styleContent += " --ep-imageCardObjectFit: " + eventprime.global_settings.events_image_visibility_options + ";\n";
1767    } else {
1768        styleContent += " --ep-imageCardObjectFit: cover;\n";
1769    }
1770    if (eventprime.global_settings.events_image_height) {
1771        styleContent += " --ep-imageCardHeight: " + eventprime.global_settings.events_image_height + "px;\n";
1772    } else {
1773        styleContent += " --ep-imageCardHeight: 140px;\n";
1774    }
1775    styleContent += "}\n";
1776    styleElement.text(styleContent);
1777    jQuery("head").append(styleElement);
1778    //  Event square card Image Setting end
1779}
1780
1781function ep_load_calendar_view_new2(search_param = '') {
1782
1783    // set initial view
1784    let default_view = 'dayGridMonth';
1785    let calendar_views = {
1786        'month': 'dayGridMonth',
1787        'week': 'dayGridWeek',
1788        'day': 'dayGridDay',
1789        'listweek': 'listWeek',
1790    };
1791    if (eventprime.global_settings.default_cal_view) {
1792        default_view = em_front_event_object.view
1793                ? calendar_views[em_front_event_object.view]
1794                : calendar_views[eventprime.global_settings.default_cal_view];
1795    }
1796
1797    // initial date
1798    let cal_initial_date = new Date();
1799    if (eventprime.global_settings.enable_default_calendar_date == 1 &&
1800            eventprime.global_settings.default_calendar_date) {
1801        cal_initial_date = eventprime.global_settings.default_calendar_date;
1802    }
1803
1804    // hide prev/next rows
1805    let hide_calendar_rows = !(eventprime.global_settings.hide_calendar_rows == 1);
1806
1807    // right views
1808    let right_views = [];
1809    if (eventprime.global_settings.front_switch_view_option) {
1810        if (eventprime.global_settings.front_switch_view_option.indexOf('month') > -1)
1811            right_views.push('dayGridMonth');
1812        if (eventprime.global_settings.front_switch_view_option.indexOf('week') > -1)
1813            right_views.push('dayGridWeek');
1814        if (eventprime.global_settings.front_switch_view_option.indexOf('day') > -1)
1815            right_views.push('dayGridDay');
1816        if (eventprime.global_settings.front_switch_view_option.indexOf('listweek') > -1)
1817            right_views.push('listWeek');
1818    }
1819    right_views = right_views.length ? right_views.toString() : '';
1820
1821    // header/day names
1822    let column_header_format = (eventprime.global_settings.calendar_column_header_format === 'ddd') ? 'short' : 'long';
1823
1824    // max events
1825    let day_max_events = eventprime.global_settings.show_max_event_on_calendar_date || 2;
1826
1827    // 12/24h mode
1828    const use24h = (eventprime.global_settings.time_format === 'HH:mm');
1829
1830    var calendarEl = document.getElementById('ep_event_calendar');
1831    var element = jQuery('#ep_hidden_args').val();
1832    var args = element ? element : (em_front_event_object.event_attributes ? JSON.stringify(em_front_event_object.event_attributes) : '');
1833
1834    if (!calendarEl)
1835        return;
1836
1837    var calendar = new FullCalendar.Calendar(calendarEl, {
1838        headerToolbar: {
1839            left: 'prevYear,prev,next,nextYear today',
1840            center: 'title',
1841            right: right_views
1842        },
1843        buttonText: {
1844            listWeek: em_front_event_object.list_week_btn_text,
1845        },
1846        initialDate: cal_initial_date,
1847        initialView: default_view,
1848        navLinks: true,
1849        dayMaxEvents: day_max_events,
1850        editable: false,
1851        timeZone: 'local',
1852
1853        // FullCalendar’s native formats (timeGrid/list/headers)
1854        eventTimeFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
1855        slotLabelFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
1856
1857        height: "auto",
1858
1859        events: function (info, successCallback, failureCallback) {
1860            jQuery('.ep-event-loader').show();
1861            $.ajax({
1862                url: eventprime.ajaxurl,
1863                method: 'POST',
1864                data: {
1865                    action: 'ep_get_calendar_event',
1866                    security: em_front_event_object._nonce,
1867                    start: info.startStr,
1868                    end: info.endStr,
1869                    args: args,
1870                    search_param: search_param
1871                },
1872                success: function (data) {
1873                    if (data && data.data) {
1874                        const pad = n => String(n).padStart(2, '0');
1875
1876                        const toISO = (dateStr, timeStr) => {
1877                            const d = new Date(`${dateStr} ${timeStr}`);
1878                            const y = d.getFullYear();
1879                            const m = pad(d.getMonth() + 1);
1880                            const da = pad(d.getDate());
1881                            const h = pad(d.getHours());
1882                            const mi = pad(d.getMinutes());
1883                            return `${y}-${m}-${da}T${h}:${mi}:00`;
1884                        };
1885
1886                        const addOneDayISODate = (dateStr) => {
1887                            const d = new Date(`${dateStr}T00:00:00`);
1888                            d.setDate(d.getDate() + 1);
1889                            return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
1890                        };
1891
1892                        const isDateOnly = (s) => typeof s === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(s);
1893
1894                        const normalized = data.data.map(e => {
1895                            e.allDay = (e.all_day === 1 || e.all_day === '1' || e.all_day === true);
1896
1897                            // flags for rendering
1898                            e.hideStartTime = !e.start_time;
1899                            e.hideEndTime = !e.end_time;
1900
1901                            // attach times for timed date-only events
1902                            if (isDateOnly(e.start) && !e.allDay && e.start_time)
1903                                e.start = toISO(e.start, e.start_time);
1904                            if (isDateOnly(e.end) && !e.allDay && e.end_time)
1905                                e.end = toISO(e.end, e.end_time);
1906
1907                            // all-day → exclusive end
1908                            if (e.allDay) {
1909                                if (!isDateOnly(e.start) && typeof e.event_start_date === 'string') {
1910                                    e.start = e.event_start_date;
1911                                }
1912                                const baseEnd = isDateOnly(e.end) ? e.end
1913                                        : (typeof e.event_end_date === 'string' ? e.event_end_date : e.start);
1914                                e.end = addOneDayISODate(baseEnd);
1915                            }
1916
1917                            return e;
1918                        });
1919
1920                        successCallback(normalized);
1921                    }
1922
1923                    setTimeout(function () {
1924                        jQuery('.ep-event-loader').hide();
1925                    }, 400);
1926                },
1927                error: function () {
1928                    failureCallback();
1929                }
1930            });
1931        },
1932
1933        showNonCurrentDates: hide_calendar_rows,
1934        fixedWeekCount: hide_calendar_rows,
1935        nextDayThreshold: '00:00',
1936
1937        // Custom label for dayGrid/timeGrid chips
1938        // For list view we'll not inject our own .fc-event-time here to avoid duplicates
1939        eventContent(arg) {
1940            const isList = arg.view && String(arg.view.type).indexOf('list') === 0;
1941            const titleEl = document.createElement('div');
1942            titleEl.className = 'fc-event-title';
1943            titleEl.textContent = arg.event.title || '';
1944
1945            if (isList) {
1946                // Let list view keep its own time column; we'll override it in eventDidMount.
1947                return {domNodes: [titleEl]};
1948            }
1949
1950            // dayGrid/timeGrid custom time label
1951            const s = arg.event.extendedProps.display_start_time || '';
1952            const e = arg.event.extendedProps.display_end_time || '';
1953            let timeLabel = '';
1954            if (arg.isStart && arg.isEnd && s && e)
1955                timeLabel = `${s} – ${e}`;
1956            else if (arg.isStart && s)
1957                timeLabel = s;
1958            else if (arg.isEnd && e)
1959                timeLabel = e;
1960
1961            const timeEl = document.createElement('div');
1962            timeEl.className = 'fc-event-time';
1963            timeEl.textContent = timeLabel;
1964
1965            return {domNodes: [timeEl, titleEl]};
1966        },
1967
1968        titleFormat: {year: 'numeric', month: 'long', day: 'numeric'},
1969        dayHeaderFormat: {weekday: column_header_format},
1970
1971        eventDidMount: function (info) {
1972            // --- colors ---
1973            let light_bg_color = '';
1974            if (info.event.extendedProps.hasOwnProperty('bg_color')) {
1975                var epColorRgb = info.event.extendedProps.bg_color; // "rgb( r,g,b )"
1976                var emColor_bg = epColorRgb.substring(epColorRgb.indexOf('(') + 1, epColorRgb.indexOf(')'));
1977                info.el.style.backgroundColor = `rgba(${emColor_bg},1)`;
1978                info.el.style.borderColor = `rgba(${emColor_bg},1)`;
1979                light_bg_color = info.el.style.backgroundColor;
1980            }
1981
1982            var textColor = light_bg_color;
1983            if (info.event.extendedProps.type_text_color)
1984                textColor = info.event.extendedProps.type_text_color;
1985            if (info.event.extendedProps.event_text_color)
1986                textColor = info.event.extendedProps.event_text_color;
1987
1988            // apply text colors
1989            ['.fc-event-time', '.fc-time', '.fc-event-title', '.fc-list-event-time', '.fc-list-item-title', '.fc-list-event-title', '.fc-list-event-dot']
1990                    .forEach(sel => {
1991                        const n = info.el.querySelector(sel);
1992                        if (n && textColor)
1993                            n.style.color = textColor;
1994                    });
1995
1996            // Global hide
1997            if (em_front_event_object.hide_time_on_front_calendar == 1) {
1998                const a = info.el.querySelector('.fc-event-time');
1999                const b = info.el.querySelector('.fc-list-event-time');
2000                if (a)
2001                    a.style.display = 'none';
2002                if (b)
2003                    b.style.display = 'none';
2004            }
2005
2006            // ⬇️ List view: override the time column label to avoid "00:00" and enforce 12h/24h preference
2007            const isList = info.view && String(info.view.type).indexOf('list') === 0;
2008            if (isList && em_front_event_object.hide_time_on_front_calendar != 1) {
2009                const nListTime = info.el.querySelector('.fc-list-event-time');
2010                if (nListTime) {
2011                    const s = info.event.extendedProps.display_start_time || '';
2012                    const e = info.event.extendedProps.display_end_time || '';
2013                    let label = '';
2014                    if (info.isStart && info.isEnd && s && e)
2015                        label = `${s} – ${e}`;
2016                    else if (info.isStart && s)
2017                        label = s;
2018                    else if (info.isEnd && e)
2019                        label = e;
2020                    else
2021                        label = ''; // middle segments → blank
2022                    nListTime.textContent = label;
2023                }
2024            }
2025
2026            // append popup
2027            $(info.el).append(info.event.extendedProps.popup_html);
2028        },
2029
2030        eventMouseEnter: function (info) {
2031            let pop_block = info.el.querySelector('.ep_event_detail_popup');
2032            if (pop_block)
2033                pop_block.style.display = 'block';
2034        },
2035        eventMouseLeave: function (info) {
2036            let pop_block = info.el.querySelector('.ep_event_detail_popup');
2037            if (pop_block)
2038                pop_block.style.display = 'none';
2039        },
2040        eventClick: function (info) {
2041            var eventObj = info.event;
2042            if (eventObj.url) {
2043                let open_event_in_new_tab = info.event.extendedProps.open_event_in_new_tab;
2044                if (open_event_in_new_tab == 1) {
2045                    window.open(eventObj.url);
2046                    info.jsEvent.preventDefault();
2047                }
2048            }
2049        },
2050    });
2051
2052    calendar.render();
2053
2054    let calAreaWidht = $("#ep-events-content-container").innerWidth();
2055    if (calAreaWidht <= 720) {
2056        calendar.setOption('dayHeaderFormat', {weekday: 'short'});
2057    } else {
2058        calendar.setOption('dayHeaderFormat', {weekday: column_header_format});
2059    }
2060
2061    // toolbar title class
2062    let cal_title_class = 'ep-calendar-title-short';
2063    let calendar_title_format = "MMMM, YYYY";
2064    if (typeof eventprime.global_settings.calendar_title_format !== 'undefined') {
2065        calendar_title_format = eventprime.global_settings.calendar_title_format;
2066    }
2067    if (calendar_title_format.search('DD') > -1) {
2068        cal_title_class = 'ep-calendar-title-full';
2069    }
2070    $('#ep_event_calendar .fc-header-toolbar .fc-toolbar-title').addClass(cal_title_class);
2071
2072    /* datepickers & filters below unchanged ... */
2073
2074    $("#filter-date-from").datepicker({
2075        dateFormat: eventprime.datepicker_format,
2076        beforeShow: function () {
2077            let date_to = $('#filter-date-to').val();
2078            if (date_to)
2079                $("#filter-date-from").datepicker("option", {maxDate: date_to});
2080            $('#ui-datepicker-div').addClass('ep-ui-cal-wrap');
2081        },
2082    });
2083    $('.ep-trigger-date-from').click(function () {
2084        $("#filter-date-from").datepicker('show');
2085    });
2086
2087    $("#filter-date-to").datepicker({
2088        dateFormat: eventprime.datepicker_format,
2089        beforeShow: function () {
2090            let date_from = $('#filter-date-from').val();
2091            if (date_from)
2092                $("#filter-date-to").datepicker("option", {minDate: date_from});
2093            $('#ui-datepicker-div').addClass('ep-ui-cal-wrap');
2094        },
2095    });
2096    $('.ep-trigger-date-to').click(function () {
2097        $("#filter-date-to").datepicker('show');
2098    });
2099
2100    $('#ep-filter-venues, #ep-filter-types').select2();
2101    $('#ep-filter-org').select2({
2102        placeholder: em_front_event_object.organizers,
2103        multiple: true,
2104        allowClear: true
2105    });
2106    $('#ep-filter-performer').select2({
2107        placeholder: em_front_event_object.performers,
2108        multiple: true,
2109        allowClear: true
2110    });
2111
2112    if ($('#ep-event-view-selector').length > 0) {
2113        $('#ep-event-view-selector, .ep-box-dropdown-overlay').click(function () {
2114            $('.ep-event-views-content').slideToggle();
2115            $('#ep-event-view-selector').toggleClass('ep-box-dropdown-open');
2116        });
2117    }
2118
2119    $('.epDatePicker').datepicker({
2120        changeYear: true,
2121        changeMonth: true,
2122        dateFormat: eventprime.datepicker_format,
2123        gotoCurrent: true,
2124        showButtonPanel: true,
2125    });
2126
2127    $("#ep_event_keyword_search").on('click', function () {
2128        $("#ep-search-filters").css("animation", "ep-searchfilters 1s forwards normal 1");
2129        $(".ep-search-filter-overlay").show();
2130        jQuery("#ep_event_find_events_btn").addClass("ep-z-index-3").removeClass("ep-z-index-1");
2131    });
2132
2133    $(".ep-search-filter-overlay").on('click', function () {
2134        if ($("#ep-search-filters").css("visibility") === "visible") {
2135            $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
2136        }
2137        $(".ep-search-filter-overlay").hide();
2138        jQuery("#ep_event_find_events_btn").addClass("ep-z-index-1").removeClass("ep-z-index-3");
2139    });
2140    $("#ep_filter_next_weekend, #ep_filter_next_week, #ep_filter_next_month, #ep_filter_online").on('click', function () {
2141        if ($("#ep-search-filters").css("visibility") === "visible") {
2142            $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
2143        }
2144        $(".ep-search-filter-overlay").hide();
2145    });
2146
2147    epCalViewWidhth();
2148
2149    // Image CSS vars
2150    var styleElement = jQuery("<style>");
2151    var styleContent = ":root {\n";
2152    styleContent += " --ep-imageCardObjectFit: " + (eventprime.global_settings.events_image_visibility_options || 'cover') + ";\n";
2153    styleContent += " --ep-imageCardHeight: " + (eventprime.global_settings.events_image_height ? eventprime.global_settings.events_image_height + "px" : "140px") + ";\n";
2154    styleContent += "}\n";
2155    styleElement.text(styleContent);
2156    jQuery("head").append(styleElement);
2157}
2158
2159function ep_load_calendar_view_new3(search_param = '') {
2160    let default_view = 'dayGridMonth';
2161    const calendar_views = {
2162        'month': 'dayGridMonth',
2163        'week': 'dayGridWeek',
2164        'day': 'dayGridDay',
2165        'listweek': 'listWeek',
2166    };
2167
2168    if (eventprime.global_settings.default_cal_view) {
2169        default_view = em_front_event_object.view
2170                ? calendar_views[em_front_event_object.view]
2171                : calendar_views[eventprime.global_settings.default_cal_view];
2172    }
2173
2174    // Initial date
2175    let cal_initial_date = new Date();
2176    if (eventprime.global_settings.enable_default_calendar_date == 1 &&
2177            eventprime.global_settings.default_calendar_date) {
2178        cal_initial_date = eventprime.global_settings.default_calendar_date;
2179    }
2180
2181    // Hide extra weeks
2182    const hide_calendar_rows = !(eventprime.global_settings.hide_calendar_rows == 1);
2183
2184    // Toolbar buttons
2185    let right_views = [];
2186    if (eventprime.global_settings.front_switch_view_option) {
2187        const opt = eventprime.global_settings.front_switch_view_option;
2188        if (opt.includes('month'))
2189            right_views.push('dayGridMonth');
2190        if (opt.includes('week'))
2191            right_views.push('dayGridWeek');
2192        if (opt.includes('day'))
2193            right_views.push('dayGridDay');
2194        if (opt.includes('listweek'))
2195            right_views.push('listWeek');
2196    }
2197    right_views = right_views.join(',');
2198
2199    // Date header format
2200    const column_header_format =
2201            (eventprime.global_settings.calendar_column_header_format === 'ddd') ? 'short' : 'long';
2202
2203    // Max events per day
2204    const day_max_events = eventprime.global_settings.show_max_event_on_calendar_date || 2;
2205
2206    // Time format (12h / 24h)
2207    const use24h = (eventprime.global_settings.time_format === 'HH:mm');
2208
2209    const calendarEl = document.getElementById('ep_event_calendar');
2210    const args = jQuery('#ep_hidden_args').val()
2211            || (em_front_event_object.event_attributes
2212                    ? JSON.stringify(em_front_event_object.event_attributes)
2213                    : '');
2214
2215    if (!calendarEl)
2216        return;
2217
2218    const calendar = new FullCalendar.Calendar(calendarEl, {
2219        headerToolbar: {
2220            left: 'prevYear,prev,next,nextYear today',
2221            center: 'title',
2222            right: right_views
2223        },
2224        buttonText: {
2225            listWeek: em_front_event_object.list_week_btn_text,
2226        },
2227        initialDate: cal_initial_date,
2228        initialView: default_view,
2229        navLinks: true,
2230        dayMaxEvents: day_max_events,
2231        editable: false,
2232        timeZone: 'local',
2233
2234        // Native formats for timeGrid/list
2235        eventTimeFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
2236        slotLabelFormat: {hour: '2-digit', minute: '2-digit', hour12: !use24h},
2237
2238        height: "auto",
2239
2240        events: function (info, successCallback, failureCallback) {
2241            jQuery('.ep-event-loader').show();
2242            $.ajax({
2243                url: eventprime.ajaxurl,
2244                method: 'POST',
2245                data: {
2246                    action: 'ep_get_calendar_event',
2247                    security: em_front_event_object._nonce,
2248                    start: info.startStr,
2249                    end: info.endStr,
2250                    args: args,
2251                    search_param: search_param
2252                },
2253                success: function (data) {
2254                    if (data && data.data) {
2255                        const pad = n => String(n).padStart(2, '0');
2256                        const toISO = (dateStr, timeStr) => {
2257                            const d = new Date(`${dateStr} ${timeStr}`);
2258                            return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:00`;
2259                        };
2260                        const addOneDayISODate = (dateStr) => {
2261                            const d = new Date(`${dateStr}T00:00:00`);
2262                            d.setDate(d.getDate() + 1);
2263                            return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
2264                        };
2265                        const isDateOnly = (s) => /^\d{4}-\d{2}-\d{2}$/.test(s);
2266
2267                        const normalized = data.data.map(e => {
2268                            e.allDay = (e.all_day === 1 || e.all_day === '1' || e.all_day === true);
2269                            e.hideStartTime = !e.start_time;
2270                            e.hideEndTime = !e.end_time;
2271
2272                            if (isDateOnly(e.start) && !e.allDay && e.start_time)
2273                                e.start = toISO(e.start, e.start_time);
2274                            if (isDateOnly(e.end) && !e.allDay && e.end_time)
2275                                e.end = toISO(e.end, e.end_time);
2276
2277                            if (e.allDay) {
2278                                if (!isDateOnly(e.start) && typeof e.event_start_date === 'string') {
2279                                    e.start = e.event_start_date;
2280                                }
2281                                const baseEnd = isDateOnly(e.end)
2282                                        ? e.end
2283                                        : (typeof e.event_end_date === 'string'
2284                                                ? e.event_end_date
2285                                                : e.start);
2286                                e.end = addOneDayISODate(baseEnd);
2287                            }
2288                            return e;
2289                        });
2290
2291                        successCallback(normalized);
2292                    }
2293                    setTimeout(() => jQuery('.ep-event-loader').hide(), 400);
2294                },
2295                error: failureCallback
2296            });
2297        },
2298
2299        showNonCurrentDates: hide_calendar_rows,
2300        fixedWeekCount: hide_calendar_rows,
2301        nextDayThreshold: '00:00',
2302
2303        // ✅ Custom rendering for all non-list views
2304        eventContent(arg) {
2305            const isList = arg.view && String(arg.view.type).startsWith('list');
2306            const titleEl = document.createElement('div');
2307            titleEl.className = 'fc-event-title';
2308            titleEl.textContent = arg.event.title || '';
2309
2310            if (isList)
2311                return {domNodes: [titleEl]}; // skip in list; handled in eventDidMount
2312
2313            const s = arg.event.extendedProps.display_start_time || '';
2314            const e = arg.event.extendedProps.display_end_time || '';
2315            let timeLabel = '';
2316            if (arg.isStart && arg.isEnd && s && e)
2317                timeLabel = `${s} – ${e}`;
2318            else if (arg.isStart && s)
2319                timeLabel = s;
2320            else if (arg.isEnd && e)
2321                timeLabel = e;
2322
2323            const timeEl = document.createElement('div');
2324            timeEl.className = 'fc-event-time';
2325            timeEl.textContent = timeLabel;
2326
2327            return {domNodes: [timeEl, titleEl]};
2328        },
2329
2330        titleFormat: {year: 'numeric', month: 'long', day: 'numeric'},
2331        dayHeaderFormat: {weekday: column_header_format},
2332
2333        // ✅ Apply colors, fix list view times, and attach popup
2334        eventDidMount: function (info) {
2335            let light_bg_color = '';
2336            if (info.event.extendedProps.bg_color) {
2337                const rgb = info.event.extendedProps.bg_color;
2338                const color = rgb.substring(rgb.indexOf('(') + 1, rgb.indexOf(')'));
2339                info.el.style.backgroundColor = `rgba(${color},1)`;
2340                info.el.style.borderColor = `rgba(${color},1)`;
2341                light_bg_color = info.el.style.backgroundColor;
2342            }
2343
2344            let textColor = light_bg_color;
2345            if (info.event.extendedProps.type_text_color)
2346                textColor = info.event.extendedProps.type_text_color;
2347            if (info.event.extendedProps.event_text_color)
2348                textColor = info.event.extendedProps.event_text_color;
2349
2350            // Apply colors to all text
2351            [
2352                '.fc-event-time',
2353                '.fc-time',
2354                '.fc-event-title',
2355                '.fc-list-event-time',
2356                '.fc-list-item-title',
2357                '.fc-list-event-title',
2358                '.fc-list-event-dot'
2359            ].forEach(sel => {
2360                const el = info.el.querySelector(sel);
2361                if (el && textColor)
2362                    el.style.color = textColor;
2363            });
2364
2365            // Hide times globally if set
2366            if (em_front_event_object.hide_time_on_front_calendar == 1) {
2367                info.el.querySelectorAll('.fc-event-time, .fc-list-event-time').forEach(n => n.style.display = 'none');
2368            }
2369
2370            // ✅ Fix list view label
2371            const isList = info.view && String(info.view.type).startsWith('list');
2372            if (isList && em_front_event_object.hide_time_on_front_calendar != 1) {
2373                const timeNode = info.el.querySelector('.fc-list-event-time');
2374                if (timeNode) {
2375                    const s = info.event.extendedProps.display_start_time || '';
2376                    const e = info.event.extendedProps.display_end_time || '';
2377                    let label = '';
2378                    if (info.isStart && info.isEnd && s && e)
2379                        label = `${s} – ${e}`;
2380                    else if (info.isStart && s)
2381                        label = s;
2382                    else if (info.isEnd && e)
2383                        label = e;
2384                    timeNode.textContent = label;
2385                }
2386            }
2387
2388            // Append popup
2389            $(info.el).append(info.event.extendedProps.popup_html);
2390        },
2391
2392        // Popup behaviors
2393        eventMouseEnter(info) {
2394            const pop = info.el.querySelector('.ep_event_detail_popup');
2395            if (pop)
2396                pop.style.display = 'block';
2397        },
2398        eventMouseLeave(info) {
2399            const pop = info.el.querySelector('.ep_event_detail_popup');
2400            if (pop)
2401                pop.style.display = 'none';
2402        },
2403        eventClick(info) {
2404            if (info.event.url) {
2405                if (info.event.extendedProps.open_event_in_new_tab == 1) {
2406                    window.open(info.event.url);
2407                    info.jsEvent.preventDefault();
2408                }
2409            }
2410        },
2411    });
2412
2413    calendar.render();
2414
2415    // Responsive header
2416    const width = $("#ep-events-content-container").innerWidth();
2417    calendar.setOption('dayHeaderFormat', {weekday: width <= 720 ? 'short' : column_header_format});
2418
2419    // Calendar title styling
2420    const cal_title_class = (eventprime.global_settings.calendar_title_format || '').includes('DD')
2421            ? 'ep-calendar-title-full'
2422            : 'ep-calendar-title-short';
2423    $('#ep_event_calendar .fc-header-toolbar .fc-toolbar-title').addClass(cal_title_class);
2424
2425    // (Keep your datepicker/filter code unchanged below)
2426}
2427
2428function ep_load_calendar_view_old(search_param='')
2429{
2430    
2431        // set initial view
2432        let default_view = 'dayGridMonth';
2433        let calendar_views = {
2434            'month':    'dayGridMonth',
2435            'week':     'dayGridWeek',
2436            'day':      'dayGridDay',
2437            'listweek': 'listWeek',
2438        };
2439        if( eventprime.global_settings.default_cal_view ) {
2440            if( em_front_event_object.view ) {
2441                default_view = calendar_views[em_front_event_object.view];    
2442            } else{
2443                default_view = calendar_views[eventprime.global_settings.default_cal_view];
2444            }
2445        }
2446        // set initial date
2447        let cal_initial_date = new Date();
2448        if( eventprime.global_settings.enable_default_calendar_date == 1 ) {
2449            if( eventprime.global_settings.default_calendar_date && eventprime.global_settings.default_calendar_date != '' ) {
2450                cal_initial_date = eventprime.global_settings.default_calendar_date;
2451            }
2452        }
2453        // hide prev and next month rows
2454        let hide_calendar_rows = true;
2455        if(eventprime.global_settings.hide_calendar_rows == 1){
2456            hide_calendar_rows = false;
2457        }
2458        // set calendar right view options
2459        let right_views = [];
2460        if( eventprime.global_settings.front_switch_view_option ) {
2461            if( eventprime.global_settings.front_switch_view_option.indexOf( 'month' ) > -1 ) {
2462                right_views.push( 'dayGridMonth' );
2463            }
2464            if( eventprime.global_settings.front_switch_view_option.indexOf( 'week' ) > -1 ) {
2465                right_views.push( 'dayGridWeek' );
2466            }
2467            if( eventprime.global_settings.front_switch_view_option.indexOf( 'day' ) > -1 ) {
2468                right_views.push( 'dayGridDay' );
2469            }
2470            if( eventprime.global_settings.front_switch_view_option.indexOf( 'listweek' ) > -1 ) {
2471                right_views.push( 'listWeek' );
2472            }
2473        }
2474        if( right_views && right_views.length > 0 ) {
2475            right_views = right_views.toString();
2476        } else{
2477            right_views = '';
2478        }
2479        // set column header format
2480        let calendar_column_header_format = eventprime.global_settings.calendar_column_header_format;
2481        let column_header_format = 'long';
2482        if( calendar_column_header_format == 'ddd' ) {
2483            column_header_format = 'short';
2484        }
2485        // set day max events
2486        let day_max_events = eventprime.global_settings.show_max_event_on_calendar_date;
2487        if( !day_max_events ) {
2488            day_max_events = 2;
2489        }
2490        // set 12 and 24 hours
2491        let hour12 = true;
2492        if( eventprime.global_settings.time_format == 'HH:mm' ){
2493            hour12 = false;
2494        }
2495        var calendarEl = document.getElementById( 'ep_event_calendar' );
2496        var element = jQuery('#ep_hidden_args' ).val();
2497        // if (element !== null) {
2498        if (element) {
2499            var args = element;
2500            // Do something with args
2501        } else if ( em_front_event_object.event_attributes ) {
2502            var args = JSON.stringify(em_front_event_object.event_attributes); 
2503        } else {
2504            var args = '';
2505        }
2506        
2507        if( calendarEl ) {
2508            //console.log(eventprime.timezone)
2509            var calendar = new FullCalendar.Calendar( calendarEl, {
2510                headerToolbar: {
2511                    left: 'prevYear,prev,next,nextYear today',
2512                    center: 'title',
2513                    right: right_views
2514                },
2515                // views: {
2516                //     listWeek: { buttonText: 'Agenda' }
2517                // },
2518                buttonText: {
2519                    listWeek: em_front_event_object.list_week_btn_text,  
2520                },
2521                initialDate: cal_initial_date,
2522                initialView: default_view,
2523                navLinks: true, // can click day/week names to navigate views
2524                dayMaxEvents: day_max_events, // allow "more" link when too many events
2525                editable: false,
2526                timeZone:eventprime.timezone,
2527                height: "auto",
2528                events: function(info, successCallback, failureCallback) {
2529        // Calculate the start and end dates of the current month
2530        jQuery('.ep-event-loader').show();
2531        $.ajax({
2532            url: eventprime.ajaxurl, // Replace with your events API endpoint
2533            method: 'POST',
2534            data: {
2535                action:'ep_get_calendar_event',
2536                security  : em_front_event_object._nonce,
2537                start: info.startStr,
2538                end: info.endStr,
2539                args: args,
2540                search_param:search_param
2541                        
2542            },
2543            success: function(data) {
2544                
2545                
2546                // clearTimeout(hideLoaderTimeout);
2547                /*
2548                if(data.data)
2549                {
2550                    successCallback(data.data);
2551                }
2552                
2553                /*
2554 * ⚠️ Important Note:
2555 * FullCalendar treats events differently depending on whether the "end" field
2556 * has a time or is just a date string. 
2557 *
2558 * Problem:
2559 * - For timed events, if "end" is passed as a plain date (YYYY-MM-DD) without time,
2560 *   FullCalendar interprets it as an all-day or exclusive end, causing the event 
2561 *   to appear on the wrong day (spilling into two days).
2562 *
2563 * Fix:
2564 * - For timed events, always convert start/end into full ISO datetime strings.
2565 * - For true all-day events, keep date-only but make the "end" exclusive 
2566 *   (next day at 00:00) as per FullCalendar’s requirement.
2567 *
2568 * Example:
2569 *   Bad → start: "2025-08-25 23:40", end: "2025-08-25"
2570 *   Good → start: "2025-08-25T23:40:00", end: "2025-08-25T23:45:00"
2571 *
2572 * This normalization ensures one-day events are rendered correctly 
2573 * and prevents them from showing on multiple days.
2574 */
2575               
2576               
2577                if (data.data) {
2578                    const pad = n => String(n).padStart(2, '0');
2579
2580                    const toISO = (dateStr, timeStr) => {
2581                        // timeStr like "11:45 PM" or "12:00 AM"
2582                        const d = new Date(`${dateStr} ${timeStr}`);
2583                        const y = d.getFullYear();
2584                        const m = pad(d.getMonth() + 1);
2585                        const da = pad(d.getDate());
2586                        const h = pad(d.getHours());
2587                        const mi = pad(d.getMinutes());
2588                        return `${y}-${m}-${da}T${h}:${mi}:00`;
2589                    };
2590
2591                    const addOneDayISODate = (dateStr) => {
2592                        const d = new Date(`${dateStr}T00:00:00`);
2593                        d.setDate(d.getDate() + 1);
2594                        return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}`;
2595                    };
2596
2597                    const isDateOnly = (s) => typeof s === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(s);
2598
2599                    const normalized = data.data.map(e => {
2600                        // Map WP field to FullCalendar
2601                        e.allDay = (e.all_day === 1 || e.all_day === '1' || e.all_day === true);
2602                        e.hideStartTime = !e.start_time; // true if start_time is blank
2603                        e.hideEndTime   = !e.end_time;   // true if end_time is blank
2604                        // START: add time if missing for timed events
2605                        if (isDateOnly(e.start) && !e.allDay && e.start_time) {
2606                            e.start = toISO(e.start, e.start_time);
2607                        }
2608                        // END: add time if missing for timed events
2609                        if (isDateOnly(e.end) && !e.allDay && e.end_time) {
2610                            e.end = toISO(e.end, e.end_time);
2611                        }
2612
2613                        // For true all-day events, make end exclusive (next day)
2614                        if (e.allDay) {
2615                            // Ensure start is date-only for all-day
2616                            if (!isDateOnly(e.start) && typeof e.event_start_date === 'string') {
2617                                e.start = e.event_start_date; // YYYY-MM-DD
2618                            }
2619                            // Ensure end is exclusive date-only
2620                            const baseEnd = isDateOnly(e.end) ? e.end
2621                                          : (typeof e.event_end_date === 'string' ? e.event_end_date : e.start);
2622                            e.end = addOneDayISODate(baseEnd);
2623                        }
2624
2625                        return e;
2626                    });
2627
2628                    successCallback(normalized);
2629                }
2630
2631                setTimeout(function() {
2632                        jQuery('.ep-event-loader').hide();
2633                    }, 400);
2634                // jQuery('.ep-event-loader').hide();
2635            },
2636            error: function() {
2637                failureCallback();
2638            }
2639        });
2640    },
2641                
2642                showNonCurrentDates: hide_calendar_rows,
2643                fixedWeekCount: hide_calendar_rows,
2644                nextDayThreshold: '00:00',
2645                eventTimeFormat: {
2646                    hour: '2-digit',
2647                    minute: '2-digit',
2648                    hour12: hour12,
2649                    meridiem: 'short'
2650                },
2651                firstDay: em_front_event_object.start_of_week,
2652                locale: em_front_event_object.local,
2653                titleFormat: { year: 'numeric', month: 'long', day: 'numeric' },
2654                dayHeaderFormat: { weekday: column_header_format },
2655                eventDidMount: function(info) {
2656                    let light_bg_color = '';
2657                    if (info.event.extendedProps.hasOwnProperty('bg_color')) {
2658                        var epColorRgb = info.event.extendedProps.bg_color;
2659                        var avoid = "rgb";
2660                        var eprgbRemover = epColorRgb.replace(avoid, '');
2661                        var emColor_bg = eprgbRemover.substring(eprgbRemover.indexOf('(') + 1, eprgbRemover.indexOf(')'))
2662                        info.el.style.backgroundColor =  `rgba(${emColor_bg},1)`;
2663                        light_bg_color = info.el.style.backgroundColor;
2664                        info.el.style.borderColor =  `rgba(${emColor_bg},1)`;
2665                    }
2666                    var textColor = light_bg_color;
2667                    if ( info.event.extendedProps.hasOwnProperty( 'type_text_color' ) ) {
2668                        textColor = info.event.extendedProps.type_text_color;
2669                    }
2670                    if ( info.event.extendedProps.hasOwnProperty( 'event_text_color' ) ) {
2671                        textColor = info.event.extendedProps.event_text_color;
2672                    }
2673                    
2674                    var fc_time = info.el.querySelector('.fc-event-time'); 
2675                    if(fc_time){
2676                        fc_time.style.color = textColor;
2677                        if( em_front_event_object.hide_time_on_front_calendar == 1 ) {
2678                            fc_time.textContent = '';
2679                            fc_time.style.color = '';
2680                        }
2681                    }
2682                    
2683                    if(textColor){
2684                        var fc_time = info.el.querySelector('.fc-time');
2685                        if(fc_time){
2686                            fc_time.style.color = textColor;
2687                            if( em_front_event_object.hide_time_on_front_calendar == 1 ) {
2688                                fc_time.textContent = '';
2689                                fc_time.style.color = '';
2690                            }
2691                        }
2692                        var fc_title = info.el.querySelector('.fc-event-title');
2693                        if(fc_title){
2694                            fc_title.style.color = textColor;
2695                        }
2696                        var fc_list_time = info.el.querySelector('.fc-event-time');
2697                        if(fc_list_time){
2698                            fc_list_time.style.color = textColor;
2699                        }
2700                        var fc_list_title = info.el.querySelector('.fc-list-item-title');
2701                        if( fc_list_title ) {
2702                            fc_list_title.style.color = textColor;
2703                        }
2704                        var fc_list_event_time = info.el.querySelector('.fc-list-event-time');
2705                        if( fc_list_event_time ) {
2706                            fc_list_event_time.style.color = textColor;
2707                        }
2708                        var fc_list_event_dot = info.el.querySelector('.fc-list-event-dot');
2709                        if( fc_list_event_dot ) {
2710                            fc_list_event_dot.style.color = textColor;
2711                        }
2712                        var fc_list_event_title = info.el.querySelector('.fc-list-event-title');
2713                        if( fc_list_event_title ) {
2714                            fc_list_event_title.style.color = textColor;
2715                        }
2716                    }
2717                    
2718                      // --- per-event time hiding/rewriting ---
2719                        const { hideStartTime, hideEndTime } = info.event.extendedProps || {};
2720                        const hour12 = (eventprime.global_settings.time_format !== 'HH:mm');
2721
2722                        // format helper
2723                        const fmt = d => {
2724                          if (!d) return '';
2725                          try {
2726                            return new Intl.DateTimeFormat(em_admin_calendar_event_object.local, {
2727                              hour: '2-digit', minute: '2-digit', hour12
2728                            }).format(d);
2729                          } catch (e) {
2730                            // fallback
2731                            const pad = n => String(n).padStart(2,'0');
2732                            return d.getHours() + ':' + pad(d.getMinutes());
2733                          }
2734                        };
2735
2736                        // nodes present across views (dayGrid/timeGrid/list)
2737                        const nDayTime   = info.el.querySelector('.fc-event-time');
2737       // dayGrid/timeGrid
2738                        const nListTime  = info.el.querySelector('.fc-list-event-time');  // list
2739                        // In some themes, dayGrid uses '.fc-time' alias as well:
2740                        const nAltTime   = info.el.querySelector('.fc-time');
2741
2742                        // Build the desired time label
2743                        const startText = hideStartTime ? '' : fmt(info.event.start);
2744                        // For end: if end is null, we won't show anything anyway
2745                        const endText   = hideEndTime   ? '' : fmt(info.event.end);
2746
2747                        let label = '';
2748                        if (startText && endText) {
2749                          label = startText + ' – ' + endText;
2750                        } else if (startText && !endText) {
2751                          label = startText;                 // show only start
2752                        } else if (!startText && endText) {
2753                          label = endText;                   // show only end
2754                        } else {
2755                          label = '';                        // both hidden → no label
2756                        }
2757
2758                        // Apply the label (or hide node completely)
2759                        const applyLabel = node => {
2760                          if (!node) return;
2761                          if (label) {
2762                            node.textContent = label;
2763                            node.style.display = '';
2764                          } else {
2765                            node.textContent = '';
2766                           // node.style.display = 'none';
2767                          }
2768                        };
2769
2770                        applyLabel(nDayTime);
2771                        applyLabel(nAltTime);
2772                        applyLabel(nListTime);
2773
2774                        // If you *also* globally hide times via a setting, keep your existing guard:
2775                        if (em_front_event_object.hide_time_on_front_calendar == 1) {
2776                          if (nDayTime)  nDayTime.style.display = 'none';
2777                          if (nAltTime)  nAltTime.style.display = 'none';
2778                          if (nListTime) nListTime.style.display = 'none';
2779                        }
2780                     // --- per-event time hiding/rewriting end---
2781                     
2782                    
2783                    if( em_front_event_object.hide_time_on_front_calendar == 1 ) {
2784                        
2785                        $(info.el).find('.fc-event-time').hide();
2786                        $(info.el).find('.fc-list-event-time').hide();
2787                        
2788                    }
2789                    $( info.el ).append( info.event.extendedProps.popup_html );
2790                },
2791                eventMouseEnter: function( info ) {
2792                    let pop_block = info.el.querySelector( '.ep_event_detail_popup' );
2793                    pop_block.style.display = 'block';
2794                },
2795                eventMouseLeave: function( info ) {
2796                    let pop_block = info.el.querySelector( '.ep_event_detail_popup' );
2797                    pop_block.style.display = 'none';
2798                },
2799                eventClick: function( info ) {
2800                    var eventObj = info.event;
2801                    if ( eventObj.url ) {
2802                        let open_event_in_new_tab = info.event.extendedProps.open_event_in_new_tab;
2803                        if( open_event_in_new_tab == 1 ) {
2804                            window.open( eventObj.url );
2805                            info.jsEvent.preventDefault();
2806                        }
2807                    }
2808                },
2809            });
2810        
2811            calendar.render();
2812
2813            let calAreaWidht = $( "#ep-events-content-container" ).innerWidth();
2814            if( calAreaWidht <= 720 ) {
2815                calendar.setOption( 'dayHeaderFormat', { weekday: 'short' } );
2816            } else{
2817                calendar.setOption( 'dayHeaderFormat', { weekday: column_header_format } );
2818            }
2819
2820            // custom class on the toolbal title
2821            let cal_title_class = 'ep-calendar-title-short';
2822
2823            let calendar_title_format = "MMMM, YYYY";
2824            if (  typeof eventprime.global_settings.calendar_title_format !== 'undefined' ) { 
2825                calendar_title_format = eventprime.global_settings.calendar_title_format;
2826            }
2827
2828            if( calendar_title_format.search( 'DD' ) > -1 ) {
2829                cal_title_class = 'ep-calendar-title-full';
2830            }
2831            $( '#ep_event_calendar .fc-header-toolbar .fc-toolbar-title').addClass( cal_title_class );
2832        }
2833        
2834        /*
2835         * Select Filter Box
2836         */
2837        $( "#filter-date-from" ).datepicker({
2838            dateFormat: eventprime.datepicker_format,
2839            beforeShow: function () {
2840                let date_to = $( '#filter-date-to' ).val();
2841                if( date_to ) {
2842                    $( "#filter-date-from" ).datepicker("option", {
2843                        maxDate: date_to // set max date to to date
2844                    });
2845                }
2846                 $('#ui-datepicker-div').addClass('ep-ui-cal-wrap' );
2847            },
2848        });
2849        $('.ep-trigger-date-from').click(function(e){
2850            $("#filter-date-from").datepicker('show');
2851        });
2852        $( "#filter-date-to" ).datepicker({
2853            dateFormat: eventprime.datepicker_format,
2854            beforeShow: function () {
2855                let date_from = $( '#filter-date-from' ).val();
2856                if( date_from ) {
2857                    $( "#filter-date-to" ).datepicker("option", {
2858                        minDate: date_from // set min date to from date
2859                    });
2860                }
2861                $('#ui-datepicker-div').addClass('ep-ui-cal-wrap' );
2862            },
2863        });
2864        $('.ep-trigger-date-to').click(function(e){
2865            $("#filter-date-to").datepicker('show');
2866        });
2867        
2868        $('#ep-filter-venues, #ep-filter-types').select2();
2869        $('#ep-filter-org').select2({
2870            placeholder: em_front_event_object.organizers,
2871            multiple: true,
2872            //templateSelection: set_organizers_query,
2873            allowClear: true
2874        });
2875        $('#ep-filter-performer').select2({
2876            placeholder: em_front_event_object.performers,
2877            multiple: true,
2878            //templateSelection: set_performers_query,
2879            allowClear: true
2880        });
2881        
2882        // event filter list toggle
2883        if( $( '#ep-event-view-selector' ).length > 0 ) {
2884            $( '#ep-event-view-selector, .ep-box-dropdown-overlay' ).click( function(){
2885                $( '.ep-event-views-content' ).slideToggle();
2886                $( '#ep-event-view-selector' ).toggleClass( 'ep-box-dropdown-open' );
2887            });
2888        }
2889        
2890        //datepicker
2891        $( '.epDatePicker' ).datepicker({
2892            changeYear: true,
2893            changeMonth: true,
2894            dateFormat: eventprime.datepicker_format,
2895            gotoCurrent: true,
2896            showButtonPanel: true,
2897        });
2898
2899        $("#ep_event_keyword_search").on('click', function(){
2900            $("#ep-search-filters").css("animation", "ep-searchfilters 1s forwards normal 1");
2901            $(".ep-search-filter-overlay").show();
2902             jQuery("#ep_event_find_events_btn").addClass("ep-z-index-3").removeClass("ep-z-index-1");
2903        });
2904        
2905        $(".ep-search-filter-overlay").on('click',function(){
2906            if ($("#ep-search-filters").css("visibility") === "visible") {
2907                $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
2908            }
2909            $(".ep-search-filter-overlay").hide();
2910            jQuery("#ep_event_find_events_btn").addClass("ep-z-index-1").removeClass("ep-z-index-3");
2911        });
2912        $("#ep_filter_next_weekend, #ep_filter_next_week, #ep_filter_next_month, #ep_filter_online").on('click',function(){
2913            if ($("#ep-search-filters").css("visibility") === "visible") {
2914                $("#ep-search-filters").css("animation", "ep-searchfilters-exit 1s forwards normal 1");
2915            }
2916            $(".ep-search-filter-overlay").hide();
2917        });
2918
2919
2920        /* let ep_mcontainer = document.querySelector( '#ep_events_front_views_staggered_grid' );
2921        if ( ep_mcontainer ) {
2922            let msnry;
2923            imagesLoaded( ep_mcontainer, function() {
2924                msnry = new Masonry( ep_mcontainer, {
2925                    itemSelector: '#ep_events_front_views_staggered_grid .ep-event-card',
2926                });
2927            });
2928        } */
2929
2930        epCalViewWidhth();
2931
2932    ///  Event square card Image Setting start
2933                
2934    var styleElement = jQuery("<style>");
2935
2936    // Set the text content to include dynamic variables in :root
2937    var styleContent = ":root {\n";
2938
2939    if(eventprime.global_settings.events_image_visibility_options){
2940       styleContent += " --ep-imageCardObjectFit: " + eventprime.global_settings.events_image_visibility_options +  ";\n";
2941    }   else{
2942        styleContent += " --ep-imageCardObjectFit: " + 'cover' + ";\n"; 
2943    }
2944    if(eventprime.global_settings.events_image_height){
2945        styleContent += "  --ep-imageCardHeight: " + eventprime.global_settings.events_image_height + "px" + ";\n";
2946    }
2947    else{
2948        styleContent += " --ep-imageCardHeight: " + '140' + "px" + ";\n"; 
2949    }
2950
2951    styleContent += "}\n";
2952    styleElement.text(styleContent);
2953
2954    //  Append the <style> element to the <head> of the document
2955     jQuery("head").append(styleElement);
2956
2957    //   Event square card Image Setting end
2958}
2959
2960

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.