_pageDriverVersion = "1.0.1"; // Handle color for icon svg with id="logo" based on the current theme const logo = document.getElementById("logo"); if(logo) { logo.style.fill = getComputedStyle(document.documentElement).getPropertyValue("--bulma-text"); } if(_wrapperVersion === undefined) { console.error("API Wrapper not found; Please include the API Wrapper before including the Page Driver"); exit(); } else { console.log("API Wrapper found; Page Driver is ready to use"); } // Find all tables on the page which have data-dataSource attribute var tables = document.querySelectorAll("table[data-dataSource]"); //var tables = [] // Get all single values with data-dataSource, data-dataCol and data-dataAction var singleValues = document.querySelectorAll("span[data-dataSource]"); // Find all search fields with data-searchTargetId var searchFields = document.querySelectorAll("input[data-searchTargetId]"); // Find all modalForms var modalForms = document.querySelectorAll("form[data-targetTable]"); // Iterate over all tables tables.forEach(async table => { console.log("Table found: ", table); // Get THEAD and TBODY elements const thead = table.querySelector("thead"); const tbody = table.querySelector("tbody"); // get index per column const columns = thead.querySelectorAll("th"); const columnIndices = []; columns.forEach((column, index) => { columnIndices[column.getAttribute("data-dataCol")] = index; }); // All required cols let requiredCols = []; columns.forEach(column => { requiredCols.push(column.getAttribute("data-dataCol")); }); console.log("Required columns: ", requiredCols); // Get data from API //let result = getRowsByTableAndColumnList(table.getAttribute("data-dataSource"), requiredCols); let result = await returnTableDataByTableName(table.getAttribute("data-dataSource")) // for (resultIndex in result) { // const row = result[resultIndex]; // const tr = document.createElement("tr"); // requiredCols.forEach(column => { // const td = document.createElement("td"); // td.innerHTML = row[column]; // tr.appendChild(td); // }); // tbody.appendChild(tr); // } writeDataToTable(table, result); console.log("Column indices: ", columnIndices); }); console.info("Processing single values"); console.info(singleValues); // Iterate over all single values singleValues.forEach(async singleValue => { writeSingelton(singleValue); }); async function writeSingelton(element) { const table = element.getAttribute("data-dataSource"); console.log("Table: ", table, " Action: ", element.getAttribute("data-dataAction"), " Element: ", element); switch(element.getAttribute("data-dataAction")) { case "COUNT": { console.log("Count action found"); element.innerHTML = (await getCountByTable(table)) break; } case "SPECIAL": { if(table == "version") { element.innerHTML = (await getServerVersion())["version"]; break } } default: { console.error("Unknown action found: ", element.getAttribute("data-dataAction")); break; } } element.classList.remove("is-skeleton"); } // Attach listeners to search fields searchFields.forEach(searchField => { searchField.addEventListener("input", async function() { console.log("Search field changed: ", searchField); const targetId = searchField.getAttribute("data-searchTargetId"); const target = document.getElementById(targetId); const table = target.getAttribute("data-dataSource"); const column = target.getAttribute("data-dataCol"); const value = searchField.value; console.log("Searching for ", value, " in ", table, " column ", column); const result = await returnTableDataByTableNameWithSearch(table, value); console.log("Result: ", result); clearTable(target); writeDataToTable(target, result); }); }); // Attach listeners to modal forms modalForms.forEach(modalForm => { modalForm.addEventListener("submit", async function(event) { event.preventDefault(); // Check what button submitted the form and if it has data-actionBtn = save // If not, close modal const pressedBtn = event.submitter; if(pressedBtn.getAttribute("data-actionBtn") != "save") { modalForm.closest(".modal").classList.remove('is-active'); return; } // Find .entryPhase and hide it const entryPhase = modalForm.querySelector(".entryPhase"); const loadPhase = modalForm.querySelector(".loadPhase"); if(entryPhase) { entryPhase.classList.add("is-hidden"); } if(loadPhase) { loadPhase.classList.remove("is-hidden"); } console.log("Form submitted: ", modalForm); const table = modalForm.getAttribute("data-targetTable"); const data = new FormData(modalForm); // Convert to JSON object let jsonData = {}; data.forEach((value, key) => { jsonData[key] = value; }); console.log("JSON Data: ", jsonData); let resp = await createEntry(table, jsonData); console.log("Response: ", resp); if(resp["status"] == "CREATED") { console.log("Entry created successfully"); modalForm.closest(".modal").classList.remove('is-active'); modalForm.reset(); // Hide loadPhase if(loadPhase) { loadPhase.classList.add("is-hidden"); } // Show entryPhase if(entryPhase) { entryPhase.classList.remove("is-hidden"); } } else { // Hide loadPhase if(loadPhase) { loadPhase.classList.add("is-hidden"); } // Show entryPhase if(entryPhase) { entryPhase.classList.remove("is-hidden"); } // TODO: Show error message } // const target = document.getElementById(table); // writeDataToTable(target, result); // Find all tables with data-searchTargetId set to table setTimeout(() => { refreshTableByName(table); updateSingeltonsByTableName(table); }, 500); }); }); // Helper async function refreshTable(table) { // Refresh a table while keeping (optionally set) search value const searchField = document.querySelector("input[data-searchTargetId='" + table.id + "']"); if(searchField) { const value = searchField.value; const dbTable = table.getAttribute("data-dataSource"); const result = await returnTableDataByTableNameWithSearch(dbTable, value); clearTable(table); writeDataToTable(table, result); } else { const result = await returnTableDataByTableName(table.getAttribute("data-dataSource")); clearTable(table); writeDataToTable(table, result); } } async function refreshTableByName(name) { const dirtyTables = document.querySelectorAll("table[data-dataSource='" + name + "']"); for(dirty of dirtyTables) { refreshTable(dirty); } } async function updateSingeltonsByTableName(name) { const dirtySingles = document.querySelectorAll("span[data-dataSource='" + name + "']"); for(dirty of dirtySingles) { writeSingelton(dirty); } } function clearTable(table) { const tbody = table.querySelector("tbody"); tbody.innerHTML = ""; } function writeDataToTable(table, data) { console.log("Writing data to table: ", table, data); // Get THEAD and TBODY elements const thead = table.querySelector("thead"); const tbody = table.querySelector("tbody"); // get index per column const columns = thead.querySelectorAll("th"); const columnIndices = []; columns.forEach((column, index) => { columnIndices[column.getAttribute("data-dataCol")] = index; }); // All required cols let requiredCols = []; columns.forEach(column => { requiredCols.push(column.getAttribute("data-dataCol")); }); for (resultIndex in data) { const row = data[resultIndex]; const tr = document.createElement("tr"); requiredCols.forEach(column => { const td = document.createElement("td"); td.innerHTML = row[column]; tr.appendChild(td); }); tbody.appendChild(tr); } } // Handle modal document.addEventListener('DOMContentLoaded', () => { // Functions to open and close a modal function openModal($el) { $el.classList.add('is-active'); } function closeModal($el) { $el.classList.remove('is-active'); } function closeAllModals() { (document.querySelectorAll('.modal') || []).forEach(($modal) => { closeModal($modal); }); } // Add a click event on buttons to open a specific modal (document.querySelectorAll('.js-modal-trigger') || []).forEach(($trigger) => { const modal = $trigger.dataset.target; const $target = document.getElementById(modal); $trigger.addEventListener('click', () => { openModal($target); }); }); // Add a click event on various child elements to close the parent modal (document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button') || []).forEach(($close) => { const $target = $close.closest('.modal'); $close.addEventListener('click', () => { closeModal($target); }); }); // Add a keyboard event to close all modals document.addEventListener('keydown', (event) => { if(event.key === "Escape") { closeAllModals(); } }); });