= 1 && page <= this.totalPages && page !== this.currentPage) {
this.currentPage = page;
this.loadPage(page);
}
},
// Navigate to previous page
prevPage() {
if (this.hasPrev) {
this.goToPage(this.currentPage - 1);
}
},
// Navigate to next page
nextPage() {
if (this.hasNext) {
this.goToPage(this.currentPage + 1);
}
},
// Change page size
changePageSize(size) {
this.perPage = size;
this.currentPage = 1;
this.loadPage(1);
},
// Load page via HTMX
loadPage(page) {
const url = new URL('{{ base_url }}', window.location.origin);
url.searchParams.set('page', page);
url.searchParams.set('per_page', this.perPage);
// Preserve other query parameters
{% if query_params %}
{% for key, value in query_params.items() %}
url.searchParams.set('{{ key }}', '{{ value }}');
{% endfor %}
{% endif %}
// Scroll to the top of the table before loading new content
const targetElement = document.querySelector(this.targetSelector);
if (targetElement) {
// Find the parent section/panel to scroll to
const panel = targetElement.closest('.tab-panel, .bg-white, .shadow');
if (panel) {
panel.scrollIntoView({ behavior: 'smooth', block: 'start' });
} else {
targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}
// Trigger HTMX request - use innerHTML so we only replace tbody content (rows)
// The OOB swap will handle the pagination controls separately
htmx.ajax('GET', url.toString(), {
target: this.targetSelector,
swap: 'innerHTML',
indicator: '{{ hx_indicator|default("#loading") }}'
});
}
}" class="flex flex-col sm:flex-row items-center justify-between gap-4 py-4 border-t border-gray-200 dark:border-gray-700">
Show:
per page
...
...
←
/
→
to navigate