Pagination
Level: Intermediate 30–60 minConcepts: Business LogicBoundariesValidationEdge Cases
Build a pagination calculator that takes a total item count, page size, and current page — then returns everything a UI needs to render pagination controls.
Requirements
Given:
totalItems— total number of items in the datasetpageSize— number of items per pagecurrentPage— the page being viewed (1-based)
Return a pagination result containing:
totalPages— total number of pagescurrentPage— the current page (validated)pageSize— items per pagestartItem— the 1-based index of the first item on this pageendItem— the 1-based index of the last item on this pagehasPrevious— whether a previous page existshasNext— whether a next page exists
Validation Rules
totalItemsmust be ≥ 0pageSizemust be ≥ 1- If
currentPage< 1, clamp to 1 - If
currentPage>totalPages, clamp tototalPages - If
totalItemsis 0, return a result withtotalPages = 0and no items
Test Cases
| Total Items | Page Size | Current Page | Total Pages | Start | End | Prev | Next |
|---|---|---|---|---|---|---|---|
| 100 | 10 | 1 | 10 | 1 | 10 | false | true |
| 100 | 10 | 5 | 10 | 41 | 50 | true | true |
| 100 | 10 | 10 | 10 | 91 | 100 | true | false |
| 95 | 10 | 10 | 10 | 91 | 95 | true | false |
| 1 | 10 | 1 | 1 | 1 | 1 | false | false |
| 0 | 10 | 1 | 0 | 0 | 0 | false | false |
| 100 | 10 | 0 | 10 | 1 | 10 | false | true |
| 100 | 10 | 99 | 10 | 91 | 100 | true | false |
Edge cases:
- Exactly divisible (100 items / 10 per page = 10 pages)
- Not divisible (95 items / 10 per page = 10 pages, last page has 5)
- Single item
- Zero items
- Page number too low (clamp to 1)
- Page number too high (clamp to last page)
- Page size of 1 (every item is its own page)
Step 2: Page Window
Add a pageWindow(windowSize) method that returns the page numbers to display in the UI:
| Current Page | Total Pages | Window Size | Page Numbers |
|---|---|---|---|
| 1 | 10 | 5 | [1, 2, 3, 4, 5] |
| 5 | 10 | 5 | [3, 4, 5, 6, 7] |
| 10 | 10 | 5 | [6, 7, 8, 9, 10] |
| 3 | 4 | 5 | [1, 2, 3, 4] |
| 1 | 2 | 5 | [1, 2] |
The window should be centered on the current page when possible, and shift when near the edges.
Bonus
- Add offset-based calculation: return
offsetandlimitfor SQL queries - Add cursor-based pagination: given a sorted list and a cursor value, return the next/previous page
- Add
firstPageandlastPagehelpers for quick navigation
Hint
Start with totalPages — it’s just ceiling division. Then startItem and endItem — simple arithmetic from page number and page size. Add clamping next. The page window is a separate concern — build it after the basic calculator is solid.