PageSourceSearch

https://www.sharjahart.org/assets/js/whats-on-list.js?v=2.3

js sharjahart.org collected 2026-09-24 17:58:43 UTC 17,820 bytes, 552 lines download raw bytes

1$(function () {
2  const $drpWhatsOn = $(".drpWhatsOn");
3
4  if ($drpWhatsOn.length) {
5    dayjs.extend(window.dayjs_plugin_customParseFormat);
6
7    function initializeDateRangePicker() {
8      // Detect if the device is mobile
9      const isMobile = window.innerWidth <= 768; // Adjust this width as needed for mobile detection
10
11      // To set the minimum date to be today
12      const today = dayjs().subtract(1, "day").toDate();
13
14      // Check if the HTML direction is RTL
15      const isRtl = $("html").attr("dir") === "rtl";
16
17      const optionsDrpWhatsOn = {
18        locale:  isRtl ? "ar-AE" : "en-US", // Set locale based on direction
19        minDate: today,
20        startName: "startDate",
21        endName: "endDate",
22        weekdayFormat: isRtl? "short" : 3,
23        inputReadOnly: true,
24        placeholder: isRtl? "من , إلى" : "From, To",
25        showAdjacementDays: false,
26        calendars: isMobile ? 1 : 2, // Set calendars to 1 for mobile, 2 otherwise
27        inputDateFormat: (date) =>
28          dayjs(date).locale("en").format("DD-MMM-YYYY"),
29        inputDateParse: (date) => dayjs(date, "DD-MMM-YYYY", "en").toDate(),
30      };
31
32      // Initialize the Date Range Picker with the updated options
33      new coreui.DateRangePicker($drpWhatsOn[0], optionsDrpWhatsOn);
34    }
35
36    // Initialize Date Range Picker on page load
37    initializeDateRangePicker();
38  }
39
40  // Helper function to get base URL up to /list/
41  function getBaseUrl() {
42    var currentUrl = window.location.href;
43    if (currentUrl.indexOf('/list/') === -1) {
44      currentUrl = currentUrl.replace('/whats-on/', '/whats-on/list/');
45    }
46    return currentUrl.split("/list/")[0] + "/list/";
47  }
48
49  // Helper function to parse current filters from URL
50  function getCurrentFilters() {
51    var currentUrl = window.location.href;
52    var filters = {
53      eventType: null,
54      location: null,
55      learnType: null,
56      ageRange: null,
57      lang: null,
58      date: null
59    };
60
61    // Check if we have the new filter structure
62    if (currentUrl.indexOf("/filter/") !== -1) {
63      var filterPart = currentUrl.split("/filter/")[1];
64      if (filterPart) {
65        var filterValue = filterPart.split("/")[0];
66        if (filterValue && filterValue !== "all") {
67          // Store the combined filter string - we'll parse individual values from DOM
68          filters.combined = filterValue;
69        }
70      }
71    }
72
73    // Check for date
74    if (currentUrl.indexOf("/date/") !== -1) {
75      var datePart = currentUrl.split("/date/")[1];
76      if (datePart) {
77        var dateValue = datePart.split("/")[0];
78        if (dateValue) {
79          filters.date = dateValue;
80        }
81      }
82    }
83
84    return filters;
85  }
86
87  // Helper function to get all selected filter IDs from dropdowns
88  function getSelectedFilterIds() {
89    var ids = [];
90
91    // Event type
92    var eventTypeVal = $("#event-type").val();
93    if (eventTypeVal && eventTypeVal !== "all") {
94      ids.push(eventTypeVal);
95    }
96
97    // Location
98    var locationVal = $("#venue-city").val();
99    if (locationVal && locationVal !== "all") {
100      ids.push(locationVal);
101    }
102
103    // Learning filters (only if learning is selected)
104    if (eventTypeVal === $("#event-type option[data-learning='true']").val() ||
105        $(".learning-filters-row").hasClass("d-flex")) {
106      // Learn type
107      var learnTypeVal = $("#learn-type").val();
108      if (learnTypeVal && learnTypeVal !== "all") {
109        ids.push(learnTypeVal);
110      }
111
112      // Age range
113      var ageRangeVal = $("#age-range").val();
114      if (ageRangeVal && ageRangeVal !== "all") {
115        ids.push(ageRangeVal);
116      }
117
118      // Language
119      var langVal = $("#lang-filter").val();
120      if (langVal && langVal !== "all") {
121        ids.push(langVal);
122      }
123    }
124
125    return ids;
126  }
127
128  // Helper function to build URL from filter IDs and date
129  function buildFilterUrl(filterIds, dateValue) {
130    var baseUrl = getBaseUrl();
131    var url = baseUrl;
132
133    // Add filter segment - use '&' as separator (URL encoded as-is since it's in the path)
134    if (filterIds.length > 0) {
135      url += "filter/" + filterIds.join("&") + "/";
136    } else {
137      url += "filter/all/";
138    }
139
140    // Add date segment only if date is selected
141    if (dateValue && dateValue !== "all") {
142      url += "date/" + dateValue + "/";
143    }
144
145    return url;
146  }
147
148  // Helper function to update URL with current filter state
149  function updateFiltersUrl(changedFilter, newValue) {
150    var filterIds = [];
151    var dateValue = null;
152
153    // Get current date from URL
154    var currentFilters = getCurrentFilters();
155    dateValue = currentFilters.date;
156
157    // Event type
158    var eventTypeVal = changedFilter === "event-type" ? newValue : $("#event-type").val();
159    if (eventTypeVal && eventTypeVal !== "all") {
160      filterIds.push(eventTypeVal);
161    }
162
163    // Location
164    var locationVal = changedFilter === "venue-city" ? newValue : $("#venue-city").val();
165    if (locationVal && locationVal !== "all") {
166      filterIds.push(locationVal);
167    }
168
169    // Check if learning event type is selected (category ID for learning)
170    var learningCatId = $("#event-type option:contains('Learning')").val() ||
171                        $("#event-type").find("option").filter(function() {
172                          return $(this).text().toLowerCase().indexOf("learning") !== -1 ||
173                                 $(this).text().toLowerCase().indexOf("تعلم") !== -1;
174                        }).val();
175
176    var isLearning = eventTypeVal === learningCatId;
177
178    // Learning filters (only if learning is selected)
179    if (isLearning) {
180      // Learn type
181      var learnTypeVal = changedFilter === "learn-type" ? newValue : $("#learn-type").val();
182      if (learnTypeVal && learnTypeVal !== "all") {
183        filterIds.push(learnTypeVal);
184      }
185
186      // Age range
187      var ageRangeVal = changedFilter === "age-range" ? newValue : $("#age-range").val();
188      if (ageRangeVal && ageRangeVal !== "all") {
189        filterIds.push(ageRangeVal);
190      }
191
192      // Language
193      var langVal = changedFilter === "lang-filter" ? newValue : $("#lang-filter").val();
194      if (langVal && langVal !== "all") {
195        filterIds.push(langVal);
196      }
197    }
198
199    return buildFilterUrl(filterIds, dateValue);
200  }
201
202  // Filter the entries based on the selected Event Type
203  $("#event-type").on("change", function () {
204    var selectedOption = $(this).find(":selected").val();
205    var newUrl = updateFiltersUrl("event-type", selectedOption);
206    window.location.href = newUrl;
207  });
208
209  // Filter the entries based on the selected Location
210  $("#venue-city").on("change", function () {
211    var selectedOption = $(this).find(":selected").val();
212    var newUrl = updateFiltersUrl("venue-city", selectedOption);
213    window.location.href = newUrl;
214  });
215
216  // Filter the entries based on the selected Learning Type
217  $("#learn-type").on("change", function () {
218    var selectedOption = $(this).find(":selected").val();
219    var newUrl = updateFiltersUrl("learn-type", selectedOption);
220    window.location.href = newUrl;
221  });
222
223  // Filter the entries based on the selected Age Range
224  $("#age-range").on("change", function () {
225    var selectedOption = $(this).find(":selected").val();
226    var newUrl = updateFiltersUrl("age-range", selectedOption);
227    window.location.href = newUrl;
228  });
229
230  // Filter the entries based on the selected Language
231  $("#lang-filter").on("change", function () {
232    var selectedOption = $(this).find(":selected").val();
233    var newUrl = updateFiltersUrl("lang-filter", selectedOption);
234    window.location.href = newUrl;
235  });
236
237  $drpWhatsOn.on("endDateChange.coreui.date-range-picker", function () {
238    var startDate = $('input[name="startDate"]').val();
239    var endDate = $('input[name="endDate"]').val();
240
241    if (startDate === null || startDate === "" || endDate === null || endDate === "") {
242      // Date range cleared - remove date from URL
243      var filterIds = getSelectedFilterIds();
244      var newUrl = buildFilterUrl(filterIds, null);
245      window.location.href = newUrl;
246    } else {
247      var daterange = startDate + "--" + endDate;
248
249      // Convert to Unix timestamps
250      var dateArray = daterange.split("--");
251      var fromDate = dateArray[0];
252      var toDate = new Date(dateArray[1]);
253
254      // Round toDate to the last minute of the day
255      toDate.setHours(23, 59, 59);
256
257      // Convert to Unix timestamps (seconds)
258      var fromUnixTimestamp = Math.floor(new Date(fromDate).getTime() / 1000);
259      var toUnixTimestamp = Math.floor(toDate.getTime() / 1000);
260      var dateRangeUnixTimestamp = fromUnixTimestamp + "--" + toUnixTimestamp;
261
262      // Build URL with current filters and new date
263      var filterIds = getSelectedFilterIds();
264      var newUrl = buildFilterUrl(filterIds, dateRangeUnixTimestamp);
265      window.location.href = newUrl;
266    }
267  });
268
269  // Function to convert the Unix Timestamp to normal date format
270  function unixTimestampToDate(unixTimestamp) {
271    // Convert Unix timestamp to milliseconds
272    var milliseconds = unixTimestamp * 1000;
273
274    // Create a new Date object using the milliseconds
275    var dateObject = new Date(milliseconds);
276
277    // Get the day, month, and year from the date object
278    var day = dateObject.getDate();
279    var monthIndex = dateObject.getMonth();
280    var year = dateObject.getFullYear();
281
282    // Array of month names
283    var monthNames = [
284      "Jan",
285      "Feb",
286      "Mar",
287      "Apr",
288      "May",
289      "Jun",
290      "Jul",
291      "Aug",
292      "Sep",
293      "Oct",
294      "Nov",
295      "Dec",
296    ];
297
298    // Get the month name using the month index
299    var monthName = monthNames[monthIndex];
300
301    // Format the date string as 'DD-MMM-YYYY'
302    var formattedDate = day + "-" + monthName + "-" + year;
303
304    // Return the formatted date string
305    return formattedDate;
306  }
307
308  // Function to fill the daterangepicker input with the date range in the URL
309  function fillDateRange() {
310    var currentUrl = window.location.href;
311
312    if (currentUrl.indexOf("/date/") !== -1) {
313      var dateSegment = currentUrl.split("/date/")[1];
314      if (dateSegment) {
315        dateSegment = dateSegment.split("/")[0];
316        if (dateSegment && dateSegment !== "all" && dateSegment.indexOf("--") !== -1) {
317          var unixTimestampFrom = dateSegment.split("--")[0];
318          var unixTimestampTo = dateSegment.split("--")[1];
319          var formattedDateFrom = unixTimestampToDate(unixTimestampFrom);
320          var formattedDateTo = unixTimestampToDate(unixTimestampTo);
321          $('input[name="datefilter"]').val(
322            formattedDateFrom + "--" + formattedDateTo
323          );
324          $('input[name="startDate"]').val(formattedDateFrom);
325          $('input[name="endDate"]').val(formattedDateTo);
326        }
327      }
328    }
329  }
330
331  // Initiate the fillDateRange Function
332  fillDateRange();
333
334  // Function to show/hide learning filters row based on event-type selection
335  function updateLearningFiltersVisibility() {
336    var eventTypeVal = $("#event-type").val();
337
338    // Find the learning category ID by checking the option text
339    var learningCatId = $("#event-type").find("option").filter(function() {
340      return $(this).text().toLowerCase().indexOf("learning") !== -1 ||
341             $(this).text().toLowerCase().indexOf("تعلم") !== -1;
342    }).val();
343
344    var $learningRow = $(".learning-filters-row");
345
346    if (eventTypeVal === learningCatId) {
347      $learningRow.removeClass("d-none").addClass("d-flex");
348    } else {
349      $learningRow.removeClass("d-flex").addClass("d-none");
350      // Reset learning filter values when hiding
351      $("#learn-type").val("all");
352      $("#age-range").val("all");
353      $("#lang-filter").val("all");
354    }
355  }
356
357  // Initialize learning filters visibility on page load
358  updateLearningFiltersVisibility();
359
360  // ==========================================
361  // Filter Badges Functionality
362  // ==========================================
363
364  // Helper function to create badge HTML
365  function createBadgeHtml(text, filterId, filterType) {
366    return '<div class="filter-badge" data-filter-id="' + filterId + '" data-filter-type="' + filterType + '">' +
367      '<span class="badge-text">
367' + text + '</span>' +
368      '<span class="badge-remove">' +
369        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor">' +
370          '<line x1="18" y1="6" x2="6" y2="18"></line>' +
371          '<line x1="6" y1="6" x2="18" y2="18"></line>' +
372        '</svg>' +
373      '</span>' +
374    '</div>';
375  }
376
377  // Helper function to remove a filter ID from the combined filter string
378  function removeFilterId(combinedFilters, filterIdToRemove) {
379    if (!combinedFilters || combinedFilters === "all") return "";
380
381    var filterIds = combinedFilters.split("&");
382    var newFilterIds = filterIds.filter(function(id) {
383      return id !== filterIdToRemove;
384    });
385
386    return newFilterIds.join("&");
387  }
388
389  // Function to populate filter badges
390  function populateFilterBadges() {
391    var $badgesContainer = $("#filterBadges");
392    if (!$badgesContainer.length) return;
393
394    $badgesContainer.empty();
395
396    var currentFilters = getCurrentFilters();
397
398    // Add category filter badges
399    if (currentFilters.combined) {
400      var filterIds = currentFilters.combined.split("&");
401
402      filterIds.forEach(function(filterId) {
403        // Find the corresponding option text from dropdowns
404        var $option = null;
405        var filterType = "";
406
407        // Check event-type dropdown
408        $option = $("#event-type option[value='" + filterId + "']");
409        if ($option.length) {
410          filterType = "event-type";
411        }
412
413        // Check venue-city dropdown
414        if (!$option.length || !$option.val()) {
415          $option = $("#venue-city option[value='" + filterId + "']");
416          if ($option.length && $option.val()) {
417            filterType = "venue-city";
418          }
419        }
420
421        // Check learn-type dropdown
422        if (!filterType) {
423          $option = $("#learn-type option[value='" + filterId + "']");
424          if ($option.length && $option.val()) {
425            filterType = "learn-type";
426          }
427        }
428
429        // Check age-range dropdown
430        if (!filterType) {
431          $option = $("#age-range option[value='" + filterId + "']");
432          if ($option.length && $option.val()) {
433            filterType = "age-range";
434          }
435        }
436
437        // Check lang-filter dropdown
438        if (!filterType) {
439          $option = $("#lang-filter option[value='" + filterId + "']");
440          if ($option.length && $option.val()) {
441            filterType = "lang-filter";
442          }
443        }
444
445        if ($option && $option.length && filterType) {
446          var badgeText = $option.text().trim();
447          $badgesContainer.append(createBadgeHtml(badgeText, filterId, filterType));
448        }
449      });
450    }
451
452    // Add date badge if date filter is active
453    if (currentFilters.date && currentFilters.date.indexOf("--") !== -1) {
454      var dateParts = currentFilters.date.split("--");
455      var fromDate = unixTimestampToDate(dateParts[0]);
456      var toDate = unixTimestampToDate(dateParts[1]);
457      var dateText = fromDate + " - " + toDate;
458      $badgesContainer.append(createBadgeHtml(dateText, currentFilters.date, "date"));
459    }
460  }
461
462  // Handle badge removal click
463  $(document).on("click", ".filter-badge", function() {
464    var $badge = $(this);
465    var filterId = $badge.data("filter-id");
466    var filterType = $badge.data("filter-type");
467
468    var currentFilters = getCurrentFilters();
469    var newFilterIds = [];
470    var newDateValue = currentFilters.date;
471
472    if (filterType === "date") {
473      // Remove date filter
474      newDateValue = null;
475      // Keep existing category filters
476      if (currentFilters.combined) {
477        newFilterIds = currentFilters.combined.split("&");
478      }
479    } else {
480      // Remove category filter
481      if (currentFilters.combined) {
482        var remainingFilters = removeFilterId(currentFilters.combined, String(filterId));
483        if (remainingFilters) {
484          newFilterIds = remainingFilters.split("&");
485        }
486      }
487    }
488
489    // Build new URL and navigate
490    var newUrl = buildFilterUrl(newFilterIds, newDateValue);
491    window.location.href = newUrl;
492  });
493
494  // Initialize badges on page load
495  populateFilterBadges();
496});
497
498$(document).ready(function () {
499  var itemsPerPage = 8;
500  var loadedItems = itemsPerPage;
501  var isLoading = false;
502
503  // Check if the url has already a sorting or filters applied
504  var currentUrl = window.location.href;
505  var partUrl = currentUrl.split("/list/")[1];
506
507  // Check the current language used
508  var lang;
509  if (currentUrl.indexOf("/ar/") === -1) {
510    lang = "/en";
511  } else {
512    lang = "/ar";
513  }
514
515  function loadMoreItems() {
516    if (isLoading) return;
517    isLoading = true;
518
519    // Simulate loading from server (replace this with actual loading mechanism)
520    $.ajax({
521      url: lang + "/AJAX/whats-on-load-more/" + loadedItems + "/" + partUrl,
522      type: "GET",
523      //data: {offset: loadedItems},
524      success: function (response) {
525        // Append loaded items to the list
526        $("#whatsOnList").append(response);
527
528        // Update loaded items count
529        loadedItems += itemsPerPage;
530
531        isLoading = false;
532      },
533      error: function () {
534        isLoading = false;
535      },
536    });
537  }
538
539  // Load initial items
540  //loadMoreItems();
541
542  // Detect scrolling to the bottom of the page
543  $(window).scroll(function () {
544    // Calculate 90% of the document height
545    var limitHeight = $(document).height() * 0.70;
546
547    // Check if scrollTop position is greater than or equal to 90% of the document height minus window height
548    if ($(window).scrollTop() >= limitHeight - $(window).height()) {
549      loadMoreItems();
550    }
551  });
552});

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