").text(String(value || "")).html();
}
function strip(value) {
return $("
").html(String(value || "")).text().replace(/\s+/g, " ").trim();
}
function geFormatEventDateTime(dateValue, timeValue) {
const rawDate = strip(dateValue || "");
const rawTime = strip(timeValue || "");
if (!rawDate) {
return { date: "", time: rawTime };
}
const looksMachineDate = /\d{4}-\d{2}-\d{2}(?:[T\s]\d{2}:\d{2})?/.test(rawDate);
const parsed = new Date(rawDate);
if (looksMachineDate && !Number.isNaN(parsed.getTime())) {
return {
date: parsed.toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric" }),
time: rawTime || parsed.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit" })
};
}
return { date: rawDate, time: rawTime };
}
function geEventDateMetaHtml(dateValue, timeValue) {
const parts = geFormatEventDateTime(dateValue, timeValue);
if (!parts.date && !parts.time) return "";
const dateHtml = parts.date ? `
${esc(parts.date)} ` : "";
const timeHtml = parts.time ? `
${esc(parts.time)} ` : "";
return `
📅 ${dateHtml}${timeHtml}
`;
}
function geCountryLabel(value) {
const code = String(value || "").trim().toUpperCase();
const map = {
NO: "Norway", SE: "Sweden", DK: "Denmark", FI: "Finland", IS: "Iceland",
DE: "Germany", FR: "France", ES: "Spain", IT: "Italy", PT: "Portugal",
NL: "Netherlands", BE: "Belgium", LU: "Luxembourg", GB: "United Kingdom",
UK: "United Kingdom", IE: "Ireland", US: "United States", USA: "United States",
CA: "Canada", AU: "Australia", NZ: "New Zealand", ZA: "South Africa",
CH: "Switzerland", AT: "Austria", PL: "Poland", CZ: "Czech Republic",
JP: "Japan", CN: "China", KR: "South Korea", IN: "India", BR: "Brazil",
MX: "Mexico", CL: "Chile", AE: "United Arab Emirates", LV: "Latvia",
BG: "Bulgaria", BU: "Myanmar", FO: "Faroe Islands", AR: "Argentina",
CY: "Cyprus", LT: "Lithuania"
};
return map[code] || String(value || "").trim();
}
function forceHttpsUrl(url) {
url = String(url || "").trim();
if (url.indexOf("http://") === 0) {
return "https://" + url.substring(7);
}
return url;
}
function normalizeAudienceList(raw) {
if (Array.isArray(raw)) {
return raw.map(function (item) {
if (typeof item === "string") return item.trim();
if (item && typeof item === "object") {
if (item.slug) return String(item.slug).trim();
if (item.name) return String(item.name).trim();
}
return "";
}).filter(Boolean);
}
if (typeof raw === "string") {
return raw.split(",").map(function (item) {
return String(item || "").trim();
}).filter(Boolean);
}
return [];
}
function geDedupeClean(value) {
return String(value || "")
.toLowerCase()
.replace(/&/g, "&")
.replace(/[^\p{L}\p{N}\s]+/gu, " ")
.replace(/\s+/g, " ")
.trim();
}
function geDedupeKey(item, type) {
const title = geDedupeClean(item.title || item.name || "");
const venue = geDedupeClean(item.venue_original || item.venue || item.location || "");
const city = geDedupeClean(item.city || "");
const country = geDedupeClean(item.country || "");
if (type === "events") {
const date = geDedupeClean(item.date_display || item.start_date || "");
const time = geDedupeClean(item.time_display || item.time || "");
return [title, date, time, venue, city, country].join("|");
}
return [title, venue, city, country].join("|");
}
function geDedupeResults(items, type) {
const list = Array.isArray(items) ? items : [];
const seen = {};
const out = [];
list.forEach(function (item) {
const title = geDedupeClean(item.title || item.name || "");
if (!title) {
out.push(item);
return;
}
const key = geDedupeKey(item, type);
if (seen[key]) return;
seen[key] = true;
out.push(item);
});
return out;
}
const GE_SS_KEYS = {
combined: "ge_combined_results_state"
};
const GE_DISCOVERY_DISPLAY_SIZE = 4;
const GE_DISCOVERY_POOL_SIZE = 12;
const GE_MOBILE_DISCOVERY_POOL_SIZE = 8;
const GE_IS_MOBILE = window.matchMedia && window.matchMedia("(max-width: 767px)").matches;
const GE_EFFECTIVE_DISCOVERY_POOL_SIZE = GE_IS_MOBILE ? 8 : GE_DISCOVERY_POOL_SIZE;
const state = {
categoryId: 0,
categorySlug: "",
subcategory: [],
audience: [],
startDate: "",
endDate: "",
nearbyMode: false,
nearbyStage: 0,
activeTab: "events",
hasSearched: false,
page: { events: 1, activities: 1 },
loading: { events: false, activities: false },
pending: { events: null, activities: null },
limit: { events: 4, activities: 4 },
lastTotal: { events: 0, activities: 0 },
discovery: {
events: { active: false, pool: [], visible: 0, sponsored: [], freshness: {} },
activities: { active: false, pool: [], visible: 0 }
},
datePicker: null,
requestSeq: 0
};
function syncAudienceFromUi() {
state.audience = [];
$(".ge-audience-checkbox:checked").each(function () {
const val = String($(this).val() || "").trim();
if (val) state.audience.push(val);
});
}
function syncSubcategoriesFromUi() {
state.subcategory = [];
$(".ge-subcat-checkbox:checked").each(function () {
const val = String($(this).val() || "").trim();
if (val) state.subcategory.push(val);
});
}
function parseDateInput() {
const raw = String($("#ge-date-input").val() || "").trim();
if (!raw) {
state.startDate = "";
state.endDate = "";
return;
}
const parts = raw.split(/\s+to\s+/i).map(function (s) {
return String(s || "").trim();
}).filter(Boolean);
state.startDate = parts[0] || "";
state.endDate = parts[1] || parts[0] || "";
}
function geResetSearchUi() {
$("#ge-keyword, #ge-city, #ge-zip, #ge-date-input").val("");
$("#ge-country").val("");
$(".ge-audience-checkbox, .ge-subcat-checkbox").prop("checked", false);
$(".ge-cat-btn").removeClass("active");
$(".ge-subcategory-group").attr("hidden", true);
state.categoryId = 0;
state.categorySlug = "";
state.subcategory = [];
state.audience = [];
state.startDate = "";
state.endDate = "";
state.nearbyMode = false;
state.nearbyStage = 0;
state.hasSearched = false;
state.page.events = 1;
state.page.activities = 1;
state.lastTotal.events = 0;
state.lastTotal.activities = 0;
state.discovery.events = { active: false, pool: [], visible: 0, sponsored: [], freshness: {}};
state.discovery.activities = { active: false, pool: [], visible: 0 };
}
function getBaseQuery() {
syncAudienceFromUi();
syncSubcategoriesFromUi();
parseDateInput();
return {
keyword: String($("#ge-keyword").val() || "").trim(),
city: String($("#ge-city").val() || "").trim(),
country: String($("#ge-country").val() || "").trim(),
zip: String($("#ge-zip").val() || "").trim(),
category_slug: state.categorySlug || "",
category: state.categoryId || 0,
subcategory: state.subcategory.join(","),
audience: state.audience.join(","),
start_date: state.startDate || "",
end_date: state.endDate || ""
};
}
function getScopedQuery() {
const q = getBaseQuery();
if (!state.nearbyMode) return q;
const scoped = { city: q.city, country: q.country, zip: q.zip };
if (state.nearbyStage >= 1) {
scoped.city = "";
scoped.zip = "";
}
if (state.nearbyStage >= 2) {
scoped.country = "";
}
return Object.assign({}, q, scoped);
}
function geSaveCombinedResultsState(targetMeta) {
try {
targetMeta = targetMeta || {};
const payload = {
lang: getCurrentLang(),
state: {
categoryId: state.categoryId,
categorySlug: state.categorySlug,
subcategory: state.subcategory || [],
audience: state.audience || [],
startDate: state.startDate || "",
endDate: state.endDate || "",
nearbyMode: !!state.nearbyMode,
nearbyStage: state.nearbyStage || 0,
activeTab: state.activeTab || "events",
hasSearched: !!state.hasSearched,
page: state.page || { events: 1, activities: 1 },
lastTotal: state.lastTotal || { events: 0, activities: 0 }
},
fields: {
keyword: $("#ge-keyword").val() || "",
city: $("#ge-city").val() || "",
country: $("#ge-country").val() || "",
zip: $("#ge-zip").val() || "",
date_input: $("#ge-date-input").val() || ""
},
html: {
eventsCount: $("#ge-events-count").html() || "",
activitiesCount: $("#ge-activities-count").html() || "",
eventResults: $("#ge-event-results").html() || "",
activityResults: $("#ge-activity-results").html() || "",
eventPagination: $("#ge-event-pagination").html() || "",
activityPagination: $("#ge-activity-pagination").html() || ""
},
scrollTop: $(window).scrollTop() || 0,
target: {
id: String(targetMeta.id || "").trim(),
url: String(targetMeta.url || "").trim()
},
ts: Date.now()
};
sessionStorage.setItem(GE_SS_KEYS.combined, JSON.stringify(payload));
} catch (e) {}
}
function geStripGeBackFromUrl() {
try {
const url = new URL(window.location.href);
if (url.searchParams.has("ge_back")) {
url.searchParams.delete("ge_back");
const clean =
url.pathname +
(url.searchParams.toString() ? "?" + url.searchParams.toString() : "") +
url.hash;
window.history.replaceState({}, document.title, clean);
}
} catch (e) {}
}
function geRestoreCombinedResultsState() {
try {
const raw = sessionStorage.getItem(GE_SS_KEYS.combined);
if (!raw) return false;
const saved = JSON.parse(raw);
if (!saved || !saved.state || !saved.html) return false;
if (saved.lang) geSetLangRuntime(saved.lang);
$("#ge-keyword").val((saved.fields && saved.fields.keyword) || "");
$("#ge-city").val((saved.fields && saved.fields.city) || "");
$("#ge-country").val((saved.fields && saved.fields.country) || "");
$("#ge-zip").val((saved.fields && saved.fields.zip) || "");
$("#ge-date-input").val((saved.fields && saved.fields.date_input) || "");
state.categoryId = saved.state.categoryId || 0;
state.categorySlug = saved.state.categorySlug || "";
state.subcategory = Array.isArray(saved.state.subcategory) ? saved.state.subcategory : [];
state.audience = Array.isArray(saved.state.audience) ? saved.state.audience : [];
state.startDate = saved.state.startDate || "";
state.endDate = saved.state.endDate || "";
state.nearbyMode = !!saved.state.nearbyMode;
state.nearbyStage = parseInt(saved.state.nearbyStage || 0, 10);
state.activeTab = saved.state.activeTab || "events";
state.hasSearched = !!saved.state.hasSearched;
state.page = saved.state.page || { events: 1, activities: 1 };
state.lastTotal = saved.state.lastTotal || { events: 0, activities: 0 };
$(".ge-subcat-checkbox").prop("checked", false);
state.subcategory.forEach(function (slug) {
$(`.ge-subcat-checkbox[value="${slug}"]`).prop("checked", true);
});
$(".ge-audience-checkbox").prop("checked", false);
state.audience.forEach(function (slug) {
$(`.ge-audience-checkbox[value="${slug}"]`).prop("checked", true);
});
$(".ge-cat-btn").removeClass("active");
$(".ge-subcategory-group").attr("hidden", true);
if (state.categoryId) {
$(`.ge-cat-btn[data-cat-id="${state.categoryId}"], .ge-cat-btn[data-cat="${state.categoryId}"]`).addClass("active");
$(`.ge-subcategory-group[data-parent="${state.categoryId}"]`).removeAttr("hidden");
}
$("#ge-events-count").html(saved.html.eventsCount || "");
$("#ge-activities-count").html(saved.html.activitiesCount || "");
$("#ge-event-results").html(saved.html.eventResults || "");
$("#ge-activity-results").html(saved.html.activityResults || "");
$("#ge-event-pagination").html(saved.html.eventPagination || "");
$("#ge-activity-pagination").html(saved.html.activityPagination || "");
setActiveTab(state.activeTab);
applyUiLabels();
filterRenderedByAudience();
geApplyResultButtonsToDom();
const targetId = saved.target && saved.target.id ? String(saved.target.id).trim() : "";
const targetUrl = saved.target && saved.target.url ? String(saved.target.url).trim() : "";
const savedScrollTop = parseInt(saved.scrollTop || 0, 10) || 0;
setTimeout(function () {
let $target = $();
if (targetId) {
$target = $("#ge-event-results .ge-event-card[data-id=\"" + targetId + "\"], #ge-activity-results .ge-event-card[data-id=\"" + targetId + "\"]").first();
}
if ((!$target || !$target.length) && targetUrl) {
$target = $(".ge-event-card a[href=\"" + targetUrl.replace(/"/g, '\\"') + "\"]").closest(".ge-event-card").first();
}
if ($target && $target.length) {
const top = Math.max($target.offset().top - 20, 0);
$(window).scrollTop(top);
} else {
$(window).scrollTop(savedScrollTop);
}
}, 60);
geStripGeBackFromUrl();
return true;
} catch (e) {
return false;
}
}
function applySearchPayload(payload) {
payload = payload || {};
if (payload && typeof payload === "object") {
if (payload.search && typeof payload.search === "object") payload = payload.search;
if (payload.filters && typeof payload.filters === "object") payload = payload.filters;
}
if (payload.lang) {
const restoredLang = geNormalizeLang(payload.lang);
geSetLangRuntime(restoredLang);
const $sel = $("#ge-language-select, .ge-language-select");
if ($sel.length && $sel.val() !== restoredLang) $sel.val(restoredLang);
}
$("#ge-keyword").val(String(payload.keyword || ""));
$("#ge-city").val(String(payload.city || ""));
$("#ge-country").val(String(payload.country || ""));
$("#ge-zip").val(String(payload.zip || ""));
state.categorySlug = String(payload.category_slug || "");
state.categoryId = parseInt(payload.category || 0, 10) || 0;
state.subcategory = String(payload.subcategory || "")
.split(",")
.map(function (v) { return String(v || "").trim(); })
.filter(Boolean);
state.audience = String(payload.audience || "")
.split(",")
.map(function (v) { return String(v || "").trim(); })
.filter(Boolean);
state.startDate = String(payload.start_date || payload.from || "");
state.endDate = String(payload.end_date || payload.to || "");
$("#ge-date-input").val(
state.startDate && state.endDate && state.startDate !== state.endDate
? `${state.startDate} to ${state.endDate}`
: (state.startDate || "")
);
$(".ge-subcat-checkbox").prop("checked", false);
state.subcategory.forEach(function (slug) {
$(`.ge-subcat-checkbox[value="${slug}"]`).prop("checked", true);
});
$(".ge-audience-checkbox").prop("checked", false);
state.audience.forEach(function (slug) {
$(`.ge-audience-checkbox[value="${slug}"]`).prop("checked", true);
});
$(".ge-cat-btn").removeClass("active");
$(".ge-subcategory-group").attr("hidden", true);
if (state.categoryId) {
$(`.ge-cat-btn[data-cat-id="${state.categoryId}"], .ge-cat-btn[data-cat="${state.categoryId}"]`).addClass("active");
$(`.ge-subcategory-group[data-parent="${state.categoryId}"]`).removeAttr("hidden");
}
}
function isDiscoveryQuery(query) {
query = query || {};
return !String(query.keyword || "").trim()
&& !String(query.city || "").trim()
&& !String(query.country || "").trim()
&& !String(query.zip || "").trim()
&& !String(query.category_slug || "").trim()
&& !parseInt(query.category || 0, 10)
&& !String(query.subcategory || "").trim()
&& !String(query.audience || "").trim()
&& !String(query.start_date || "").trim()
&& !String(query.end_date || "").trim();
}
function discoveryEndHtml(type) {
const label = type === "activities"
? geGetUiText("search_for_activities", "Search for activities")
: geGetUiText("search_for_events", "Search for events");
return '';
}
function renderNextDiscoveryEvents() {
const bucket = state.discovery.events;
const nextItems = bucket.pool.slice(bucket.visible, bucket.visible + GE_DISCOVERY_DISPLAY_SIZE);
const append = bucket.visible > 0;
if (!nextItems.length) {
$("#ge-event-pagination").html(discoveryEndHtml("events"));
geApplyResultButtonsToDom();
return;
}
bucket.visible += nextItems.length;
const sponsoredHtml = (!append && bucket.sponsored.length)
? bucket.sponsored.map(function (ev) { return renderEventCard(ev, true); }).join("")
: "";
const cardsHtml = nextItems.map(function (ev) { return renderEventCard(ev, false); }).join("");
if (append && $("#ge-event-results .ge-organic-grid").length) {
$("#ge-event-results .ge-organic-grid").append(cardsHtml);
} else {
$("#ge-event-results").html(
`
${sponsoredHtml}${cardsHtml}
`
);
}
const fresh = bucket.freshness || {};
const newLast24 = parseInt(fresh.new_last_24h || 0, 10);
const updatedLast24 = parseInt(fresh.updated_last_24h || 0, 10);
let freshHtml = "";
if (newLast24 > 0 || updatedLast24 > 0) {
freshHtml = `
${esc(geGetUiText("updated_today", "Updated today"))} · ${newLast24} ${esc(geGetUiText("new_events", "new events"))} · ${updatedLast24} ${esc(geGetUiText("updated_events", "updated"))}
`;
}
$("#ge-events-count").html(`${state.lastTotal.events} ${esc(geGetUiText("upcoming_events_found", "upcoming events found"))}${freshHtml}`);
$("#ge-event-pagination").html(bucket.visible < bucket.pool.length ? loadMoreHtml("events", false) : discoveryEndHtml("events"));
if (!bucket.pool.length && !bucket.sponsored.length && !append) {
$("#ge-event-results").html(`
${esc(geGetUiText("no_events_found", "No events found."))}
`);
$("#ge-event-pagination").empty();
}
filterRenderedByAudience();
geApplyResultButtonsToDom();
}
function renderNextDiscoveryActivities() {
const bucket = state.discovery.activities;
const nextItems = bucket.pool.slice(bucket.visible, bucket.visible + GE_DISCOVERY_DISPLAY_SIZE);
const append = bucket.visible > 0;
if (!nextItems.length) {
$("#ge-activity-pagination").html(discoveryEndHtml("activities"));
geApplyResultButtonsToDom();
return;
}
bucket.visible += nextItems.length;
const cardsHtml = nextItems.map(renderActivityCard).join("");
if (append && $("#ge-activity-results .ge-organic-grid").length) {
$("#ge-activity-results .ge-organic-grid").append(cardsHtml);
} else {
$("#ge-activity-results").html(`
${cardsHtml}
`);
}
$("#ge-activities-count").text(`${state.lastTotal.activities} ${geGetUiText("activities_found", "activities found")}`);
$("#ge-activity-pagination").html(bucket.visible < bucket.pool.length ? loadMoreHtml("activities", false) : discoveryEndHtml("activities"));
if (!bucket.pool.length && !append) {
$("#ge-activity-results").html(`
${esc(geGetUiText("no_activities_found", "No activities found."))}
`);
$("#ge-activity-pagination").empty();
}
filterRenderedByAudience();
geApplyResultButtonsToDom();
}
function geIsBackIntent() {
try {
const sp = new URLSearchParams(window.location.search);
if (sp.has("ge_back")) return true;
} catch (e) {}
return false;
}
function geApplyResultButtonsToDom() {
const viewDetails = geGetUiText("view_details", "View details");
const viewTickets = geGetUiText("view_tickets", "View tickets");
const sponsored = geGetUiText("sponsored", "Sponsored");
const sponsoredHeading = geGetUiText("sponsored_events", "Sponsored events");
$("#ge-event-results .ge-event-btn:not(.ge-activity-ticket-btn)").text(viewDetails);
$("#ge-activity-results .ge-event-btn:not(.ge-activity-ticket-btn)").text(viewDetails);
$("#ge-activity-results .ge-activity-ticket-btn").text(viewTickets);
$("#ge-event-results .ge-sponsored-badge").text(sponsored);
$("#ge-event-results .ge-sponsored-heading").text(sponsoredHeading);
const loadingMoreEvents = geGetUiText("loading_more_events", "Loading more events…");
const loadMoreEvents = geGetUiText("load_more_events", "Load more events");
const loadingMoreActivities = geGetUiText("loading_more_activities", "Loading more activities…");
const loadMoreActivities = geGetUiText("load_more_activities", "Load more activities");
const searchForEvents = geGetUiText("search_for_events", "Search for events");
const searchForActivities = geGetUiText("search_for_activities", "Search for activities");
$("#ge-event-pagination .ge-back-to-search-btn[data-type='events']").text(searchForEvents);
$("#ge-activity-pagination .ge-back-to-search-btn[data-type='activities']").text(searchForActivities);
$("#ge-event-pagination .ge-load-more-btn").each(function () {
const $btn = $(this);
const isBusy = $btn.is("[aria-busy='true']") || $btn.hasClass("is-loading");
$btn.find(".ge-load-more-label").text(isBusy ? loadingMoreEvents : loadMoreEvents);
});
$("#ge-activity-pagination .ge-load-more-btn").each(function () {
const $btn = $(this);
const isBusy = $btn.is("[aria-busy='true']") || $btn.hasClass("is-loading");
$btn.find(".ge-load-more-label").text(isBusy ? loadingMoreActivities : loadMoreActivities);
});
}
function renderEventCard(ev, sponsored) {
const safeTitle = strip(ev.title || ev.name || "Untitled event");
const safePermalink = String(ev.permalink || "#").trim() || "#";
const venueOriginal = strip(ev.venue_original || ev.venue || ev.location || "");
const safeCity = strip(ev.city || "");
const safeCountry = geCountryLabel(ev.country || "");
const locationParts = [venueOriginal, safeCity, safeCountry].filter(Boolean);
const location = esc(locationParts.join(", "));
const dateMeta = geEventDateMetaHtml(ev.date_display || ev.start_date || "", ev.time_display || ev.time || "");
const imageUrl = forceHttpsUrl(ev.image || ev.image_url || ev.thumbnail || "");
const desc = strip(ev.description || ev.excerpt || "");
const description = desc ? `
${esc(desc)}
` : "";
const defaultEventImage = "https://globoevent.com/wp-content/uploads/2026/03/event_default_image.png";
const image = `
`;
const sponsoredBadge = sponsored
? ``
: "";
const pastBadge = (
ev &&
(
ev.is_past === true ||
ev.is_past === 1 ||
ev.is_past === "1" ||
ev.status === "past"
)
)
? `
${esc(geGetUiText("past_event", "Past event"))}
`
: "";
const audienceRaw = normalizeAudienceList(ev.audience || ev.audiences).join(",");
return `
${image}
${sponsoredBadge}
${pastBadge}
${esc(safeTitle)}
${dateMeta}
📍 ${location}
${description}
`;
}
function renderActivityCard(ev) {
const safeTitle = strip(ev.title || ev.name || "Untitled activity");
const safePermalink = String(ev.permalink || "#").trim() || "#";
const venueOriginal = strip(ev.venue_original || ev.venue || ev.location || "");
const safeCity = strip(ev.city || "");
const safeCountry = geCountryLabel(ev.country || "");
const locationParts = [venueOriginal, safeCity, safeCountry].filter(Boolean);
const location = esc(locationParts.join(", "));
const imageUrl = forceHttpsUrl(ev.image || ev.image_url || ev.thumbnail || "");
const desc = strip(ev.description || ev.excerpt || "");
const description = desc ? `
${esc(desc)}
` : "";
const openingHours = strip(ev.opening_hours || "");
const activityKind = strip(ev.activity_kind || "");
const ticketUrl = forceHttpsUrl(ev.ticket_url || ev.cta_url || "");
const defaultActivityImage = "https://globoevent.com/wp-content/uploads/2026/04/find_activities_in_globoevent-scaled.jpg";
const image = `
`;
const hoursHtml = openingHours
? `
🕒 ${esc(openingHours)}
`
: "";
const kindHtml = activityKind
? `
🎡 ${esc(activityKind)}
`
: "";
const detailsBtn = `
${esc(geGetUiText("view_details", "View details"))}
`;
const ticketBtn = ticketUrl
? `
${esc(geGetUiText("view_tickets", "View tickets"))}
`
: "";
const audienceRaw = normalizeAudienceList(ev.audience || ev.audiences).join(",");
return `
${image}
${esc(safeTitle)}
📍 ${location}
${kindHtml}
${hoursHtml}
${description}
${detailsBtn}
${ticketBtn}
`;
}
function sectionLoading(selector, message) {
$(selector).html(`
${esc(message)}
`);
}
function sectionError(selector, message) {
$(selector).html(`
${esc(message)}
`);
}
function loadMoreHtml(type, isLoading) {
const isEvents = type === "events";
const loadLabel = isEvents
? (isLoading
? geGetUiText("loading_more_events", "Loading more events…")
: geGetUiText("load_more_events", "Load more events"))
: (isLoading
? geGetUiText("loading_more_activities", "Loading more activities…")
: geGetUiText("load_more_activities", "Load more activities"));
const searchLabel = isEvents
? geGetUiText("search_for_events", "Search for events")
: geGetUiText("search_for_activities", "Search for activities");
const disabled = isLoading ? ' disabled aria-disabled="true" aria-busy="true"' : "";
const loadingClass = isLoading ? " is-loading" : "";
return ''
+ '';
}
function renderEventsSection(data, append) {
const results = geDedupeResults(Array.isArray(data.results) ? data.results : [], "events");
const sponsored = geDedupeResults(Array.isArray(data.sponsored_results) ? data.sponsored_results : [], "events");
const total = parseInt(data.total || results.length || 0, 10);
state.lastTotal.events = total;
if (state.discovery.events.active && !append) {
state.discovery.events.pool = results.slice();
state.discovery.events.visible = 0;
state.discovery.events.sponsored = sponsored.slice();
state.discovery.events.freshness = data.freshness || {};
renderNextDiscoveryEvents();
return;
}
const sponsoredHtml = (sponsored.length && !append)
? sponsored.map(function (ev) { return renderEventCard(ev, true); }).join("")
: "";
const cardsHtml = results.map(function (ev) { return renderEventCard(ev, false); }).join("");
if (append && $("#ge-event-results .ge-organic-grid").length) {
const existingKeys = {};
$("#ge-event-results .ge-event-card").each(function () {
const key = [
geDedupeClean($(this).find(".ge-event-title").text()),
geDedupeClean($(this).find(".ge-event-meta").first().text().replace("📅", "")),
geDedupeClean($(this).attr("data-venue-original") || ""),
geDedupeClean($(this).find(".ge-event-meta").eq(1).text().replace("📍", ""))
].join("|");
existingKeys[key] = true;
});
const freshHtml = results.filter(function (ev) {
const key = [
geDedupeClean(ev.title || ev.name || ""),
geDedupeClean((ev.date_display || ev.start_date || "") + " " + (ev.time_display || ev.time || "")),
geDedupeClean(ev.venue_original || ev.venue || ev.location || ""),
geDedupeClean([ev.city || "", ev.country || ""].filter(Boolean).join(" "))
].join("|");
if (existingKeys[key]) return false;
existingKeys[key] = true;
return true;
}).map(function (ev) {
return renderEventCard(ev, false);
}).join("");
$("#ge-event-results .ge-organic-grid").append(freshHtml);
} else {
$("#ge-event-results").html(
`
${sponsoredHtml}${cardsHtml}
`
);
}
const fresh = data.freshness || {};
const newLast24 = parseInt(fresh.new_last_24h || 0, 10);
const updatedLast24 = parseInt(fresh.updated_last_24h || 0, 10);
let freshHtml = "";
if (newLast24 > 0 || updatedLast24 > 0) {
freshHtml = `
${esc(geGetUiText("updated_today", "Updated today"))} · ${newLast24} ${esc(geGetUiText("new_events", "new events"))} · ${updatedLast24} ${esc(geGetUiText("updated_events", "updated"))}
`;
}
$("#ge-events-count").html(`${total} ${esc(geGetUiText("upcoming_events_found", "upcoming events found"))}${freshHtml}`);
if (data.has_more) {
$("#ge-event-pagination").html(loadMoreHtml("events", false));
} else if (state.hasSearched) {
$("#ge-event-pagination").html(
''
);
} else {
$("#ge-event-pagination").empty();
}
if (!results.length && !sponsored.length && !append) {
$("#ge-event-results").html(`
${esc(geGetUiText("no_events_found", "No events found."))}
`);
$("#ge-event-pagination").empty();
}
filterRenderedByAudience();
geApplyResultButtonsToDom();
}
function renderActivitiesSection(data, append) {
const results = geDedupeResults(Array.isArray(data.results) ? data.results : [], "activities");
const total = parseInt(data.total || results.length || 0, 10);
state.lastTotal.activities = total;
if (state.discovery.activities.active && !append) {
state.discovery.activities.pool = results.slice();
state.discovery.activities.visible = 0;
renderNextDiscoveryActivities();
return;
}
const cardsHtml = results.map(renderActivityCard).join("");
if (append && $("#ge-activity-results .ge-organic-grid").length) {
$("#ge-activity-results .ge-organic-grid").append(cardsHtml);
} else {
$("#ge-activity-results").html(`
${cardsHtml}
`);
}
$("#ge-activities-count").text(`${total} ${geGetUiText("activities_found", "activities found")}`);
if (data.has_more) {
$("#ge-activity-pagination").html(loadMoreHtml("activities", false));
} else if (state.hasSearched) {
$("#ge-activity-pagination").html(
''
);
} else {
$("#ge-activity-pagination").empty();
}
if (!results.length && !append) {
$("#ge-activity-results").html(`
${esc(geGetUiText("no_activities_found", "No activities found."))}
`);
$("#ge-activity-pagination").empty();
}
filterRenderedByAudience();
geApplyResultButtonsToDom();
}
function abortPending(type) {
const req = state.pending[type];
if (req && typeof req.abort === "function") {
try { req.abort("abort"); } catch (e) {}
}
state.pending[type] = null;
}
function eventsRequest(query, page) {
abortPending("events");
state.loading.events = true;
const eventCity = String(query.city || "").trim();
const eventZip = String(query.zip || "").trim();
// Important: if city or zip exists, do not also send country.
// City + country meta queries are too slow on events.
const eventCountry = (eventCity || eventZip) ? "" : String(query.country || "").trim();
const data = {
action: "ge_search_events",
lang: getCurrentLang(),
keyword: query.keyword,
category_slug: query.category_slug,
category: query.category,
subcategory: query.subcategory,
audience: query.audience,
start_date: query.start_date,
end_date: query.end_date,
page: isDiscoveryQuery(query) ? 1 : page,
limit: isDiscoveryQuery(query) ? GE_EFFECTIVE_DISCOVERY_POOL_SIZE : state.limit.events
};
if (eventCity) data.city = eventCity;
if (eventZip) data.zip = eventZip;
if (eventCountry) data.country = eventCountry;
state.pending.events = $.ajax({
url: geAjaxUrl(),
method: "POST",
dataType: "json",
timeout: 60000,
data: data
}).fail(function (jqXHR, textStatus, errorThrown) {
console.error("ge_search_events failed", {
textStatus: textStatus,
errorThrown: errorThrown,
status: jqXHR.status,
responseText: jqXHR.responseText
});
});
return state.pending.events.always(function () {
state.loading.events = false;
state.pending.events = null;
});
}
function activitiesRequest(query, page) {
abortPending("activities");
state.loading.activities = true;
state.pending.activities = $.ajax({
url: geAjaxUrl(),
method: "POST",
dataType: "json",
timeout: 30000,
data: {
action: "ge_search_activities",
lang: getCurrentLang(),
keyword: query.keyword,
city: query.city,
country: query.country,
zip: query.zip,
category_slug: query.category_slug,
category: query.category,
subcategory: query.subcategory,
audience: query.audience,
page: isDiscoveryQuery(query) ? 1 : page,
limit: isDiscoveryQuery(query) ? GE_EFFECTIVE_DISCOVERY_POOL_SIZE : state.limit.activities,
preload: isDiscoveryQuery(query) ? 1 : 0
}
}).fail(function (jqXHR, textStatus, errorThrown) {
console.error("ge_search_activities failed", {
textStatus: textStatus,
errorThrown: errorThrown,
status: jqXHR.status,
responseText: jqXHR.responseText
});
});
return state.pending.activities.always(function () {
state.loading.activities = false;
state.pending.activities = null;
});
}
function normalizeResponse(res) {
if (typeof res === "string") {
try { res = JSON.parse(res); } catch (e) { res = {}; }
}
return (res && res.data) ? res.data : {};
}
function shouldFallback(eventsData, activitiesData, append) {
if (!state.nearbyMode || append) return false;
const eLen = Array.isArray(eventsData.results) ? eventsData.results.length : 0;
const eSponsor = Array.isArray(eventsData.sponsored_results) ? eventsData.sponsored_results.length : 0;
const aLen = Array.isArray(activitiesData.results) ? activitiesData.results.length : 0;
return eLen === 0 && eSponsor === 0 && aLen === 0 && state.nearbyStage < 2;
}
function renderFallbackMessage() {
if (state.nearbyStage === 1) {
$("#ge-results").prepend(`
${esc(geGetUiText("no_local_results_expanding_country", "No local results. Expanding to your country…"))}
`);
} else if (state.nearbyStage === 2) {
$("#ge-results").prepend(`
${esc(geGetUiText("no_country_results_global", "No nearby country results. Showing global results…"))}
`);
}
}
function setActiveTab(tab) {
state.activeTab = (tab === "activities") ? "activities" : "events";
$(".ge-results-tab").removeClass("active").attr("aria-selected", "false");
$(`.ge-results-tab[data-tab="${state.activeTab}"]`).addClass("active").attr("aria-selected", "true");
$("#ge-events-section, #ge-activities-section").removeClass("is-active");
if (state.activeTab === "events") $("#ge-events-section").addClass("is-active");
else $("#ge-activities-section").addClass("is-active");
}
function renderPreSearchState() {
$("#ge-events-count").empty();
$("#ge-activities-count").empty();
$("#ge-event-pagination").empty();
$("#ge-activity-pagination").empty();
$("#ge-event-results").html(
`
${esc(geGetUiText("presearch_events", "Search to find upcoming events."))}
`
);
$("#ge-activity-results").html(
`
${esc(geGetUiText("presearch_activities", "Search to find ongoing activities."))}
`
);
setActiveTab(state.activeTab);
geApplyResultButtonsToDom();
}
function bindTabs() {
$(document)
.off("click.geResultsTabs", ".ge-results-tab")
.on("click.geResultsTabs", ".ge-results-tab", function (e) {
e.preventDefault();
setActiveTab(String($(this).data("tab") || "events"));
});
}
function filterRenderedByAudience() {
const selected = Array.isArray(state.audience) ? state.audience : [];
const applyFilter = function ($cards) {
let visibleCount = 0;
$cards.each(function () {
const $card = $(this);
const raw = String($card.attr("data-audience") || "").trim();
const itemAudiences = raw
? raw.split(",").map(function (v) { return String(v || "").trim(); }).filter(Boolean)
: [];
let show = true;
if (selected.length) {
show = selected.some(function (wanted) {
return itemAudiences.includes(wanted);
});
}
$card.toggle(show);
if (show) visibleCount += 1;
});
return visibleCount;
};
const visibleEvents = applyFilter($("#ge-event-results .ge-event-card"));
const visibleActivities = applyFilter($("#ge-activity-results .ge-activity-card"));
const fresh = state.discovery.events.freshness || {};
const newLast24 = parseInt(fresh.new_last_24h || 0, 10);
const updatedLast24 = parseInt(fresh.updated_last_24h || 0, 10);
let freshHtml = "";
if (newLast24 > 0 || updatedLast24 > 0) {
freshHtml = `
${esc(geGetUiText("updated_today", "Updated today"))} · ${newLast24} ${esc(geGetUiText("new_events", "new events"))} · ${updatedLast24} ${esc(geGetUiText("updated_events", "updated"))}
`;
}
const eventCount = selected.length ? visibleEvents : state.lastTotal.events;
$("#ge-events-count").html(
`${eventCount} ${esc(geGetUiText("upcoming_events_found", "upcoming events found"))}${freshHtml}`
);
$("#ge-activities-count").text(
selected.length
? `${visibleActivities} ${geGetUiText("activities_found", "activities found")}`
: `${state.lastTotal.activities} ${geGetUiText("activities_found", "activities found")}`
);
}
function applyUiLabels() {
geApplyUiDict(window.GE_UI || {});
geApplyAudienceDict(window.GE_AUDIENCE_DICT || {});
$(".ge-mobile-filters-toggle, .ge-search-filters-toggle, #ge-search-filters-toggle")
.text(geGetUiText("filters", "Search & Filters"));
$("#ge-events-section .ge-results-section-title").text(geGetUiText("events", "Events"));
$("#ge-activities-section .ge-results-section-title").text(geGetUiText("activities", "Activities"));
$('.ge-results-tab[data-tab="events"]').text(geGetUiText("events", "Events"));
$('.ge-results-tab[data-tab="activities"]').text(geGetUiText("activities", "Activities"));
const $advancedHeadings = $("#ge-advanced-panel h4");
if ($advancedHeadings.length) $advancedHeadings.first().text(geGetUiText("audience", "Audience"));
const $modalH3 = $("#ge-category-modal h3").first();
if ($modalH3.length) $modalH3.text(geGetUiText("refine_category", "Refine category"));
const $modalH4 = $("#ge-category-modal h4").first();
if ($modalH4.length) $modalH4.text(geGetUiText("subcategories", "Subcategories"));
geApplyResultButtonsToDom();
if (!state.hasSearched) renderPreSearchState();
else filterRenderedByAudience();
}
function runCombinedSearch(options) {
options = options || {};
state.hasSearched = true;
const appendType = options.appendType || "";
const resetPages = !appendType;
const requestId = ++state.requestSeq;
if (resetPages) {
state.page.events = 1;
state.page.activities = 1;
sectionLoading("#ge-event-results", geGetUiText("loading_events", "Loading events…"));
sectionLoading("#ge-activity-results", geGetUiText("loading_activities", "Loading activities…"));
$("#ge-event-pagination, #ge-activity-pagination").empty();
$(".ge-fallback-message").remove();
}
const query = getScopedQuery();
const discoveryQuery = isDiscoveryQuery(query);
if (resetPages) {
state.discovery.events = { active: discoveryQuery, pool: [], visible: 0, sponsored: [], freshness: {} };
state.discovery.activities = { active: discoveryQuery, pool: [], visible: 0 };
}
const wantEvents = appendType === "" || appendType === "events";
const wantActivities = appendType === "" || appendType === "activities";
const eventPromise = wantEvents
? eventsRequest(query, state.page.events)
: $.Deferred().resolve({ data: { results: [], total: state.lastTotal.events, has_more: false } }).promise();
const activityPromise = wantActivities
? activitiesRequest(query, state.page.activities)
: $.Deferred().resolve({ data: { results: [], total: state.lastTotal.activities, has_more: false } }).promise();
function safeSearchPromise(promise, type) {
const d = $.Deferred();
promise
.done(function (res) {
d.resolve({ ok: true, type: type, res: res });
})
.fail(function (jqXHR, textStatus, errorThrown) {
if (textStatus === "abort") {
d.resolve({ ok: false, aborted: true, type: type });
return;
}
console.error("ge_search_" + type + " failed safely", {
textStatus: textStatus,
errorThrown: errorThrown,
status: jqXHR && jqXHR.status,
responseText: jqXHR && jqXHR.responseText
});
d.resolve({
ok: false,
type: type,
jqXHR: jqXHR,
textStatus: textStatus,
errorThrown: errorThrown
});
});
return d.promise();
}
$.when(safeSearchPromise(eventPromise, "events"), safeSearchPromise(activityPromise, "activities"))
.done(function (eventWrap, activityWrap) {
if (requestId !== state.requestSeq) return;
if ((eventWrap && eventWrap.aborted) || (activityWrap && activityWrap.aborted)) return;
const eventsData = eventWrap && eventWrap.ok ? normalizeResponse(eventWrap.res) : { results: [], total: 0, has_more: false };
const activitiesData = activityWrap && activityWrap.ok ? normalizeResponse(activityWrap.res) : { results: [], total: 0, has_more: false };
if ((eventWrap && eventWrap.ok) && (activityWrap && activityWrap.ok) && shouldFallback(eventsData, activitiesData, !!appendType)) {
state.nearbyStage += 1;
renderFallbackMessage();
runCombinedSearch({ appendType: "" });
return;
}
if (wantEvents) {
if (eventWrap && eventWrap.ok) renderEventsSection(eventsData, appendType === "events");
else sectionError("#ge-event-results", geGetUiText("events_failed_to_load", "Events failed to load."));
}
if (wantActivities) {
if (activityWrap && activityWrap.ok) renderActivitiesSection(activitiesData, appendType === "activities");
else sectionError("#ge-activity-results", geGetUiText("activities_failed_to_load", "Activities failed to load."));
}
if (wantEvents && (!eventWrap || !eventWrap.ok)) $("#ge-events-count").text("");
if (wantActivities && (!activityWrap || !activityWrap.ok)) $("#ge-activities-count").text("");
setActiveTab(state.activeTab);
geApplyResultButtonsToDom();
});
}
function geLocalDateString(date) {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
const d = String(date.getDate()).padStart(2, "0");
return `${y}-${m}-${d}`;
}
function setToday() {
const today = geLocalDateString(new Date());
state.startDate = today;
state.endDate = today;
$("#ge-date-input").val(today);
}
function setWeekend() {
const now = new Date();
const day = now.getDay(); // 0 = Sunday, 6 = Saturday
const saturday = new Date(now);
const sunday = new Date(now);
if (day === 6) {
// Saturday: today + tomorrow
sunday.setDate(now.getDate() + 1);
} else if (day === 0) {
// Sunday: yesterday + today
saturday.setDate(now.getDate() - 1);
} else {
// Monday-Friday: upcoming Saturday/Sunday
saturday.setDate(now.getDate() + (6 - day));
sunday.setDate(saturday.getDate() + 1);
}
state.startDate = geLocalDateString(saturday);
state.endDate = geLocalDateString(sunday);
$("#ge-date-input").val(`${state.startDate} to ${state.endDate}`);
}
function initDatePicker() {
const $input = $("#ge-date-input");
const $btn = $("#ge-date-btn");
if (!$input.length || !$btn.length) return;
if (typeof window.flatpickr === "function") {
state.datePicker = window.flatpickr($input[0], {
mode: "range",
dateFormat: "Y-m-d",
allowInput: false,
clickOpens: false,
onChange: function (dates, dateStr) {
$input.val(dateStr || "");
parseDateInput();
if (dates.length === 2 || (dates.length === 1 && dateStr)) {
state.nearbyMode = false;
state.nearbyStage = 0;
runCombinedSearch();
}
}
});
$(document).off("click.geDateBtn", "#ge-date-btn").on("click.geDateBtn", "#ge-date-btn", function (e) {
e.preventDefault();
try { state.datePicker.open(); } catch (err) {}
});
return;
}
$(document).off("click.geDateBtn", "#ge-date-btn").on("click.geDateBtn", "#ge-date-btn", function (e) {
e.preventDefault();
const typed = window.prompt(
geGetUiText("date_prompt", "Enter date or range as YYYY-MM-DD or YYYY-MM-DD to YYYY-MM-DD"),
$("#ge-date-input").val() || ""
);
if (typed === null) return;
$("#ge-date-input").val(String(typed || "").trim());
parseDateInput();
state.nearbyMode = false;
state.nearbyStage = 0;
runCombinedSearch();
});
}
$(document).on("click", ".ge-back-to-search-btn", function (e) {
e.preventDefault();
const $target =
$("#ge-search-form").length ? $("#ge-search-form") :
$(".ge-filter-row").first().length ? $(".ge-filter-row").first() :
$("#globoevent-wrapper").length ? $("#globoevent-wrapper") :
$("body");
$("html, body").animate({
scrollTop: Math.max(($target.offset() ? $target.offset().top : 0) - 20, 0)
}, 600);
});
function geCleanNearbyCity(value) {
return String(value || "")
.replace(/\s+Municipality$/i, "")
.replace(/\s+Commune$/i, "")
.replace(/\s+County$/i, "")
.trim();
}
function bindNearby() {
$(document)
.off("click.geCombinedNearby", ".ge-nearby")
.on("click.geCombinedNearby", ".ge-nearby", function (e) {
e.preventDefault();
if (!navigator.geolocation) {
alert("Geolocation not supported.");
return;
}
navigator.geolocation.getCurrentPosition(function (position) {
const lat = position.coords.latitude;
const lng = position.coords.longitude;
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&zoom=10&addressdetails=1&lat=${encodeURIComponent(lat)}&lon=${encodeURIComponent(lng)}`)
.then(function (res) {
if (!res.ok) throw new Error("Reverse geocode failed");
return res.json();
})
.then(function (data) {
const a = (data && data.address) ? data.address : {};
const rawCity = a.city || a.town || a.village || a.municipality || a.suburb || a.county || "";
const city = geCleanNearbyCity(rawCity);
const country = a.country_code ? a.country_code.toUpperCase() : "";
$("#ge-city").val(city || "");
$("#ge-country").val(country || "");
$("#ge-zip").val("");
state.nearbyMode = true;
state.nearbyStage = 0;
runCombinedSearch();
})
.catch(function () {
state.nearbyMode = true;
state.nearbyStage = 0;
$("#ge-city").val("");
$("#ge-country").val("");
$("#ge-zip").val("");
runCombinedSearch();
});
}, function () {
alert("Location permission denied or unavailable.");
}, { enableHighAccuracy: false, timeout: 15000, maximumAge: 60000 });
});
}
function geEnsureSavedContainer() {
if ($("#ge-saved-container").length) return;
const html = '
';
if ($("#globoevent-wrapper").length) $("#globoevent-wrapper").prepend(html);
else if ($("#ge-results").length) $("#ge-results").before(html);
else $("body").prepend(html);
}
function geIsLoggedIn() {
try {
return document.body && (document.body.className || "").indexOf("logged-in") !== -1;
} catch (e) {}
return false;
}
function geGuestStoreKey() {
const host = (location && location.host) ? location.host : "site";
return "ge_saved_searches_guest_" + host + "_combined";
}
function geGuestLoadAll() {
try {
const raw = localStorage.getItem(geGuestStoreKey());
const arr = raw ? JSON.parse(raw) : [];
return Array.isArray(arr) ? arr : [];
} catch (e) {
return [];
}
}
function geGuestSaveAll(arr) {
try {
localStorage.setItem(geGuestStoreKey(), JSON.stringify(Array.isArray(arr) ? arr : []));
} catch (e) {}
}
function geGuestMakeFiltersPayload() {
syncAudienceFromUi();
syncSubcategoriesFromUi();
parseDateInput();
return {
keyword: $("#ge-keyword").val() || "",
city: $("#ge-city").val() || "",
zip: $("#ge-zip").val() || "",
country: $("#ge-country").val() || "",
lang: (typeof getCurrentLang === "function") ? getCurrentLang() : "en",
audience: Array.isArray(state.audience) ? state.audience.join(",") : "",
category: state.categoryId || 0,
category_slug: state.categorySlug || "",
subcategory: Array.isArray(state.subcategory) ? state.subcategory.join(",") : "",
from: state.startDate || "",
to: state.endDate || "",
free_only: 0,
tags: []
};
}
function geServerSaysLoginRequired(res) {
const msg =
(res && res.data && (res.data.message || res.data.error))
? String(res.data.message || res.data.error)
: "";
return msg.toLowerCase().indexOf("login") !== -1;
}
function getSavedSearchesRequest() {
return $.ajax({
url: geAjaxUrl(),
method: "POST",
dataType: "json",
timeout: 30000,
data: { action: "ge_load_saved_searches" }
});
}
function geShareIconSvg() {
return '
';
}
function geBuildShareUrl(filters) {
const data = filters || {};
const params = new URLSearchParams();
function setIf(key, val) {
if (val === undefined || val === null) return;
const str = String(val).trim();
if (!str || str === "0") return;
params.set(key, str);
}
setIf("keyword", data.keyword || "");
setIf("city", data.city || "");
setIf("zip", data.zip || "");
setIf("country", data.country || "");
setIf("lang", data.lang || getCurrentLang());
setIf("audience", data.audience || "");
setIf("category", data.category || "");
setIf("subcategory", data.subcategory || "");
setIf("from", data.from || data.start_date || "");
setIf("to", data.to || data.end_date || "");
const url = new URL(window.location.href);
url.search = params.toString();
return url.toString();
}
function geOpenShareMenu(anchorEl, shareUrl, shareTitle) {
$(".ge-share-menu").remove();
const title = shareTitle || "Check out this GloboEvent search";
const text = "I found this search on GloboEvent";
const encodedUrl = encodeURIComponent(shareUrl);
const encodedText = encodeURIComponent(text + " " + shareUrl);
const encodedTitle = encodeURIComponent(title);
const menu = $(
''
);
$("body").append(menu);
const offset = $(anchorEl).offset() || { top: 0, left: 0 };
menu.css({
position: "absolute",
top: offset.top + $(anchorEl).outerHeight() + 8,
left: Math.max(12, offset.left - 120 + ($(anchorEl).outerWidth() || 0)),
zIndex: 99999,
minWidth: "180px",
background: "#fff",
border: "1px solid #ddd",
borderRadius: "12px",
boxShadow: "0 10px 30px rgba(0,0,0,0.12)",
padding: "8px",
display: "grid",
gap: "6px"
});
menu.find(".ge-share-option").css({
display: "block",
width: "100%",
border: "0",
background: "#fff",
color: "#111",
textAlign: "left",
padding: "10px 12px",
borderRadius: "10px",
textDecoration: "none",
cursor: "pointer"
});
menu.on("click", "[data-share-copy]", function (e) {
e.preventDefault();
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(shareUrl).then(function () {
alert(geGetUiText("link_copied", "Link copied."));
}, function () {
window.prompt(geGetUiText("copy_this_link", "Copy this link:"), shareUrl);
});
} else {
window.prompt(geGetUiText("copy_this_link", "Copy this link:"), shareUrl);
}
menu.remove();
});
menu.on("click", "[data-share-email]", function (e) {
e.preventDefault();
const subject = $(this).attr("data-share-title") || encodedTitle;
const body = $(this).attr("data-share-body") || encodedText;
window.location.href = "mailto:?subject=" + subject + "&body=" + body;
menu.remove();
});
menu.on("click", "[data-share-native]", function (e) {
e.preventDefault();
if (navigator.share) {
navigator.share({ title: title, text: text, url: shareUrl }).catch(function () {});
} else {
window.prompt(geGetUiText("copy_this_link", "Copy this link:"), shareUrl);
}
menu.remove();
});
setTimeout(function () {
$(document).one("click.geShareMenu", function (ev) {
if (!$(ev.target).closest(".ge-share-menu, .ge-saved-share, .ge-share-selected").length) {
$(".ge-share-menu").remove();
}
});
}, 0);
}
function renderSavedSearches(items) {
const list = Array.isArray(items) ? items : [];
if (!list.length) {
$("#ge-saved-container").html(
'
' + esc(geGetUiText("no_saved_searches", "No saved searches.")) + "
"
);
return;
}
let html = '
';
list.forEach(function (item, index) {
let payload = (item && item.filters) ? item.filters : ((item && item.search) ? item.search : item);
if (typeof payload === "string") {
try { payload = JSON.parse(payload); } catch (e) { payload = {}; }
}
if (payload && typeof payload === "object") {
if (payload.search && typeof payload.search === "object") payload = payload.search;
if (payload.filters && typeof payload.filters === "object") payload = payload.filters;
}
const label =
(item && (item.name || item.label || item.title)) ||
(geGetUiText("saved_search", "Saved search") + " " + (index + 1));
html += `
${esc(label)}
${geShareIconSvg()}
`;
});
html += `
${esc(geGetUiText("share_selected", "Share selected"))}
${esc(geGetUiText("delete_selected", "Delete selected"))}
${esc(geGetUiText("delete_all", "Delete all"))}
`;
html += "
";
$("#ge-saved-container").html(html);
}
$(document)
.off("click.geSaveSearch touchend.geSaveSearch", ".ge-save-search")
.on("click.geSaveSearch touchend.geSaveSearch", ".ge-save-search", function (e) {
e.preventDefault();
const promptText = geGetUiText(
"save_search_prompt",
"Name this search:\n\nThis search is saved temporarily in your browser on this device. It may be removed if you clear browser data or cache."
);
const rawName = window.prompt(promptText, "");
if (rawName === null) return;
const name = String(rawName || "").trim();
if (!name) return;
if (!geIsLoggedIn()) {
const all = geGuestLoadAll();
all.unshift({
name: name,
filters: geGuestMakeFiltersPayload(),
ts: Date.now()
});
geGuestSaveAll(all);
$("#ge-saved-container").html(
'
' + esc(geGetUiText("search_saved_device", "Search saved on this device.")) + "
"
);
return;
}
const payload = geGuestMakeFiltersPayload();
$.ajax({
url: geAjaxUrl(),
method: "POST",
dataType: "json",
timeout: 60000,
data: {
action: "ge_save_search",
name: name,
keyword: payload.keyword || "",
city: payload.city || "",
zip: payload.zip || "",
country: payload.country || "",
lang: payload.lang || getCurrentLang(),
audience: payload.audience || "",
category: payload.category || 0,
subcategory: payload.subcategory || "",
from: payload.from || "",
to: payload.to || "",
free_only: 0,
tags: []
}
}).done(function (res) {
if (typeof res === "string") {
try { res = JSON.parse(res); } catch (err) { res = {}; }
}
if (res && res.success) {
$("#ge-saved-container").html(
'
' + esc(geGetUiText("search_saved_device", "Search saved on this device.")) + "
"
);
return;
}
if (geServerSaysLoginRequired(res)) {
const all = geGuestLoadAll();
all.unshift({
name: name,
filters: geGuestMakeFiltersPayload(),
ts: Date.now()
});
geGuestSaveAll(all);
$("#ge-saved-container").html(
'
' + esc(geGetUiText("search_saved_device", "Search saved on this device.")) + "
"
);
return;
}
$("#ge-saved-container").html(
'
' + esc(geGetUiText("save_search_failed", "Could not save search.")) + "
"
);
}).fail(function () {
$("#ge-saved-container").html(
'
' + esc(geGetUiText("save_search_failed", "Could not save search.")) + "
"
);
});
});
$(document)
.off("click.geSavedSearch touchend.geSavedSearch", ".ge-saved-search")
.on("click.geSavedSearch touchend.geSavedSearch", ".ge-saved-search", function (e) {
e.preventDefault();
if (!geIsLoggedIn()) {
const items = geGuestLoadAll().map(function (it) {
return { name: it.name, filters: it.filters };
});
renderSavedSearches(items);
return;
}
getSavedSearchesRequest()
.done(function (res) {
if (typeof res === "string") {
try { res = JSON.parse(res); } catch (err) { res = {}; }
}
if (!res || !res.success || !Array.isArray(res.data)) {
if (geServerSaysLoginRequired(res)) {
const items = geGuestLoadAll().map(function (it) {
return { name: it.name, filters: it.filters };
});
renderSavedSearches(items);
return;
}
$("#ge-saved-container").html(
'
' + esc(geGetUiText("no_saved_searches", "No saved searches.")) + "
"
);
return;
}
renderSavedSearches(res.data);
})
.fail(function () {
$("#ge-saved-container").html(
'
' + esc(geGetUiText("saved_searches_failed", "Could not load saved searches.")) + "
"
);
});
});
$(document)
.off("click.geRunSaved", ".ge-run-saved, .ge-saved-item")
.on("click.geRunSaved", ".ge-run-saved, .ge-saved-item", function (e) {
e.preventDefault();
const index = parseInt($(this).attr("data-index") || $(this).data("index"), 10);
if (isNaN(index)) return;
function runWithPayload(payload) {
if (payload && typeof payload === "object") {
if (payload.search && typeof payload.search === "object") payload = payload.search;
if (payload.filters && typeof payload.filters === "object") payload = payload.filters;
}
applySearchPayload(payload || {});
state.nearbyMode = false;
state.nearbyStage = 0;
$(".ge-saved-list").remove();
runCombinedSearch();
}
if (!geIsLoggedIn()) {
const all = geGuestLoadAll();
const item = all[index];
if (!item || !item.filters) return;
runWithPayload(item.filters);
return;
}
$.post(geAjaxUrl(), {
action: "ge_run_saved_search",
index: index
}).done(function (res) {
if (!res || !res.success || !res.data || !res.data.filters) return;
runWithPayload(res.data.filters);
});
});
$(document).on("click", ".ge-saved-share", function (e) {
e.preventDefault();
e.stopPropagation();
let payload = {};
try {
payload = JSON.parse(String($(this).attr("data-payload") || "{}"));
} catch (err) {
payload = {};
}
if (payload && typeof payload === "object") {
if (payload.search && typeof payload.search === "object") payload = payload.search;
if (payload.filters && typeof payload.filters === "object") payload = payload.filters;
}
geOpenShareMenu(this, geBuildShareUrl(payload), geGetUiText("share_search_title", "Check out this GloboEvent search"));
});
$(document).on("click", ".ge-share-selected", function (e) {
e.preventDefault();
const $selected = $(".ge-saved-radio:checked").first();
if (!$selected.length) {
alert(geGetUiText("no_searches_selected", "No searches selected."));
return;
}
const index = parseInt($selected.val(), 10);
const $row = $(`.ge-saved-item-row[data-index="${index}"]`);
const $btn = $row.find(".ge-saved-item").first();
let payload = {};
try {
payload = JSON.parse(String($btn.attr("data-payload") || "{}"));
} catch (err) {
payload = {};
}
if (payload && typeof payload === "object") {
if (payload.search && typeof payload.search === "object") payload = payload.search;
if (payload.filters && typeof payload.filters === "object") payload = payload.filters;
}
geOpenShareMenu(
this,
geBuildShareUrl(payload),
geGetUiText("share_selected_title", "Check out this GloboEvent saved search")
);
});
$(document).on("click", ".ge-delete-selected", function (e) {
e.preventDefault();
const $selected = $(".ge-saved-radio:checked").first();
if (!$selected.length) {
alert(geGetUiText("no_searches_selected", "No searches selected."));
return;
}
const selected = [parseInt($selected.val(), 10)];
if (!geIsLoggedIn()) {
const all = geGuestLoadAll();
const keep = all.filter(function (_, idx) {
return selected.indexOf(idx) === -1;
});
geGuestSaveAll(keep);
$(`.ge-saved-item-row[data-index="${selected[0]}"]`).remove();
if (!$(".ge-saved-item-row").length) {
$("#ge-saved-container").html(
'
' + esc(geGetUiText("no_saved_searches", "No saved searches.")) + "
"
);
}
return;
}
$.ajax({
url: geAjaxUrl(),
method: "POST",
dataType: "json",
timeout: 30000,
data: {
action: "ge_delete_saved_searches",
indexes: selected
}
}).done(function (res) {
if (res && res.success) {
$(`.ge-saved-item-row[data-index="${selected[0]}"]`).remove();
if (!$(".ge-saved-item-row").length) {
$("#ge-saved-container").html(
'
' + esc(geGetUiText("no_saved_searches", "No saved searches.")) + "
"
);
}
} else {
alert(geGetUiText("delete_failed", "Delete failed."));
}
}).fail(function () {
alert(geGetUiText("delete_failed", "Delete failed."));
});
});
$(document).on("click", ".ge-delete-all", function (e) {
e.preventDefault();
if (!window.confirm(geGetUiText("delete_all_confirm", "Delete ALL saved searches?"))) return;
if (!geIsLoggedIn()) {
geGuestSaveAll([]);
$("#ge-saved-container").html(
'
' + esc(geGetUiText("no_saved_searches", "No saved searches.")) + "
"
);
return;
}
$.ajax({
url: geAjaxUrl(),
method: "POST",
dataType: "json",
timeout: 30000,
data: {
action: "ge_delete_all_saved_searches"
}
}).done(function (res) {
if (res && res.success) {
$("#ge-saved-container").html(
'
' + esc(geGetUiText("no_saved_searches", "No saved searches.")) + "
"
);
} else {
alert(geGetUiText("delete_failed", "Delete failed."));
}
}).fail(function () {
alert(geGetUiText("delete_failed", "Delete failed."));
});
});
$(document).on("click", ".ge-cat-btn", function (e) {
e.preventDefault();
const $btn = $(this);
const alreadyActive = $btn.hasClass("active");
$(".ge-cat-btn").removeClass("active");
$(".ge-subcategory-group").attr("hidden", true);
if (alreadyActive) {
state.categoryId = 0;
state.categorySlug = "";
state.subcategory = [];
$(".ge-subcat-checkbox").prop("checked", false);
return;
}
$btn.addClass("active");
state.categoryId = parseInt($btn.data("catId") || $btn.data("cat") || 0, 10) || 0;
state.categorySlug = String($btn.data("catSlug") || "").trim();
if (state.categoryId) {
$(`.ge-subcategory-group[data-parent="${state.categoryId}"]`).removeAttr("hidden");
$("#ge-category-modal").removeClass("hidden");
}
});
$(document).on("click", "#ge-advanced-btn", function (e) {
e.preventDefault();
$("#ge-advanced-panel").toggleClass("hidden");
});
$(document).on("click", "#ge-search-btn", function (e) {
e.preventDefault();
state.nearbyMode = false;
state.nearbyStage = 0;
runCombinedSearch();
});
$(document).on("change", "#ge-keyword, #ge-city, #ge-country, #ge-zip", function () {
state.nearbyMode = false;
state.nearbyStage = 0;
});
$(document).on("change", ".ge-subcat-checkbox", function () {
state.nearbyMode = false;
state.nearbyStage = 0;
runCombinedSearch();
});
$(document).on("change", ".ge-audience-checkbox", function () {
syncAudienceFromUi();
filterRenderedByAudience();
});
$(document).on("keydown", "#ge-keyword, #ge-city, #ge-country, #ge-zip", function (e) {
if (e.key === "Enter") {
e.preventDefault();
state.nearbyMode = false;
state.nearbyStage = 0;
runCombinedSearch();
}
});
$(document).on("click", ".ge-today", function (e) {
e.preventDefault();
setToday();
$("#ge-city").val("");
$("#ge-country").val("");
$("#ge-zip").val("");
state.nearbyMode = false;
state.nearbyStage = 0;
runCombinedSearch();
});
$(document).on("click", ".ge-weekend", function (e) {
e.preventDefault();
setWeekend();
$("#ge-city").val("");
$("#ge-country").val("");
$("#ge-zip").val("");
state.nearbyMode = false;
state.nearbyStage = 0;
runCombinedSearch();
});
$(document).on("click", "#ge-reset-all", function (e) {
e.preventDefault();
geResetSearchUi();
runCombinedSearch();
});
$(document).on("click", ".ge-load-more-btn", function (e) {
e.preventDefault();
const type = String($(this).data("type") || "");
if (type !== "events" && type !== "activities") return;
state.page[type] += 1;
if (type === "events") {
if (state.discovery.events.active) {
renderNextDiscoveryEvents();
return;
}
$("#ge-event-pagination").html(loadMoreHtml("events", true));
eventsRequest(getScopedQuery(), state.page.events)
.done(function (res) {
const data = normalizeResponse(res);
renderEventsSection(data, true);
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.error("Load more events failed", {
textStatus: textStatus,
errorThrown: errorThrown,
status: jqXHR && jqXHR.status,
responseText: jqXHR && jqXHR.responseText
});
state.page.events = Math.max(1, state.page.events - 1);
$("#ge-event-pagination").html(loadMoreHtml("events", false));
alert(geGetUiText("events_failed_load_more", "Could not load more events. Please try again."));
});
return;
}
if (state.discovery.activities.active) {
renderNextDiscoveryActivities();
return;
}
$("#ge-activity-pagination").html(loadMoreHtml("activities", true));
activitiesRequest(getScopedQuery(), state.page.activities)
.done(function (res) {
const data = normalizeResponse(res);
renderActivitiesSection(data, true);
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.error("Load more activities failed", {
textStatus: textStatus,
errorThrown: errorThrown,
status: jqXHR && jqXHR.status,
responseText: jqXHR && jqXHR.responseText
});
state.page.activities = Math.max(1, state.page.activities - 1);
$("#ge-activity-pagination").html(loadMoreHtml("activities", false));
alert(geGetUiText("activities_failed_load_more", "Could not load more activities. Please try again."));
});
});
const langSelectEl = document.querySelector("#ge-language-select, .ge-language-select");
if (langSelectEl) {
langSelectEl.addEventListener("change", function (e) {
e.stopImmediatePropagation();
e.stopPropagation();
const chosen = geNormalizeLang(e.target.value);
$.post(geAjaxUrl(), { action: "ge_set_language", lang: chosen })
.done(function (res) {
let confirmed = chosen;
if (res && res.success && res.data && res.data.lang) {
confirmed = geNormalizeLang(res.data.lang);
}
geSetLangRuntime(confirmed);
if (res && res.success && res.data) {
if (res.data.ui) geApplyUiDict(res.data.ui);
else if (res.data.dict && res.data.dict.ui) geApplyUiDict(res.data.dict.ui);
if (res.data.audience) geApplyAudienceDict(res.data.audience);
else if (res.data.dict && res.data.dict.audience) geApplyAudienceDict(res.data.dict.audience);
applyUiLabels();
return;
}
geLoadUiDict(confirmed, function () {
applyUiLabels();
});
})
.fail(function () {
geSetLangRuntime(chosen);
geLoadUiDict(chosen, function () {
applyUiLabels();
});
});
}, true);
}
$(document).on("click", ".ge-event-card a", function () {
const $card = $(this).closest(".ge-event-card");
geSaveCombinedResultsState({
id: String($card.attr("data-id") || $card.data("id") || "").trim(),
url: String($(this).attr("href") || $card.attr("data-url") || $card.data("url") || "").trim()
});
});
function setupMobileAdvancedActions() {
if (window.innerWidth > 768) return;
const $panel = $("#ge-advanced-panel");
if (!$panel.length) return;
let $actions = $panel.find(".ge-advanced-actions");
if (!$actions.length) {
$panel.prepend('
');
$actions = $panel.find(".ge-advanced-actions");
}
const $save = $(".ge-filter-row .ge-save-search").first();
const $saved = $(".ge-filter-row .ge-saved-search").first();
if ($save.length && !$actions.find(".ge-save-search").length) {
$actions.append($save.clone(true, true).css("display", ""));
}
if ($saved.length && !$actions.find(".ge-saved-search").length) {
$actions.append($saved.clone(true, true).css("display", ""));
}
}
setupMobileAdvancedActions();
bindNearby();
bindTabs();
initDatePicker();
geEnsureSavedContainer();
const initialLang = geEnsureLanguage();
const isBack = geIsBackIntent();
let isReload = false;
try {
const nav = performance.getEntriesByType("navigation");
if (nav && nav[0] && nav[0].type === "reload") {
isReload = true;
sessionStorage.removeItem(GE_SS_KEYS.combined);
geResetSearchUi();
}
} catch (e) {}
if (!isReload && isBack && geRestoreCombinedResultsState()) {
geLoadUiDict(initialLang, function () {
applyUiLabels();
geApplyResultButtonsToDom();
});
return;
}
geLoadUiDict(initialLang, function () {
applyUiLabels();
runCombinedSearch();
});
});
https://globoevent.com/post-type-ge_event-sitemap-192.xml
2026-06-16T03:18:25+00:00
https://globoevent.com/post-type-ge_event-sitemap-193.xml
2026-06-16T03:28:16+00:00
https://globoevent.com/post-type-ge_event-sitemap-194.xml
2026-06-16T03:37:37+00:00
https://globoevent.com/post-type-ge_event-sitemap-195.xml
2026-06-16T03:47:25+00:00
https://globoevent.com/post-type-ge_event-sitemap-196.xml
2026-06-16T03:56:38+00:00
https://globoevent.com/post-type-ge_event-sitemap-197.xml
2026-06-16T04:09:35+00:00
https://globoevent.com/post-type-ge_event-sitemap-198.xml
2026-06-16T04:24:40+00:00
https://globoevent.com/post-type-ge_event-sitemap-199.xml
2026-06-16T04:38:44+00:00
https://globoevent.com/post-type-ge_event-sitemap-200.xml
2026-06-16T04:52:38+00:00
https://globoevent.com/post-type-ge_event-sitemap-201.xml
2026-06-16T05:03:51+00:00
https://globoevent.com/post-type-ge_event-sitemap-202.xml
2026-06-16T05:14:08+00:00
https://globoevent.com/post-type-ge_event-sitemap-203.xml
2026-06-16T05:25:45+00:00
https://globoevent.com/post-type-ge_event-sitemap-204.xml
2026-06-16T05:39:17+00:00
https://globoevent.com/post-type-ge_event-sitemap-205.xml
2026-06-16T05:47:58+00:00