htmx.defineExtension('disable-submit', { onEvent: function (name, evt, data) { /* let elt = evt.detail.elt; let result = elt.querySelectorAll('.hx-disable'); if (name === 'htmx:beforeRequest') { result.forEach(element => element.disabled = true); if (elt.classList.contains('hx-disable')) { elt.disabled = true;} } else if(name == 'htmx:afterRequest') { result.forEach(element => element.disabled = false); if (elt.classList.contains('hx-disable')) elt.disabled = false; } */ } }) htmx.defineExtension('rename-params', { onEvent: function(name , evt) { if (name === "htmx:configRequest") { var normal = evt.detail.elt.getAttribute("hx-rename-params"); if (normal) { normal = JSON.parse(normal); for (const [key, value] of Object.entries(normal)) { console.log(evt.detail.parameters) evt.detail.parameters[value] = evt.detail.parameters[key]; delete evt.detail.parameters[key]; } } var exclusive = evt.detail.elt.getAttribute("hx-rename-params-ex"); if (exclusive) { exclusive = JSON.parse(exclusive); var params = {}; for (const [key, value] of Object.entries(exclusive)) { var v = evt.detail.parameters[key] if (v) { params[value] = v; } } evt.detail.parameters = params; } } } }); htmx.defineExtension('reactive-trigger', { onEvent: function(name , evt) { if (name === "htmx:beforeProcessNode") { var element = evt.detail.elt; var reactiveTrigger = element.getAttribute("hx-reactive-trigger"); if (reactiveTrigger) { reactiveTrigger = JSON.parse(reactiveTrigger); var reactiveSource = element.getAttribute("hx-reactive-source"); reactiveSource = reactiveSource ? document.querySelector(reactiveSource) : element.closest("form"); // var triggerString = Object.keys(reactiveTrigger).map(k => "change from:#" + reactiveSource.getAttribute("id") + " [name=\"" + k + "\"]").join(", "); var triggerString = reactiveTrigger.map(k => "change from:" + "[name=\"" + k + "\"]").join(", "); element.setAttribute("hx-trigger", triggerString); } } else if (name=="htmx:configRequest") { var element = evt.detail.elt; var reactiveTrigger = element.getAttribute("hx-reactive-trigger"); if (reactiveTrigger) { reactiveTrigger = JSON.parse(reactiveTrigger); var reactiveSource = element.getAttribute("hx-reactive-source"); reactiveSource = reactiveSource ? document.querySelector(reactiveSource) : element.closest("form"); for (key of reactiveTrigger) { console.log( reactiveSource.querySelector(`[name="${key}"]`).value) evt.detail.parameters[key] = reactiveSource.querySelector(`[name="${key}"]`).value || ""; } } } } }); function deepEqual(obj1, obj2) { if (obj1 === obj2) { return true; // Check for equality } if (typeof obj1 !== 'object' || typeof obj2 !== 'object' || obj1 === null || obj2 === null) { return false; // Check if both are objects } const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) { return false; // Check if they have the same number of properties } for (const key of keys1) { if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) { return false; // Recursively compare properties } } return true; // Objects are deeply equal } htmx.defineExtension('trigger-filter', { onEvent: function(name , evt) { if (name=="htmx:beforeRequest") { var element = evt.detail.elt; console.log("HEREEE", element.lastParams, evt.detail.requestConfig.parameters) if (!deepEqual(element.lastParams, evt.detail.requestConfig.parameters)) { element.lastParams = evt.detail.requestConfig.parameters; } else { console.log("unchanged") evt.preventDefault(); } } } }); initDatepicker = function(elem) { const modalParent = elem.closest('#modal-content'); if (modalParent) { elem.dp = new Datepicker(elem, {format: "mm/dd/yyyy", autohide: true, container: "#modal-content .modal-card"}); } else { elem.dp = new Datepicker(elem, {format: "mm/dd/yyyy", autohide: true}); } } countRows = function(id) { var table = document.querySelector(id); var rows = table.querySelectorAll("tbody tr"); return rows.length; } htmx.onLoad(function(content) { var sortables = content.querySelectorAll(".sortable"); for (var i = 0; i < sortables.length; i++) { var sortable = sortables[i]; var sortableInstance = new Sortable(sortable, { animation: 150, ghostClass: 'bg-blue-100', // Make the `.htmx-indicator` unsortable filter: ".htmx-indicator", onMove: function (evt) { return evt.related.className.indexOf('htmx-indicator') === -1; }, // Disable sorting on the `end` event onEnd: function (evt) { this.option("disabled", true); } }); // Re-enable sorting on the `htmx:afterSwap` event sortable.addEventListener("htmx:afterSwap", function() { sortableInstance.option("disabled", false); }); } }) async function copyToClipboard(text) { try { // Write the text to the clipboard await navigator.clipboard.writeText(text); console.log('Text copied to clipboard:', text); } catch (err) { console.error('Failed to copy text to clipboard:', err); } }