Skip to content

Pagination

oldmangan edited this page Oct 6, 2026 · 1 revision

Page controls for a list that the server (or the app) pages: first, previous, next and last buttons, a "page N of M" box or numbered buttons, a page-size selector and a "1–50 of 1,234" summary. Added in #34.

from wapyt import Pagination, PaginationConfig

pager = Pagination(PaginationConfig(page_size=50, page_sizes=[20, 50, 100]),
                   container=footer_cell)

async def load(state):
    pager.set_busy(True)
    result = await api.find(page=state["page"], page_size=state["page_size"])
    table.set_rows(result["docs"])
    pager.set_total(result["total"], exact=result["exact"])
    pager.set_busy(False)

pager.on_change(lambda state: spawn(load(state), "page"))

Mount it with container= (an element or a layout cell), root= (a selector), or Layout.add_pagination(id, config).

Options

PaginationConfig
total Item count, or None if unknown (see below)
page, page_size 1-based current page and items per page
page_sizes Choices for the page-size selector; empty hides it
exact False shows the total as an estimate: "of ≈1,200"
has_more With an unknown total, whether there is a next page
numbers Numbered buttons (1 … 4 5 6 … 20) instead of the page box; needs a known total
siblings Numbered buttons either side of the current page (default 1)
show_jump, show_summary The page box and the summary text
empty_text Summary when there is nothing to show (default "No items")
label aria-label of the <nav>

Events and methods

on_change gets {page, page_size, offset}. It fires only when the person moves (a button, the page box, a numbered button or the page-size selector), plus one case: set_total shrinking the list under the current page moves to the new last page and fires, so the app loads it. Changing the page size goes back to page 1.

Method
set_total(total, exact=True, has_more=True, shown=None) Report the count after a load
set_page(page), set_page_size(size) Move without firing on_change
set_busy(True) Disable every control while a page loads
get_state() {page, page_size, offset, total, page_count}
page_rows(rows) The current page of an in-memory list (also page_slice(rows, page, size))

The setters never fire on_change, so a load handler can call them freely.

Unknown totals

When the server gives up counting (Monguana's count timeout), pass total=None. There is then no Last button and no "of M"; Next is enabled while has_more is true. Pass shown (the rows on this page) so a short final page reads "41–57" rather than "41–60". Numbered mode needs a total and falls back to the page box without one.

Accessibility

A <nav> with an aria-label; icon buttons are labelled ("Next page"); the current numbered button has aria-current="page"; the summary is aria-live="polite". It wraps instead of overflowing on narrow screens.

Clone this wiki locally