let page = "Padliography"; let endpoint = `https://pzwiki.wdka.nl/mw-mediadesign/api.php?action=parse&format=json&origin=*§ion=1&page=${page}&prop=text`; const container = document.getElementById("wiki-contents"); const filtersContainer = document.getElementById("filters-container"); const activeAllButton = document.getElementById("active-all"); // We use a set and not an array in order to avoid repetition let filters = new Set(); // Variables for the filter system let allActive = true; let tagList; // Global variable for the generated table let table; // Request the content to the Wiki API and parse it as a JSON file fetch(endpoint) .then((response) => response.json()) .then((data) => { // Create a new element to insert the response from the wiki and get the table out of it let section = document.createElement("div"); section.innerHTML = data.parse.text["*"]; let wikiTable = section.getElementsByTagName("table")[0]; // Create a new table using the data in the Wiki table createTable(wikiTable); // Fill the filter section with all the tags gathered in the filters Set // We don't need any argument because the filters set is defined as global createFilters(); showAllTags(); }); function createTable(data) { table = document.createElement("table"); // Traverse the rows collection as an array [...data.rows].forEach((row, index) => { // Avoid first row that contains column titles if (index > 0) { // Create a row element let tableRow = document.createElement("tr"); // Create a list of tags from the categories cell let categoryTags = row.cells[3].innerText.split(",").map((category) => category.trim()); // Set the categories as classes for future filtering categoryTags.forEach((tag) => tableRow.classList.add(tag)); // Columns order could be modified simply by reordering the next 4 sections // Create a cell with title + link to the pad let title = document.createElement("td"); title.appendChild(createTitleLink(row)); tableRow.appendChild(title); // Create a cell with the overview let overview = document.createElement("td"); overview.innerHTML = row.cells[2].innerText; tableRow.appendChild(overview); // Create a cell with categories let categories = document.createElement("td"); categories.appendChild(createTags(categoryTags)); tableRow.appendChild(categories); // Create a cell with date let date = document.createElement("td"); date.innerHTML = row.cells[4].innerText; tableRow.appendChild(date); // Insert the row in the table table.appendChild(tableRow); } }); // Insert the table in the container container.appendChild(table); } function createTitleLink(row) { // Take the first cell of the wiki (link) let url = row.cells[0].innerText; // Take the second cell of the wiki (title) let title = row.cells[1].innerText; // Create a link element let link = document.createElement("a"); link.setAttribute("target", "_blank"); // Use the link as href link.href = url; // Use the title as text link.innerHTML = title; return link; } function createTags(categories) { // Create a list to contain all the tags let tagsContainer = document.createElement("ul"); // For each category create a li element categories.forEach((item) => { let tag = document.createElement("li"); tag.classList.add("tag"); tag.innerHTML = item; tagsContainer.appendChild(tag); // add the category to the filters Set to use it later filters.add(item); }); return tagsContainer; } function createFilters() { filters.forEach((item) => { let tag = document.createElement("li"); tag.setAttribute("data-tag", item); tag.setAttribute("tabindex", 0); tag.classList.add("tag"); tag.innerHTML = item; filtersContainer.appendChild(tag); }); tagList = document.querySelectorAll("[data-tag]"); } function conditionalToggle(element) { if (allActive) { tagList.forEach((tag) => { filters.delete(tag.getAttribute("data-tag")); tag.classList.remove("active"); tag.setAttribute("aria-expanded", "false"); }); activeAllButton.classList.remove("active"); allActive = false; } if (element.classList.contains("active")) { element.classList.remove("active"); element.setAttribute("aria-expanded", "false"); filters.delete(element.getAttribute("data-tag")); } else { element.classList.add("active"); element.setAttribute("aria-expanded", "true"); filters.add(element.getAttribute("data-tag")); } allActive = tagList.length == filters.size; if (allActive) { activeAllButton.classList.add("active"); activeAllButton.setAttribute("aria-expanded", "true"); } if (filters.size === 0) { showAllTags(); } } function showSelectedRows() { [...table.rows].forEach((row) => { row.classList.remove("active"); }); filters.forEach((filter) => { let selectedRows = [...table.rows].filter((el) => { filter = filter.replaceAll(" ", "-"); return el.classList.contains(filter); }); selectedRows.forEach((row) => row.classList.add("active")); }); allActiveCheck(); } function showAllTags() { tagList.forEach((tag) => { filters.add(tag.getAttribute("data-tag")); tag.classList.add("active"); tag.setAttribute("aria-expanded", "true"); }); allActive = true; showSelectedRows(); } // TODO: fix active class function allActiveCheck() { if (tagList.length === filters.size) { allActive = true; tagList.forEach((tag) => tag.classList.add("all")); filtersContainer.firstElementChild.classList.add("active"); } else { allActive = false; tagList.forEach((tag) => tag.classList.remove("all")); filtersContainer.firstElementChild.classList.remove("active"); } } // Event Listener filtersContainer.addEventListener("click", (e) => { if (e.target.tagName === "LI") { conditionalToggle(e.target); showSelectedRows(); } }); activeAllButton.addEventListener("click", (e) => { activeAllButton.classList.add("active"); activeAllButton.setAttribute("aria-expanded", "true"); showAllTags(); });