UNPKG

vanillajs-datatable

Version:

A lightweight, dependency-free, and theme-friendly DataTable alternative to jQuery DataTables built with modern JavaScript — works great with Tailwind CSS, DaisyUI, and Bootstrap.

1 lines 75.2 kB
var VanillaJsDatatable=function(e,t){"use strict";const n={INIT:"init",SORT:"sort",FILTER:"filter",PAGE_CHANGE:"pageChange",LOADING:"loading",LOADED:"loaded",ERROR:"error",SEARCH:"search",PER_PAGE_CHANGE:"perPageChange",RESET:"reset",RELOAD:"reload",STATE_RESTORED:"stateRestored",SELECTION_CHANGED:"selectionChanged",ROW_SELECTED:"rowSelected",ROW_DESELECTED:"rowDeselected",ALL_SELECTED:"allSelected",ALL_DESELECTED:"allDeselected",ROW_ACTIVATE:"rowActivate"},i={daisyui:{controlsContainer:"border-base-300 border-b border-dashed",controlsWrapper:"flex flex-wrap items-center justify-between gap-4 p-4",controlsLeft:"flex items-center gap-2",buttonGroup:"flex items-center gap-2",perPageSelect:"select select-sm select-bordered",searchWrapper:"relative w-full max-w-xs",searchIcon:"absolute left-3 top-1/2 transform -translate-y-1/2",searchInput:"input input-bordered w-full pl-10",button:"btn btn-sm btn-outline",table:"table w-full border border-base-200 rounded-xl overflow-hidden shadow-sm",header:"bg-base-200 text-base-content",headerCell:"px-4 py-3 text-sm font-semibold tracking-wide text-left",headerSticky:"sticky top-0 z-10 bg-base-100 shadow-md",groupHeaderRow:"column-group-headers bg-base-300 text-base-content font-semibold text-center",groupHeaderCell:"",filterRow:"bg-base-200 column-filters",filterInput:"input input-sm input-bordered w-full column-search",body:"bg-base-100 divide-y divide-base-200",row:"hover:bg-base-200 transition-colors duration-200",cell:"px-4 py-3 text-sm text-base-content",highlight:"bg-yellow-200 text-black font-semibold rounded-sm px-1",paginationContainer:"flex justify-between items-center px-4 py-2 border-t border-gray-300 bg-base-200 text-base-content rounded-b-lg",paginationInfo:"text-sm text-gray-600",paginationWrapper:"join gap-1 mt-2",paginationButton:"btn btn-sm",paginationButtonActive:"btn-primary",paginationButtonDisabled:"opacity-50 cursor-not-allowed",paginationEllipsis:"px-2 text-gray-500",advancedFilterToggle:"px-4 py-3 flex justify-between items-center cursor-pointer bg-base-200 text-sm font-medium gap-2 hover:bg-base-300 transition-colors duration-200",advancedFilterArrow:"transition-transform duration-300 text-base-content",advancedFilterRow:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 py-0 px-2 bg-base-100 rounded-box transition-all duration-500 max-h-0 opacity-0 overflow-hidden",advancedFilterDiv:"form-control",advancedFilterLabel:"label-text text-sm mb-1",advancedFilterInputs:"flex gap-2",advancedFilterInput:"input input-sm input-bordered w-full",advancedFilterButtonContainer:"flex items-center justify-start mt-5",advancedFilterButton:"btn btn-primary btn-sm w-40 h-10",scrollWrapperClass:"overflow-y-auto",scrollLoaderClass:"text-center py-2 text-sm text-base-content",editableInput:"input input-bordered input-sm w-full",editableSelect:"select select-bordered select-sm w-full",borderSuccess:"border-success",borderError:"border-error",borderLoading:"border-warning"},tailwind:{controlsContainer:"border-b border-dashed border-gray-300 bg-white dark:bg-gray-900 dark:border-gray-700",controlsWrapper:"flex flex-wrap items-center justify-between gap-4 p-4",controlsLeft:"flex flex-col sm:flex-row flex-wrap items-start sm:items-center gap-2",buttonGroup:"flex flex-wrap items-center gap-2",perPageSelect:"text-sm border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-white rounded-md px-3 py-1.5 focus:ring focus:ring-primary",searchWrapper:"relative w-full max-w-xs",searchIcon:"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 dark:text-gray-500",searchInput:"w-full pl-10 pr-3 py-2 text-sm border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-primary",button:"cursor-pointer rounded-md flex items-center gap-1 text-sm px-3 py-1.5 border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 active:bg-gray-200 transition shadow-sm",table:"min-w-full table-auto border border-gray-300 dark:border-gray-700 rounded-lg overflow-hidden",header:"bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-white",headerCell:"px-4 py-3 text-sm font-medium text-left tracking-wide whitespace-nowrap",headerSticky:"sticky top-0 z-10 bg-white dark:bg-gray-900 shadow",groupHeaderRow:"bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-100 font-semibold text-center",groupHeaderCell:"",filterRow:"bg-gray-50 dark:bg-gray-800 column-filters",filterInput:"w-full pl-3 pr-3 py-2 text-sm border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-primary",body:"bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700",row:"hover:bg-blue-50 dark:hover:bg-gray-700 hover:shadow-sm transition-colors duration-150",cell:"px-4 py-3 text-sm text-gray-800 dark:text-gray-100 whitespace-nowrap",highlight:"bg-yellow-200 dark:bg-yellow-500 text-black dark:text-gray-900 font-semibold rounded px-1",paginationContainer:"flex flex-col sm:flex-row justify-between sm:items-center items-start px-4 py-3 border-t border-gray-300 dark:border-gray-700 bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-100 rounded-b-lg",paginationInfo:"text-sm text-gray-600 dark:text-gray-400",paginationWrapper:"flex gap-1 mt-2",paginationButton:"px-3 py-1.5 text-sm border rounded hover:bg-gray-200 dark:hover:bg-gray-700 transition cursor-pointer border-gray-300 dark:border-gray-600 text-gray-800 dark:text-white",paginationButtonActive:"bg-blue-600 text-white border-blue-600 cursor-pointer",paginationButtonDisabled:"opacity-50 cursor-not-allowed",paginationEllipsis:"px-2 text-gray-500 dark:text-gray-400 cursor-default",advancedFilterToggle:"px-4 py-3 flex justify-between items-center cursor-pointer bg-gray-200 dark:bg-gray-900 text-sm font-medium gap-2 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200",advancedFilterArrow:"transform transition-transform duration-300 text-gray-600 dark:text-white",advancedFilterRow:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 py-0 px-2 bg-gray-100 dark:bg-gray-900 rounded-lg transition-all duration-500 max-h-0 opacity-0 overflow-hidden",advancedFilterDiv:"flex flex-col items-start",advancedFilterLabel:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1",advancedFilterInputs:"flex gap-2",advancedFilterInput:"w-full pl-3 pr-3 py-2 text-sm border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-white rounded-md focus:outline-none focus:ring-2 focus:ring-primary placeholder:font-normal",advancedFilterButtonContainer:"flex items-center justify-start mt-5",advancedFilterButton:"w-40 h-10 cursor-pointer px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md",scrollWrapperClass:"overflow-y-auto",scrollLoaderClass:"text-center py-2 text-sm text-gray-500",editableInput:"border px-2 py-1 w-full rounded focus:outline-none focus:ring-2 focus:ring-primary",editableSelect:"border px-2 py-1 w-full rounded focus:outline-none focus:ring-2 focus:ring-primary",borderSuccess:"border-green-500",borderError:"border-red-500",borderLoading:"border-yellow-500"},bootstrap:{controlsContainer:"py-3 border-bottom px-3",controlsWrapper:"d-flex flex-wrap justify-content-between align-items-center gap-3",controlsLeft:"d-flex flex-wrap align-items-center gap-3",buttonGroup:"btn-group flex-wrap gap-2",perPageSelect:"form-select form-select-sm w-auto",searchWrapper:"position-relative w-md-auto",searchIcon:"position-absolute top-50 start-0 translate-middle-y ps-3 text-muted",searchInput:"form-control form-control-sm ps-5 rounded p-2",button:"btn btn-outline-secondary btn-sm d-inline-flex align-items-center gap-1 rounded",table:"table table-striped table-hover align-middle mb-0 border",header:"",headerCell:"text-nowrap",headerSticky:"sticky-top bg-body-tertiary z-1 shadow-sm",groupHeaderRow:"bg-secondary text-white text-center fw-bold",groupHeaderCell:"",filterRow:"bg-body-secondary column-filters",filterInput:"form-control form-control-sm column-search",body:"",row:"align-middle",cell:"text-nowrap",highlight:"bg-warning text-dark fw-semibold px-1 rounded",paginationContainer:"d-flex flex-column flex-md-row justify-content-between align-items-center gap-2 pt-3 mt-3 border-top px-3",paginationInfo:"text-muted small mb-0",paginationWrapper:"btn-group flex-wrap gap-2",paginationButton:"btn btn-sm btn-outline-secondary rounded",paginationButtonActive:"page-item active",paginationButtonDisabled:"disabled",paginationEllipsis:"px-2 text-muted",advancedFilterToggle:"cursor-pointer d-flex justify-content-between align-items-center px-3 py-3 cursor-pointer bg-body-secondary fw-medium hover-bg-secondary-subtle transition",advancedFilterArrow:"transition-transform duration-300",advancedFilterRow:"row gy-3 gx-2 py-3 px-3 bg-body-tertiary rounded shadow-sm",advancedFilterDiv:"col-12 col-md-6 col-lg-4 d-flex flex-column",advancedFilterLabel:"form-label mb-1 fw-medium text-body",advancedFilterInputs:"d-flex gap-2",advancedFilterInput:"form-control form-control-sm",advancedFilterButtonContainer:"px-3 mt-4 d-flex justify-content-start",advancedFilterButton:"btn btn-primary btn-sm px-4 py-2 fw-semibold",scrollWrapperClass:"overflow-y-auto",scrollLoaderClass:"text-center py-2 small text-muted",editableInput:"form-control",editableSelect:"form-select",borderSuccess:"border-success",borderError:"border-danger",borderLoading:"border-warning"}};class a{constructor(e,t={}){this.table=e,this.selectable=t.selectable||!1,this.selectMode=t.selectMode||"single",this.selectedRows=new Set,this.selectionClass=t.selectionClass||"selected",this.selectionBgClass=t.selectionBgClass||"bg-red-100",this.baseTheme=t.baseTheme||"tailwind",this.theme=i[this.baseTheme],this.selectable&&this._initializeSelection()}_initializeSelection(){this.table.addEventListener("click",e=>{const t=e.target.closest("tr");t&&t.dataset.id&&this._handleRowSelection(t)}),this._addSelectionStyles()}_handleRowSelection(e){e.dataset.id;const t=e.classList.contains(this.selectionClass);"single"===this.selectMode&&this._clearAllSelections(),t?this._deselectRow(e):this._selectRow(e)}_selectRow(e){const t=e.dataset.id,n=e.dataset.zebra;n&&e.classList.remove(n),e.classList.add(...this.selectionClass.split(" "),this.selectionBgClass),"bootstrap"===this.baseTheme&&e.querySelectorAll("td").forEach(e=>{e.classList.add(this.selectionBgClass||"bg-primary","text-white")}),this.selectedRows.add(t)}_deselectRow(e){const t=e.dataset.id,n=e.dataset.zebra,i=[...this.selectionClass.split(" "),this.selectionBgClass];e.classList.remove(...i),n&&e.classList.add(n),"bootstrap"===this.baseTheme&&e.querySelectorAll("td").forEach(e=>{e.classList.remove(this.selectionBgClass||"bg-primary","text-white")}),"tailwind"===this.baseTheme&&i.forEach(t=>e.classList.remove(t)),this.selectedRows.delete(t)}_clearAllSelections(){this.table.querySelectorAll(`tr.${this.selectionClass}`).forEach(e=>{this._deselectRow(e)});this.table.querySelectorAll(`tr.${this.selectionClass}`).forEach(e=>{this._deselectRow(e)})}_addSelectionStyles(){if(!document.getElementById("selectable-table-styles")){const e=document.createElement("style");e.id="selectable-table-styles",e.textContent=`\n tr.${this.selectionClass} {\n cursor: pointer;\n transition: background-color 0.2s ease;\n }\n `,document.head.appendChild(e)}}_updateRowVisualState(e,t){t?(e.classList.add(this.selectionClass,this.selectionBgClass),e.dataset.zebra&&e.classList.remove(e.dataset.zebra)):(e.classList.remove(this.selectionClass,this.selectionBgClass),e.dataset.zebra&&e.classList.add(e.dataset.zebra))}isSelected(e){return this.selectedRows.has(e)}onSelectionChange(e){this.table.addEventListener("click",t=>{const n=t.target.closest("tr");n&&n.dataset.id&&e(this.getSelectedIds())})}getSelectedIds(){return Array.from(this.selectedRows)}clearSelection(){this.getSelectedIds(),this._clearAllSelections()}selectAll(){if("single"===this.selectMode)return;this.table.querySelectorAll("tr[data-id]").forEach(e=>{this._selectRow(e)})}toggleRowSelection(e,t){const n=this.table.querySelector(`tr[data-id="${e}"]`);if(!n)return!1;const i=this.selectedRows.has(e),a=void 0!==t?t:!i;return a===i?i:(a?("single"===this.selectMode&&this._clearAllSelections(),this._selectRow(n)):this._deselectRow(n),a)}getSelectedRows(){return Array.from(this.table.querySelectorAll(`tr.${this.selectionClass}`))}getSelectedData(){return this.getSelectedRows().map(e=>JSON.parse(e.dataset.row||"{}"))}getSelectedCount(){return this.selectedRows.size}setSelection(e=[]){return this.clearSelection(),e.forEach(e=>this.toggleRowSelection(e,!0)),this.selectedRows.size}invertSelection(){if("single"===this.selectMode){const e=this.table.querySelector("tr[data-id]");if(!e)return;return void this.toggleRowSelection(e.dataset.id)}Array.from(this.table.querySelectorAll("tbody tr[data-id]")).forEach(e=>{const t=e.dataset.id,n=!this.isSelected(t);n?this.selectedRows.add(t):this.selectedRows.delete(t),n?this._selectRow(e):this._deselectRow(e)})}selectRange(e,t){if("single"===this.selectMode)return;const n=Array.from(this.table.querySelectorAll("tr[data-id]")),i=n.findIndex(t=>t.dataset.id===e),a=n.findIndex(e=>e.dataset.id===t);if(-1===i||-1===a)return;const[r,s]=i<a?[i,a]:[a,i];for(let e=r;e<=s;e++)this.toggleRowSelection(n[e].dataset.id,!0)}setSelectable(e=!0){this.selectable=Boolean(e)}setSelectMode(e){if(["single","multiple"].includes(e)&&(this.selectMode=e,"single"===e&&this.selectedRows.size>1)){const e=this.getSelectedIds()[0];this.clearSelection(),this.toggleRowSelection(e,!0)}}destroy(){this.clearSelection(),this.table.removeEventListener("click",this._boundClickHandler)}}class r{constructor(e,{selectable:t,getData:n,enabled:i=!0,main:a}){this.table=e,this.selectable=t,this.getData=n,this.enabled=i,this.lastSelectedRow=null,this._boundKeyHandler=this.handleKeyDown.bind(this),this.main=a,this.enabled&&this.init()}init(){return document.addEventListener("keydown",this._boundKeyHandler),this}destroy(){document.removeEventListener("keydown",this._boundKeyHandler),this.lastSelectedRow=null}handleKeyDown(e){if(this.enabled&&!this._shouldIgnoreKeyEvent(e)){switch(e.key){case"ArrowUp":e.preventDefault(),this.navigateRow(-1);break;case"ArrowDown":e.preventDefault(),this.navigateRow(1);break;case"ArrowLeft":e.preventDefault(),this._navigatePage(-1);break;case"ArrowRight":e.preventDefault(),this._navigatePage(1);break;case"Home":e.preventDefault(),e.ctrlKey?this._goToFirstPage():this._goToFirstRow();break;case"Enter":e.preventDefault(),this.openSelectedRow();break;case"Escape":e.preventDefault(),this.selectable.clearSelection()}if(e.ctrlKey||e.metaKey)switch(e.key.toLowerCase()){case"p":e.preventDefault(),this._triggerPrint();break;case"s":e.preventDefault(),this._triggerSearch();break;case"e":e.preventDefault(),this._triggerExport("excel");break;case"c":e.preventDefault(),this._triggerExport("csv");break;case"d":e.preventDefault(),this._triggerExport("pdf");break;case"r":e.preventDefault(),this.reloadData();break;case"f":e.preventDefault(),this._focusSearchInput();break;case"z":e.preventDefault(),this._triggerReset()}if(!e.ctrlKey&&!e.metaKey&&!e.altKey)switch(e.key){case"/":e.preventDefault(),this._focusSearchInput();break;case"a":"multiple"===this.selectable.selectMode&&(e.preventDefault(),this.selectable.selectAll());break;case" ":e.preventDefault(),this._toggleRowSelection()}}}navigateRow(e){const t=this._getVisibleRows();if(0===t.length)return;const n=this._getCurrentRowIndex(t),i=Math.max(0,Math.min(n+e,t.length-1));n!==i&&("single"===this.selectable.selectMode&&this.lastSelectedRow&&this.selectable.toggleRowSelection(this.lastSelectedRow.dataset.id,!1),this._selectRow(t[i]))}openSelectedRow(){const e=this.selectable.getSelectedIds();0!==e.length&&this.table.dispatchEvent(new CustomEvent(`datatable:${n.ROW_ACTIVATE}`,{detail:{rowId:e[0],rowData:this.getData().find(t=>t.id===e[0]),timestamp:(new Date).toISOString()},bubbles:!0}))}_shouldIgnoreKeyEvent(e){return["INPUT","TEXTAREA","SELECT"].includes(document.activeElement.tagName)||e.ctrlKey&&"c"===e.key.toLowerCase()||e.altKey}_getVisibleRows(){return Array.from(this.table.querySelectorAll("tbody tr[data-id]"))}_getCurrentRowIndex(e){if(this.lastSelectedRow)return e.indexOf(this.lastSelectedRow);const t=this.selectable.getSelectedIds();return t.length>0?(this.lastSelectedRow=this.table.querySelector(`tr[data-id="${t[0]}"]`),e.indexOf(this.lastSelectedRow)):-1}_selectRow(e){this.selectable.toggleRowSelection(e.dataset.id,!0),this.lastSelectedRow=e,this._scrollRowIntoView(e),this.table.dispatchEvent(new CustomEvent(`datatable:${n.ROW_ACTIVATE}`,{detail:{rowId:e.dataset.id,rowData:this.getData().find(t=>t.id===e.dataset.id),timestamp:(new Date).toISOString()},bubbles:!0}))}_scrollRowIntoView(e){e.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"})}_focusSearchInput(){const e=document.getElementById(`${this.table.id}-search-input`)||this.table.querySelector(".datatable-search-input")||document.querySelector("input[data-datatable-search]");return e?(e.focus(),e.select(),!0):(console.warn("Search input not found for table:",this.table.id),!1)}_toggleRowSelection(){const e=this._getVisibleRows();if(0===e.length)return;const t=this._getCurrentRowIndex(e);if(t>=0){const n=e[t],i=this.selectable.getSelectedIds().includes(n.dataset.id);this.selectable.toggleRowSelection(n.dataset.id,!i)}}_goToFirstRow(){const e=this._getVisibleRows();e.length>0&&this._selectRow(e[0])}_goToLastRow(){const e=this._getVisibleRows();e.length>0&&this._selectRow(e[e.length-1])}_goToFirstPage(){this.main?.goToFirstPage&&this.main.goToFirstPage()}_triggerSearch(){this._focusSearchInput()}_triggerExport(e){if(!this.main||!this.main.buttonConfig)return;const t=this.main.buttonConfig;"csv"===e&&!1!==t.downloadCsv?.enabled?this.main.downloadCSV():"pdf"===e&&!1!==t.downloadPdf?.enabled?this.main.downloadPdf():"excel"===e&&!1!==t.exportExcel?.enabled?this.main.exportToExcel():console.warn(`Export format "${e}" is disabled or unsupported.`)}_triggerPrint(){this.main.printTable&&!1!==this.main.buttonConfig?.print?.enabled&&this.main.printTable()}_triggerReset(){this.main.resetTable&&!1!==this.main.buttonConfig?.reset?.enabled&&this.main.resetTable()}reloadData(){this.main.fetchData()}}function s(){return[...this.data]}function o(e){return this.data.find(t=>t.id===e)||null}function l(e){return this.data.findIndex(t=>t.id===e)}function d(e,t){return this.data.filter(n=>n[e]===t)}function c(e,t){const n=String(t).toLowerCase();return this.data.filter(t=>String(t[e]??"").toLowerCase().includes(n))}function h(e,t=!1,n=!1){return e.id?this.getRowData(e.id)?(console.warn(`Row with id ${e.id} already exists`),!1):(n?this.data.unshift(e):this.data.push(e),t||this._renderTable(),!0):(console.warn("Each row must have a unique `id`."),!1)}function p(e,t=!1){if(!Array.isArray(e))throw new TypeError("addRows expects an array");const n=e.map(e=>this.addRow(e,!0,!1));return t||this._renderTable(),n}function g(e,t){const n=this.data.findIndex(t=>t.id===e);return-1!==n&&(this.data[n]={...this.data[n],...t},this._renderTable(),!0)}function u(e,t=!1){const n=[];return e.forEach(({id:e,...t})=>{const i=this.updateRow(e,t,!0);i&&n.push(i)}),!t&&n.length&&this._renderTable(),n}function b(e){const t=this.data.findIndex(t=>t.id===e);return-1!==t&&(this.data.splice(t,1),this._renderTable(),!0)}function m(e,t=!1){Array.isArray(e)||(e=[e]);const n=[];return e.forEach(e=>{const t=this.deleteRow(e,!0);t&&n.push(t)}),!t&&n.length&&this._renderTable(),n}function f(e){if(!e||"function"!=typeof e._renderTable)throw new Error("redraw(): _renderTable method not found on instance");e._renderTable()}function w(){f(this)}function x(){f(this)}function y(e,t="table-data.json"){!function(e,t="data.json"){const n=JSON.stringify(e,null,2),i=new Blob([n],{type:"application/json"}),a=URL.createObjectURL(i),r=document.createElement("a");r.href=a,r.download=t,r.click(),setTimeout(()=>URL.revokeObjectURL(a),1e3)}(e,t)}function v(e,t="asc"){if(!["asc","desc"].includes(t))return void console.warn(`Invalid sort direction "${t}" - must be "asc" or "desc"`);this.columns.some(t=>t.data===e||t.name===e)?(this.sort=e,this.order=t,this.fetchData()):console.warn(`Invalid column "${e}" - not found in column definition`)}function S(){this.sort="",this.order="",this.fetchData()}function E(e="csv"){const t=this.data;if(!t||0===t.length)return void alert("No data to copy.");const n=this.columns.filter(e=>!1!==e.visible&&"actions"!==e.name).map(e=>e.label||e.name),i=t.map(t=>this.columns.filter(e=>!1!==e.visible&&"actions"!==e.name).map(e=>t[e.name]??"").join("csv"===e?",":"\t")),a=[n.join("csv"===e?",":"\t"),...i].join("\n");navigator.clipboard.writeText(a).then(()=>{console.log("Table data copied to clipboard")}).catch(e=>{console.error("Failed to copy data:",e)})}function C(e){const t=parseInt(e,10);isNaN(t)||t<1||this.totalPages&&t>this.totalPages?console.warn(`Invalid page number: ${e}`):(this.currentPage=t,this.fetchData())}function P(e){const t=parseInt(e,10);isNaN(t)||t<=0?console.warn(`Invalid page size: ${e}`):(this.rowsPerPage=t,this.currentPage=1,this.fetchData())}function k(){return this.currentPage}function R(){return this.goToPage(this.currentPage+1)}function L(){return this.goToPage(this.currentPage-1)}function T(){return this.goToPage(1)}function I(){if(this.totalPages&&!(this.totalPages<1))return this.goToPage(this.totalPages);console.warn("Cannot go to last page: totalPages is not defined")}return class{constructor({data:e,tableId:t,url:n,perPage:f=10,perPageOptions:D=[10,25,50],defaultSort:F="id",defaultOrder:$="asc",columns:N=[],dataSrc:B=null,saveState:_=!1,keyboardNav:A=!1,searchInputId:O=null,prevBtnId:H=null,nextBtnId:M=null,pageInfoId:j=null,infoTextId:W=null,paginationWrapperId:z=null,perPageSelectId:q=null,resetBtnId:G=null,reloadBtnId:V=null,exportBtnId:U=null,downloadCsvBtnId:K=null,printBtnId:X=null,pdfBtnId:J=null,paginationType:Y="detailed",sortable:Z=!0,sortableColumns:Q=[],searchDelay:ee=300,reset:te=!0,reload:ne=!0,perPageSelector:ie=!0,searchable:ae=!0,pagination:re=!0,filterableColumns:se=null,columnGroups:oe=[],stickyHeader:le=!1,columnFiltering:de=!1,saveStateDuration:ce=36e5,theme:he={},baseTheme:pe="tailwind",rangeFilterFields:ge={},filters:ue={},loading:be={show:!1,elementId:null,delay:1e3},selection:me={enabled:!1,mode:"single",rowClass:"row-selected",backgroundClass:"bg-blue-100"},infiniteScroll:fe={enabled:!1,scrollOffset:10,hidePaginationOnScroll:!0,maxScrollPages:1e3,scrollWrapperHeight:"80vh"},exportable:we={enabled:!0,buttons:{print:!0,excel:!0,csv:!0,pdf:!0},title:{print:"Printable Report",pdf:"PDF Export",excel:"Excel Export",csv:"CSV Export"},chunkSize:{print:50,pdf:50,excel:50,csv:50},pdfOptions:{orientation:"portrait",unit:"mm",format:"a4",theme:"grid",watermark:{text:null,opacity:.1,angle:45}},fileName:{print:"print_report",pdf:"pdf_export",excel:"excel_export",csv:"csv_export"},footer:!0}}){const xe={enabled:!1!==fe?.enabled,scrollOffset:fe?.scrollOffset,hidePaginationOnScroll:fe?.hidePaginationOnScroll,maxScrollPages:fe?.maxScrollPages,scrollWrapperHeight:fe?.scrollWrapperHeight};this.infiniteScroll=xe.enabled,this.scrollOffset=xe.scrollOffset,this.hidePaginationOnScroll=xe.hidePaginationOnScroll,this.maxScrollPages=xe.maxScrollPages,this.scrollWrapperHeight=xe.scrollWrapperHeight,this.rangeFilterFields=ge,this.filters=ue;const ye=i[pe]||i.daisyui;this.theme={...ye,...he,framework:pe.includes("bootstrap")?"bootstrap":pe.includes("daisyui")?"daisyui":"tailwind"},this.data=[],this.tableId=t,this.table=document.getElementById(t),this.url=n,this.rowsPerPage=f,this.perPageOptions=D,this.sort=F,this.order=$,this.search="",this.currentPage=1,this.dataSrc=B||"data",this.enableSaveState=_,this.saveStateDuration=ce,this.updatePagination=this.updatePagination.bind(this),this.paginationType=Y,this.sortable=Z,this.pagination=re,this.sortableColumns=Array.isArray(Q)?Q:[],this.searchDelay=ee,this.columnFilters={},this.columns=N,this.searchDebounceTimer=null;const ve={show:!1!==be?.show,elementId:be?.elementId,delay:be?.delay};this.enableLoadingSpinner=ve.show,this.LoadingSpinnerContainer=ve.elementId||`${t}-loading-spinner`,this.loadingDelay=ve.delay,this.columnGroups=oe||[],this.stickyHeader=le,this.columnFiltering=de,this.filters=ue,this.exportable={enabled:!1!==we.enabled,buttons:{print:!1!==we.buttons?.print,excel:!1!==we.buttons?.excel,csv:!1!==we.buttons?.csv,pdf:!0===we.buttons?.pdf,...we.buttons},title:{print:we.title?.print||"Printable Report",pdf:we.title?.pdf||"PDF Export",excel:we.title?.excel||"Excel Export",csv:we.title?.csv||"Csv Export",...we.title},chunkSize:{print:we.chunkSize?.print||100,pdf:we.chunkSize?.pdf||100,excel:we.chunkSize?.excel||100,csv:we.chunkSize?.csv||100,...we.chunkSize},fileName:{print:we.fileName?.print||"report",pdf:we.fileName?.pdf||"pdf_export",excel:we.fileName?.excel||"excel_export",csv:we.fileName?.csv||"csv_export",...we.fileName},watermark:{text:we.pdfOptions.watermark?.text||"Company Confidential",opacity:we.pdfOptions.watermark?.opacity||.1,angle:we.pdfOptions.watermark?.angle||45,...we.pdfOptions.watermark},pdfOptions:{orientation:we.pdfOptions?.orientation||"portrait",unit:we.pdfOptions?.unit||"mm",format:we.pdfOptions?.format||"a4",theme:we.pdfOptions?.theme||"grid",...we.pdfOptions},footer:!1!==we.footer},this.chunkSize=this.exportable.chunkSize,this.buttonConfig={reset:{id:G||`${t}-reset-button`,enabled:te,icon:'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-ccw-icon lucide-rotate-ccw"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>',text:"Reset"},reload:{id:V||`${t}-reload-button`,enabled:ne,icon:'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-ccw-icon lucide-refresh-ccw"><path d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/><path d="M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16"/><path d="M16 16h5v5"/></svg>',text:"Reload"},print:{id:X||`${t}-print-button`,enabled:this.exportable.enabled&&this.exportable.buttons.print,icon:'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-printer-check-icon lucide-printer-check"><path d="M13.5 22H7a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v.5"/><path d="m16 19 2 2 4-4"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v2"/><path d="M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6"/></svg>',text:"Print"},export:{id:U||`${t}-export-button`,enabled:this.exportable.enabled&&this.exportable.buttons.excel,icon:'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-squares-exclude-icon lucide-squares-exclude"><path d="M16 12v2a2 2 0 0 1-2 2H9a1 1 0 0 0-1 1v3a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2h0"/><path d="M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3a1 1 0 0 1-1 1h-5a2 2 0 0 0-2 2v2"/></svg>',text:"Excel"},downloadCsv:{id:K||`${t}-download-csv-button`,enabled:this.exportable.enabled&&this.exportable.buttons.csv,icon:'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-check2-icon lucide-file-check-2"><path d="M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="m3 15 2 2 4-4"/></svg>',text:"CSV"},pdf:{id:J||`${t}-download-pdf-button`,enabled:this.exportable.enabled&&this.exportable.buttons.pdf,icon:'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text-icon lucide-file-text"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/></svg>',text:"PDF"},perPageSelect:{id:q||`${t}-per-page`,enabled:ie,text:"Perpage"},search:{id:O||`${t}-search-input`,enabled:ae,icon:'<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search-icon lucide-search"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>',text:"Search"}},this.paginationConfig={previous:{id:H||`${t}-prev-button`,text:"Previous"},next:{id:M||`${t}-next-button`,text:"Next"},pageInfo:{id:j||`${t}-page-info`,text:"Page Info"},infoText:{id:W||`${t}-info-text`,text:"Entries Info"},wrapper:{id:z||`${t}-pagination`,text:"Pagination Controls Wrapper"}},this.filterableColumns=se;const Se={selectable:!1!==me?.enabled,selectMode:me?.mode||"single",selectionClass:me?.rowClass||"row-selected",selectionBgClass:me?.backgroundClass||"bg-blue-100"};this.keyboardNav&&(this.keyboardNav.destroy(),this.keyboardNav=null),!1!==A&&(this.keyboardNav=new r(this.table,{selectable:this.selectable,selectionClass:this.selectionClass,selectionBgClass:this.selectionBgClass,getData:()=>this.data,enabled:A,main:this})),this.copyToClipboard=E.bind(this),this.exportJSON=()=>{y(this.data)},this.downloadSelectedJSON=()=>{const e=this.getSelectedIds();if(0===e.length)return void console.error("Please select at least one row to export.");y(this.data.filter(t=>e.includes(String(t.id))))},this.getData=s.bind(this),this.getRowData=o.bind(this),this.getRowIndex=l.bind(this),this.getRowsBy=d.bind(this),this.findRowsByFieldContains=c.bind(this),this.addRow=h.bind(this),this.addRows=p.bind(this),this.updateRow=g.bind(this),this.updateRows=u.bind(this),this.deleteRow=b.bind(this),this.deleteRows=m.bind(this),this.redraw=w.bind(this),this.draw=x.bind(this),this.setSort=v.bind(this),this.clearSort=S.bind(this),this.goToPage=C.bind(this),this.setPageSize=P.bind(this),this.getCurrentPage=k.bind(this),this.nextPage=R.bind(this),this.prevPage=L.bind(this),this.firstPage=T.bind(this),this.lastPage=I.bind(this),this.selectable=new a(this.table,{selectable:Se.selectable,selectMode:Se.selectMode,selectionClass:Se.selectionClass,selectionBgClass:Se.selectionBgClass,baseTheme:pe}),this.getSelectedIds=()=>this.selectable.getSelectedIds(),this.clearSelection=()=>this.selectable.clearSelection(),this.selectAll=()=>this.selectable.selectAll(),this.toggleRowSelection=(e,t)=>this.selectable.toggleRowSelection(e,t),this.isSelected=e=>this.selectable.isSelected(e),this.onSelectionChange=e=>this.selectable.onSelectionChange(e),this.getSelectedRows=()=>this.selectable.getSelectedRows(),this.getSelectedData=()=>this.selectable.getSelectedData(),this.getSelectedCount=()=>this.selectable.getSelectedCount(),this.setSelection=e=>this.selectable.setSelection(e),this.invertSelection=()=>this.selectable.invertSelection(),this.selectRange=(e,t)=>this.selectable.selectRange(e,t),this.setSelectable=e=>this.selectable.setSelectable(e),this.setSelectMode=e=>this.selectable.setSelectMode(e),this.destroySelectable=()=>this.selectable.destroy(),this.init()}init(){this.saveState&&this.loadState(),this.enableLoadingSpinner&&this.toggleLoadingSpinner(!0),this.addDefaultControls(),this.initButtons(),this.initSearch(),this.fetchData(),this.initPagination(),this.initInfiniteScroll(),this.renderTableHeader(),this.dispatchEvent(n.INIT,{config:{url:this.url,columns:this.columns,features:{sorting:this.sortable,pagination:this.pagination,search:this.search}}})}dispatchEvent(e,t={}){if(!this.table)return console.warn(`Cannot dispatch datatable:${e} - table element not found`),!1;const n=new CustomEvent(`datatable:${e}`,{detail:{...t,tableId:this.table.id,timestamp:(new Date).toISOString()},bubbles:!0,cancelable:!0});return this.table.dispatchEvent(n)}saveState(){if(!this.table||!this.table.id)return;const e={sort:this.sort,order:this.order,page:this.currentPage,perPage:this.rowsPerPage,filters:this.columnFilters,search:this.search};localStorage.setItem(`datatable_${this.table.id}_state`,JSON.stringify(e))}loadState(){const e=localStorage.getItem(`datatable_${this.table.id}_state`);if(!e)return;const t=JSON.parse(e);this.saveStateDuration&&Date.now()-t.timestamp>this.saveStateDuration?this.clearState():(this.dispatchEvent(n.STATE_RESTORED,{state:t}),this.sort=t.sort,this.order=t.order,this.currentPage=t.page,this.rowsPerPage=t.perPage,this.columnFilters=t.filters||{},this.search=t.search||"")}clearState(){this.table&&this.table.id&&localStorage.removeItem(`datatable_${this.table.id}_state`)}initButtons(){this.buttonConfig.reset.enabled&&this.bindResetButton(),this.buttonConfig.reload.enabled&&this.bindReloadButton(),this.exportable.enabled&&this.buttonConfig.print.enabled&&this.bindPrintButton(),this.exportable.enabled&&this.buttonConfig.export.enabled&&this.bindExportButton(),this.exportable.enabled&&this.buttonConfig.downloadCsv.enabled&&this.bindDownloadCsvButton(),this.exportable.enabled&&this.buttonConfig.pdf.enabled&&this.bindPdfButton(),this.buttonConfig.perPageSelect.enabled&&this.bindPerPageSelect()}initPagination(){this.pagination&&(this.paginationConfig={previous:{id:`${this.tableId}-prev-button`,text:"Previous"},next:{id:`${this.tableId}-next-button`,text:"Next"},pageInfo:{id:`${this.tableId}-page-info`,text:"Page Info"},infoText:{id:`${this.tableId}-info-text`,text:"Showing X to Y of Z entries"},wrapper:{id:`${this.tableId}-pagination`},container:{id:`${this.tableId}-pagination-container`}},this.prevBtn=this.getOrCreateElement(this.paginationConfig.previous.id,"button",this.theme.paginationButton+" join-item",this.paginationConfig.previous.text),this.nextBtn=this.getOrCreateElement(this.paginationConfig.next.id,"button",this.theme.paginationButton+" join-item",this.paginationConfig.next.text),this.pageInfo=this.getOrCreateElement(this.paginationConfig.pageInfo.id,"span",this.theme.paginationInfo,""),this.infoText=this.getOrCreateElement(this.paginationConfig.infoText.id,"div",this.theme.paginationInfo,""),this.paginationWrapper=document.getElementById(this.paginationConfig.wrapper.id),this.paginationWrapper||(this.paginationWrapper=document.createElement("div"),this.paginationWrapper.id=this.paginationConfig.wrapper.id,this.paginationWrapper.className=this.theme.paginationWrapper),this.paginationContainer=document.getElementById(this.paginationConfig.container.id),this.paginationContainer||(this.paginationContainer=document.createElement("div"),this.paginationContainer.id=this.paginationConfig.container.id,this.paginationContainer.className=this.theme.paginationContainer,this.paginationContainer.appendChild(this.infoText),this.paginationContainer.appendChild(this.paginationWrapper),this.table.parentNode.appendChild(this.paginationContainer)),this.paginationWrapper.contains(this.prevBtn)||this.paginationWrapper.appendChild(this.prevBtn),this.paginationWrapper.contains(this.nextBtn)||this.paginationWrapper.appendChild(this.nextBtn),this.bindPaginationButtons())}getOrCreateElement(e,t,n,i){let a=document.getElementById(e);return a||(a=document.createElement(t),a.id=e,a.className=n,i&&(a.textContent=i)),a}addDefaultControls(){const e=document.createElement("div");e.className=this.theme.controlsContainer||"";let t="",n="",i="";for(const[e,a]of Object.entries(this.buttonConfig))if(a.enabled&&!document.getElementById(a.id))if("perPageSelect"===e){const e=this.perPageOptions.map(e=>`<option value="${e}" ${this.rowsPerPage==e?"selected":""}>${e}</option>`).join("");t=`\n <select id="${a.id}" class="${this.theme.perPageSelect}" title="${a.text}">\n ${e}\n </select>\n `}else"search"===e?i=`\n <div class="${this.theme.searchWrapper}">\n <span class="${this.theme.searchIcon}">${a.icon}</span>\n <input type="text" id="${a.id}" placeholder="Search records..." class="${this.theme.searchInput}" />\n </div>\n `:n+=`\n <button id="${a.id}" class="${this.theme.button}" title="${a.text}">\n ${a.icon?`<span>${a.icon}</span>`:""}<span>${a.text}</span>\n\n </button>\n `;e.innerHTML=`\n <div class="${this.theme.controlsWrapper}">\n <div class="${this.theme.controlsLeft}">\n ${t}\n <div class="${this.theme.buttonGroup}">${n}</div>\n </div>\n ${i}\n </div>\n `;const a=this.table.parentNode;a&&a.insertBefore(e,this.table)}toggleLoadingSpinner(e){if(!this.enableLoadingSpinner||!this.tableId)return;const t=document.getElementById(this.tableId);if(!t)return;const n=t.querySelector("tbody");if(!n)return;let i=document.getElementById(this.LoadingSpinnerContainer);this.theme.framework;const a="bootstrap"===this.theme.framework,r="daisyui"===this.theme.framework;if(!i){let e;i=document.createElement("div"),i.id=this.LoadingSpinnerContainer,a?(i.className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center bg-white bg-opacity-75 d-none",e=document.createElement("div"),e.className="spinner-border text-primary"):r?(i.className="absolute inset-0 flex items-center justify-center bg-base-100/70 z-50 hidden",e=document.createElement("span"),e.className="loading loading-dots loading-lg"):(i.className="absolute inset-0 flex items-center justify-center bg-white/70 z-50 hidden",e=document.createElement("div"),e.className="w-10 h-10 border-4 border-gray-300 border-t-blue-500 rounded-full animate-spin"),i.appendChild(e);const t=n.parentNode;t.classList.contains("relative")||t.classList.add("relative"),t.appendChild(i)}this.loadingSpinnerTimeout&&clearTimeout(this.loadingSpinnerTimeout),e?(a?i.classList.remove("d-none"):i.classList.remove("hidden"),this.loadingDelay>0&&(this.loadingSpinnerTimeout=setTimeout(()=>{this.toggleLoadingSpinner(!1)},this.loadingDelay))):a?i.classList.add("d-none"):i.classList.add("hidden")}bindResetButton(){const e=document.getElementById(this.buttonConfig.reset.id);e&&e.addEventListener("click",()=>this.resetTable())}resetTable(){this.search="",this.currentPage=1,this.sort="id",this.order="asc",this.columnFilters={},this.searchInput&&(this.searchInput.value=""),this.clearState();document.querySelectorAll("[data-column-filter]").forEach(e=>{e.value=""}),this.dispatchEvent(n.RESET),this.fetchData()}bindReloadButton(){const e=document.getElementById(this.buttonConfig.reload.id);e&&e.addEventListener("click",()=>{this.dispatchEvent(n.RELOAD),this.fetchData()})}bindExportButton(){const e=document.getElementById(this.buttonConfig.export.id);e&&e.addEventListener("click",()=>{this.dispatchEvent(n.EXPORT),this.exportToExcel()})}bindDownloadCsvButton(){const e=document.getElementById(this.buttonConfig.downloadCsv.id);e&&e.addEventListener("click",()=>this.downloadCSV())}bindPrintButton(){const e=document.getElementById(this.buttonConfig.print.id);e&&e.addEventListener("click",()=>this.printTable())}bindPdfButton(){const e=document.getElementById(this.buttonConfig.pdf.id);e&&e.addEventListener("click",()=>this.downloadPdf())}initSearch(){const e=document.getElementById(this.buttonConfig.search.id);e&&(this.searchInput=e,this.bindSearch(),this.searchInput.addEventListener("input",e=>{this.search=e.target.value,this.currentPage=1,this.dispatchEvent(n.SEARCH,{search:this.search})}))}bindSearch(){if(!this.searchInput)return;const e=this.debounce(e=>{this.search=e.target.value,this.currentPage=1,this.dispatchEvent(n.SEARCH,{searchTerm:this.search,currentPage:this.currentPage,searchDelay:this.searchDelay}),this.enableSaveState&&this.saveState(),this.fetchData()},this.searchDelay);this.searchInput.addEventListener("input",e)}debounce(e,t){let n;return function(...i){clearTimeout(n),n=setTimeout(()=>{e.apply(this,i)},t)}}bindColumnSearchInputs(){document.querySelectorAll(".column-search").forEach(e=>{const t=e.dataset.column;e.addEventListener("input",()=>{clearTimeout(this.columnSearchTimer),this.columnSearchTimer=setTimeout(()=>{this.columnFilters[t]=e.value,this.currentPage=1,this.enableSaveState&&this.saveState(),this.fetchData()},this.searchDelay)})})}bindPerPageSelect(){const e=this.buttonConfig.perPageSelect;if(!e||!e.enabled)return;const t=document.getElementById(e.id);t?t.addEventListener("change",e=>{this.rowsPerPage=parseInt(e.target.value),this.currentPage=1,this.dispatchEvent(n.PER_PAGE_CHANGE,{perPage:this.rowsPerPage,currentPage:this.currentPage}),this.fetchData()}):console.warn(`Per page select element with id '${e.id}' not found.`)}getRangeFilters(){const e={};for(const[t]of Object.entries(this.rangeFilterFields)){const n=document.querySelector(`[data-filter-min="${t}"]`)?.value,i=document.querySelector(`[data-filter-max="${t}"]`)?.value;(n||i)&&(e[t]={min:n,max:i})}return e}async fetchData({applyRangeFilters:e=!1}={}){this.enableLoadingSpinner&&this.toggleLoadingSpinner(!0);const t=new URLSearchParams({search:this.search,sortBy:this.sort,order:this.order,page:this.currentPage,perPage:this.rowsPerPage,columnFilters:JSON.stringify(this.columnFilters)});for(const[e,n]of Object.entries(this.filters))""!==n&&null!=n&&t.append(e,n);e&&t.append("rangeFilters",JSON.stringify(this.getRangeFilters())),this.dispatchEvent(n.LOADING,{queryParams:t.toString()});try{const e=new AbortController,i=setTimeout(()=>e.abort(),3e4),a=await fetch(`${this.url}?${t.toString()}`,{method:"GET",headers:{"Content-Type":"application/json"},signal:e.signal});if(clearTimeout(i),!a.ok)throw new Error(`HTTP error! status: ${a.status}`);const r=await a.json();this.data=r[this.dataSrc]||[],this.dispatchEvent(n.LOADED,{data:this.data,page:this.currentPage,totalItems:r.total||this.data.length,response:r}),0===this.data.length?this.showEmptyStateInTable("No records found."):this.renderTable(this.data),this.pagination&&this.updatePagination(r)}catch(e){console.error("Error fetching data:",e),this.dispatchEvent(n.ERROR,{error:e,requestParams:t.toString()}),0===this.data.length&&this.showEmptyStateInTable("Error loading data")}finally{this.loadingDelay<=0&&this.toggleLoadingSpinner(!1)}}showEmptyStateInTable(e="No data available."){if(!this.table)return void console.warn("DataTable: this.table is undefined");let t=this.table.querySelector("tbody");t||(console.warn("DataTable: <tbody> not found in table"),t=document.createElement("tbody"),this.table.appendChild(t));const n=this.table.querySelectorAll("thead tr:first-child th").length||1;t.innerHTML=`\n <tr>\n <td colspan="${n}" class="text-center text-base-content text-sm py-6">\n ${e}\n </td>\n </tr>\n `;const i=this.paginationWrapper||document.getElementById("pagination");i&&(i.innerHTML="")}_renderTable(){this.renderTable(this.data)}renderTableHeader(){this.theme?.table&&(this.table.className=this.theme.table);const e=this.table.querySelector("thead");e&&e.remove();const t=this.table.createTHead();t.className=this.theme.header||"",this.stickyHeader&&t.classList.add(...this.theme.headerSticky?.split(" ")||[]);const n=this.columns.filter(e=>!1!==e.visible),i=this.columnGroups?.length>0;i&&this.renderGroupHeaders(t,n),this.columnFiltering&&this.renderFilterInputs(t,n),this.renderColumnHeaders(t,n,i),this.table.querySelector("tbody")||this.table.appendChild(document.createElement("tbody"))}renderGroupHeaders(e,t){const n=e.insertRow();n.className=this.theme.groupHeaderRow||"";const i={};t.forEach(e=>{e.group&&(i[e.group]=(i[e.group]||0)+1)});const a={};this.columnGroups.forEach(e=>a[e.key]=e);const r=new Set;let s=0;for(;s<t.length;){const e=t[s];if(e.group&&!r.has(e.group)){const t=document.createElement("th");t.colSpan=i[e.group],t.textContent=a[e.group]?.label||e.group;const o=this.theme.groupHeaderCell||"",l=a[e.group]?.headerClass||"";t.className=`${o} ${l}`.trim(),n.appendChild(t),r.add(e.group),s+=i[e.group]}else{const e=document.createElement("th");e.colSpan=1,n.appendChild(e),s++}}}renderFilterInputs(e,t){const i=e.insertRow();if(i.className=this.theme.filterRow||"",this.columnFilters=this.columnFilters||{},Object.keys(this.rangeFilterFields||{}).length>0){const t=e.insertRow(),n=document.createElement("th");n.colSpan=100;const i=document.createElement("div");i.className="w-full";const a=document.createElement("div");a.className=this.theme.advancedFilterToggle,a.innerHTML=`\n <span class="text-gray-700 dark:text-white">Advanced Filters</span>\n <svg id="range-toggle-arrow" xmlns="http://www.w3.org/2000/svg" width="14" height="14" class="${this.theme.advancedFilterArrow}" fill="none" viewBox="0 0 24 24" stroke="currentColor">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>\n </svg>`;const r=document.createElement("div");r.className=this.theme.advancedFilterRow;for(const[e,t]of Object.entries(this.rangeFilterFields)){const n="number"===t.type?"number":"date",i=t.label||e,a=document.createElement("div");a.className=this.theme.advancedFilterDiv;const s=document.createElement("label");s.className=this.theme.advancedFilterLabel,s.textContent=i;const o=document.createElement("div");o.className=this.theme.advancedFilterInputs;const l=document.createElement("input");l.type=n,l.placeholder=t.placeholderMin||"From",l.dataset.filterMin=e,l.className=this.theme.advancedFilterInput;const d=document.createElement("input");d.type=n,d.placeholder=t.placeholderMax||"To",d.dataset.filterMax=e,d.className=this.theme.advancedFilterInput,o.appendChild(l),o.appendChild(d),a.appendChild(s),a.appendChild(o),r.appendChild(a)}const s=document.createElement("div");s.className=this.theme.advancedFilterButtonContainer;const o=document.createElement("button");o.textContent="Apply Filters",o.type="button",o.className=this.theme.advancedFilterButton,o.addEventListener("click",()=>{this.fetchData({applyRangeFilters:!0})}),s.appendChild(o),r.appendChild(s);const l="tailwind"===this.theme.framework,d="bootstrap"===this.theme.framework;this.theme.framework,a.addEventListener("click",()=>{l&&(r.classList.toggle("max-h-0"),r.classList.toggle("opacity-0"),r.classList.toggle("max-h-[1000px]"),r.classList.toggle("opacity-100"),r.classList.toggle("py-0"),r.classList.toggle("py-3")),d&&r.classList.toggle("d-none");a.querySelector("#range-toggle-arrow").classList.toggle("rotate-180")}),i.appendChild(a),i.appendChild(r),n.appendChild(i),t.appendChild(n)}t.forEach(e=>{const t=document.createElement("th");if(t.className=this.theme.headerCell||"",this.filterableColumns.includes(e.name)){const i=document.createElement("input");i.type="search",i.placeholder=`Filter ${e.label}`,i.className=this.theme.filterInput||"",i.addEventListener("input",this.debounce(t=>{this.columnFilters[e.name]=t.target.value,this.dispatchEvent(n.FILTER,{column:e,value:t.target.value,filters:this.columnFilters,timestamp:(new Date).toISOString(),tableId:this.table.id||null,searchDelay:this.searchDelay}),this.fetchData()},this.searchDelay)),t.appendChild(i)}i.appendChild(t)})}setFilter(e,t,n=!1){this.filters[e]=t,n||this.fetchData()}removeFilter(e){delete this.filters[e]}clearFilters(){this.filters={}}renderColumnHeaders(e,t,i){const a=e.insertRow();t.forEach((r,s)=>{const o=document.createElement("th");if(this.theme.headerCell?o.className=this.theme.headerCell:o.classList.add("cursor-pointer"),i){const e=t[s-1],n=t[s+1];e&&e.group===r.group||(o.dataset.groupStart="true"),n&&n.group===r.group||(o.dataset.groupEnd="true")}o.dataset.columnName=r.name,r.tooltip&&(o.title=r.tooltip);const l=document.createElement("span");if(l.textContent=r.label,o.appendChild(l),this.sortableColumns?.includes(r.name)){o.classList.add("cursor-pointer"),o.dataset.column=r.name,o.dataset.order=this.defaultOrder||"asc";const t=document.createElement("span");t.className="sort-icon ml-2",t.innerHTML=this.getNeutralSortIcon(),o.appendChild(t),o.addEventListener("click",()=>{const t="asc"===o.dataset.order?"desc":"asc";o.dataset.order=t,this.sort=r.name,this.order=t,e.querySelectorAll(".sort-icon").forEach(e=>{e.innerHTML=this.getNeutralSortIcon()});const i=o.querySelector(".sort-icon");i&&(i.innerHTML="asc"===t?this.getAscSortIcon():this.getDescSortIcon()),this.dispatchEvent(n.SORT,{column:r.name,label:r.label,index:this.columns.indexOf(r),direction:t,timestamp:(new Date).toISOString(),tableId:this.table.id||null}),this.enableSaveState&&this.saveState(),this.fetchData()})}a.appendChild(o)})}getNeutralSortIcon(){return'\n <svg width="16" height="16" viewBox="0 0 24 24" fill="none"\n xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="2"\n stroke-linecap="round" stroke-linejoin="round" style="color: #9ca3af;">\n <path d="m3 16 4 4 4-4" />\n <path d="M7 20V4" />\n <path d="m21 8-4-4-4 4" />\n <path d="M17 4v16" />\n </svg>\n '}getAscSortIcon(){return'\n <svg width="16" height="16" viewBox="0 0 24 24" fill="none"\n xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="2"\n stroke-linecap="round" stroke-linejoin="round" style="color: #4b5563;">\n <path d="m3 8 4-4 4 4" />\n <path d="M7 4v16" />\n <path d="M11 12h4" />\n <path d="M11 16h7" />\n <path d="M11 20h10" />\n </svg>\n '}getDescSortIcon(){return'\n <svg width="16" hei