Hi,
Can any one point me in the direction of how to add pagination to a uui-table in the back office.
I have it loading data but I need to paginate it.
Regards
Darren
Hi,
Can any one point me in the direction of how to add pagination to a uui-table in the back office.
I have it loading data but I need to paginate it.
Regards
Darren
I used AI to create a minimal example based on a dashboard where I use paging in a uui-table. It also features a dropdown to select the page size. Hope it helps!
It’s a matter of using a uui-pagination and keeping track of pages and page size and request your data paged from an API endpoint. You just need to handle a few events, but that’s it.
import { LitElement, html, state, customElement } from "@umbraco-cms/backoffice/external/lit";
/**
* Minimal paging example for form posts
*/
@customElement('minimal-paged-form')
export default class MinimalPagedFormElement extends LitElement {
// Page size options
private readonly PAGE_SIZE_OPTIONS: number[] = [10, 25, 50];
private readonly DEFAULT_PAGE_SIZE: number = 25;
// Pagination state
@state()
private _currentPage = 1;
@state()
private _pageSize = this.DEFAULT_PAGE_SIZE;
@state()
private _totalPages = 0;
@state()
private _totalItems = 0;
@state()
private _data: any[] = [];
@state()
private _isLoading = false;
async connectedCallback() {
super.connectedCallback();
await this.#loadData();
}
/**
* Load paged data from API
*/
async #loadData(): Promise<void> {
this._isLoading = true;
try {
// Calculate skip value for API
const skip = (this._currentPage - 1) * this._pageSize;
// Example API call structure (replace with your actual endpoint)
const response = await fetch('/api/your-endpoint', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
skip: skip,
take: this._pageSize
// Add other filters/parameters as needed
})
});
const result = await response.json();
// Update state with results
this._data = result.items || [];
this._totalItems = result.totalCount || 0;
this._totalPages = Math.ceil(this._totalItems / this._pageSize);
} catch (error) {
console.error("Failed to load data", error);
} finally {
this._isLoading = false;
}
}
/**
* Handle page change from pagination component
*/
async #onPageChange(event: CustomEvent): Promise<void> {
this._currentPage = event.detail?.current || 1;
await this.#loadData();
}
/**
* Handle page size change
*/
async #onPageSizeChange(newSize: number): Promise<void> {
this._pageSize = newSize;
// Recalculate total pages and adjust current page if needed
const newTotalPages = Math.ceil(this._totalItems / newSize);
this._currentPage = Math.min(this._currentPage, Math.max(1, newTotalPages));
await this.#loadData();
}
render() {
return html`
<div class="container">
${this._isLoading
? html`<uui-loader></uui-loader>`
: html`
<!-- Your data display here -->
<div class="data">
${this._data.map(item => html`<div>${item}</div>`)}
</div>
<!-- Pager -->
<div class="pager-container">
<!-- Page size selector -->
<div class="page-size">
Results per page:
${this.PAGE_SIZE_OPTIONS.map((size, index) => html`
${index > 0 ? html`<span>|</span>` : ''}
<uui-button
compact
.look="${this._pageSize === size ? 'primary' : 'default'}"
@click="${() => this.#onPageSizeChange(size)}">
${size}
</uui-button>
`)}
</div>
<!-- Pagination component -->
<uui-pagination
.current="${this._currentPage}"
.total="${this._totalPages}"
@change="${this.#onPageChange}">
</uui-pagination>
</div>
`
}
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'minimal-paged-form': MinimalPagedFormElement;
}
}
Thank you for your help.
There are a few examples in the umbraco-cms source.. not necessarily tables but lists with pagination and seem to follow the same pattern..