const BASE_URL = window.location.origin; window.addEventListener("load", async function () { $.noConflict(); const dropdownKeys = [ { key: "catType", selector: ".resource-type select" }, { key: "catTheme", selector: ".theme select" }, { key: "catRelig", selector: ".religious-content select" }, ]; const sections = [ 'recommended', 'approved', 'all' ]; const screenSections = []; const filteredData = []; const displayedData = []; const totalResultsElement = []; sections.forEach((section) => { screenSections[section] = document.querySelector(`.${section}-section-wrapper`); filteredData[section] = []; displayedData[section] = []; totalResultsElement[section] = document.querySelector(`.${section}-count span`); }); const loadingScreen = document.getElementById("loading-screen"); const itemsPerLoad = 30; // Number of items to load initially and for each "Load More" async function getResourcesData() { const format = "format=json-pretty"; const jsonPath = BASE_URL + "/resources?offset="; accumulatedData = []; let page = 0; let baseUrl = ''; try { offset = 9999999999999; const seenIds = new Set(); while(true) { page += 1; url = jsonPath + offset + "&" + format; console.log("URL: " + url); console.log(`Fetching page ${page}, Services so far: ${accumulatedData.length}`); const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); // save baseUrl to create links for each listing if (page == 1) { baseUrl = data.website.baseUrl; } if (data.items && data.items.length > 0) { for (const item of data.items) { if (!seenIds.has(item.id)) { seenIds.add(item.id); // add base URL to create actual link item.fullUrl = baseUrl + item.fullUrl; accumulatedData.push(item); } } } if (data.pagination && data.pagination.nextPageOffset) { offset = data.pagination.nextPageOffset + 1; } else { break; } } } catch (error) { console.log("Error fetching data: " + error.message); return; } console.log("Finished loading resource listings: " + accumulatedData.length); return accumulatedData; } function extractedData(delimiter, dataArrays) { const combinedData = []; dataArrays.forEach((data) => { if (data.includes(delimiter) && data.split(delimiter)[1].trim() !== "") { combinedData.push(data.split(delimiter)[1].trim()); } }); return [...new Set(combinedData)]; } function sortWithAllFirst(arr, keyword = "All") { if (!arr.includes(keyword)) { arr.push(keyword); } return arr.slice().sort((a, b) => { if (a === keyword) return -1; if (b === keyword) return 1; return a.localeCompare(b); }); } function prepareResourceData(resourcesData) { window.wholeCategories = {}; let catType = [], typeCat = [], catTheme = [], themeCat = [], catRelig = [], religionCat = []; let recommendedData = [], approvedData = [], allData = []; resourcesData.forEach((item) => { catType = extractedData("Typ:", item.categories); catTheme = extractedData("The:", item.categories); catRelig = extractedData("Rel:", item.categories); requiredData = [{ id: item.id, fullUrl: item.fullUrl, title: item.title, excerpt: item.excerpt, featured: item.starred, publishOn: item.publishOn, updatedOn: item.updatedOn, catType: catType, catTheme: catTheme, catRelig: catRelig, body: item.body, }]; typeCat = [...new Set([...typeCat, ...catType])]; themeCat = [...new Set([...themeCat, ...catTheme])]; religionCat = [...new Set([...religionCat, ...catRelig])]; if (item.categories.includes("Level:Recommended")) { recommendedData.push(...requiredData); } else if (item.categories.includes("Level:Approved")) { approvedData.push(...requiredData); } allData.push(...requiredData); }); window.wholeCategories = { catType: sortWithAllFirst(typeCat), catTheme: sortWithAllFirst(themeCat), catRelig: sortWithAllFirst(religionCat), }; console.log(window.wholeCategories); recommendedData.sort((a, b) => a.title.localeCompare(b.title)); approvedData.sort((a, b) => a.title.localeCompare(b.title)); allData.sort((a, b) => a.title.localeCompare(b.title)); window.sectionData = []; window.sectionData['recommended'] = recommendedData; window.sectionData['approved'] = approvedData; window.sectionData['all'] = allData; console.log("Recommended Resources: " + recommendedData.length); console.log("Approved Resources: " + approvedData.length); console.log("All Resources: " + allData.length); } async function initialise() { // Show the loading screen loadingScreen.classList.remove("loading-hidden"); loadingScreen.classList.add("loading-visible"); // load the resources data resources = await getResourcesData(); prepareResourceData(resources); dropdownKeys.forEach((item) => { populateDropdown( document.querySelector(item.selector), window.wholeCategories[item.key] ); initializeSingleSelect(document.querySelector(item.selector), item.key, "All"); }); // Initially display results filterResults(); // hide loading screen loadingScreen.classList.remove("loading-visible"); loadingScreen.classList.add("loading-hidden"); } function populateDropdown(element, options) { try { if (!element) throw new Error("Dropdown element not found"); // Reset dropdown element.innerHTML = ""; // Sort options alphabetically options.forEach((option) => { const optionElement = document.createElement("option"); optionElement.value = option; optionElement.textContent = option; element.appendChild(optionElement); }); } catch (error) { console.error("Error populating dropdown:", error); showError("Error populating dropdown, please check the data."); } } function getQueryParam(name) { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(name); // Returns the value of the parameter } function initializeSingleSelect(element, paramName, defaultValue) { jQuery(element).selectpicker("refresh"); jQuery(element).selectpicker({ noneSelectedText: "Select an option", liveSearch: true, actionsBox: false, }); // Get the GET parameter value const preselectValue = getQueryParam(paramName) || defaultValue; // Default to "ALL" if no parameter is found // Select the preselected or default value if (preselectValue) { jQuery(element).val(preselectValue).selectpicker("refresh"); } } function displayResults(section,data) { cards = ""; // Iterate through filtered data and append to respective sections data.forEach((item) => { const card = `
${stripHtmlAndLimit(item.excerpt, 500) || "" }
No description available.
No description available.
" ); } // display the modal properly jQuery("#descriptionModal").appendTo("body") }); // Ensure modal-backdrop is appended correctly jQuery(document).on("show.bs.modal", function () { jQuery(".modal-backdrop").appendTo("body"); }); // use submit button instead document.getElementById("submit-btn").addEventListener("click", () => { if(filterResults()) { // scroll to different elements depending on mobile or desktop view var element = document.querySelector('#resultsTabs'); if(element && isHidden(element)) { element = document.querySelector('.scroll-implementation'); } if (element) { // Scroll to the element, positioning it near the top window.scrollTo({ top: element.getBoundingClientRect().top + window.scrollY - 20, // 20px offset from the top behavior: 'smooth' // Smooth scrolling animation }); } } }); // Where el is the DOM element you'd like to test for visibility function isHidden(el) { var style = window.getComputedStyle(el); return (style.display === 'none') } function filterResults() { try { const filters = {}; dropdownKeys.forEach(({ key, selector }) => { const selectedValues = getSelectedValues(selector); if (selectedValues !== null) filters[key] = selectedValues; }); var totalCount = 0; sections.forEach((section) => { filteredData[section] = window.sectionData[section].filter((item) => { return Object.entries(filters).every(([key, values]) => { let categoryArray = Array.isArray(item[key]) ? item[key] : item[key] ? [item[key]] : []; // If the item is tagged with "All", always match if (categoryArray.some((cat) => cat.trim().toLowerCase() === "all")) { return true; } // If filter includes "All", allow all items for this key if (values.includes("All")) { return true; } return values.some((value) => categoryArray.some( (cat) => cat.trim().toLowerCase() === value.trim().toLowerCase() ) ); }); }); displayedData[section] = filteredData[section].slice(0, itemsPerLoad); totalCount += filteredData[section].length; displayResults(section,displayedData[section], true); updateTotalResults(section,filteredData[section].length); }) // display "no results" if necessary const noResultsWrapper = document.querySelector(".no-results-wrapper"); if (totalCount === 0) { noResultsWrapper.classList.remove("d-none"); // Hide if count is 0 } else { noResultsWrapper.classList.add("d-none"); // Show if count > 0 } return totalCount > 0; } catch (error) { console.error("Error filtering results:", error); showError("Error filtering results, please try again."); } } function getSelectedValues(selector) { const selectedOptions = Array.from( document.querySelector(selector).selectedOptions ); const values = selectedOptions.map((option) => option.value); return values.length === 0 || values.includes("--") || values[0] === 'ALL' ? null : values; } initialise(); });