").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();
});
});
404: Page not found - GloboEvent – Your Global Event Search Engine. Find Events Anywhere
Skip to content
It looks like the link pointing here was faulty. Maybe try searching?
Customize Reject All Accept All
✖
Necessary cookies enable essential site features like secure log-ins and consent preference adjustments. They do not store personal data.
None
Functional cookies support features like content sharing on social media, collecting feedback, and enabling third-party tools.
None
Analytical cookies track visitor interactions, providing insights on metrics like visitor count, bounce rate, and traffic sources.
None
Advertisement cookies deliver personalized ads based on your previous visits and analyze the effectiveness of ad campaigns.
None
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
None