Show number of results per page
interface User {
id: string;
firstName: string;
lastName: string;
age: number;
}
const [users, setUsers] = useState<User[]>([]);
const [pageUsers, setPageUsers] = useState<User[]>([]);
const [page, setPage] = useState<number>(1);
const [perPage, setPerPage] = useState<number>(10);
useEffect(() => {
// Generate sample data
const firstNames = ["Emma", "Liam", "Olivia", "Noah", "Ava", "James", "Sophia", "William", "Isabella", "Oliver", "Mia", "Benjamin", "Charlotte", "Elijah", "Amelia", "Lucas", "Harper", "Mason", "Evelyn", "Logan"];
const lastNames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Wilson", "Anderson", "Taylor", "Thomas", "Moore", "Jackson", "Martin", "Lee", "Thompson", "White"];
const _users: User[] = [];
for (let i = 1; i <= 100; i++) {
_users.push({
id: `user-${i}`,
firstName: firstNames[(i - 1) % firstNames.length],
lastName: lastNames[(i - 1) % lastNames.length],
age: 20 + (i % 40),
});
}
setUsers(_users);
setPageUsers(_users.slice(0, perPage));
}, [perPage]);
function changePage(newPage: number) {
const offset = (newPage - 1) * perPage;
const _users = users.slice(offset, offset + perPage);
setPage(newPage);
setPageUsers(_users);
}
function handlePerPageCountChangeEvent(event: GoabDropdownOnChangeDetail) {
const perPageValue = parseInt(event.value || "10");
setPage(1);
setPerPage(perPageValue);
const _users = users.slice(0, perPageValue);
setPageUsers(_users);
}<GoabxTable width="100%" mb="xl">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{pageUsers.map((u) => (
<tr key={u.id}>
<td>{u.firstName}</td>
<td>{u.lastName}</td>
<td>{u.age}</td>
</tr>
))}
</tbody>
</GoabxTable>
<GoabBlock alignment="center" width="100%">
<GoabBlock mb="m" alignment="center">
Show
<GoabxDropdown
onChange={handlePerPageCountChangeEvent}
value={perPage.toString()}
width="9ch"
>
<GoabxDropdownItem value="10" label="10" />
<GoabxDropdownItem value="20" label="20" />
<GoabxDropdownItem value="30" label="30" />
</GoabxDropdown>
<span style={{ width: "75px" }}>per page</span>
</GoabBlock>
<GoabSpacer hSpacing="fill" />
<GoabxPagination
itemCount={users.length}
perPageCount={perPage}
pageNumber={page}
onChange={(event) => changePage(event.page)}
/>
</GoabBlock>users: User[] = [];
pageUsers: User[] = [];
page = 1;
perPage = 10;
total = 100;
constructor() {
this.pageUsers = this.prepareUsers().slice(0, this.perPage);
}
prepareUsers(): User[] {
const firstNames = ["Emma", "Liam", "Olivia", "Noah", "Ava", "James", "Sophia", "William", "Isabella", "Oliver", "Mia", "Benjamin", "Charlotte", "Elijah", "Amelia", "Lucas", "Harper", "Mason", "Evelyn", "Logan"];
const lastNames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Wilson", "Anderson", "Taylor", "Thomas", "Moore", "Jackson", "Martin", "Lee", "Thompson", "White"];
for (let i = 1; i <= this.total; i++) {
this.users.push({
id: `user-${i}`,
firstName: firstNames[(i - 1) % firstNames.length],
lastName: lastNames[(i - 1) % lastNames.length],
age: 20 + (i % 40),
});
}
return this.users;
}
handlePageChange(event: GoabPaginationOnChangeDetail): void {
this.page = event.page;
const offset = (this.page - 1) * this.perPage;
this.pageUsers = this.users.slice(offset, offset + this.perPage);
}
handlePerPageCountChangeEvent(event: GoabDropdownOnChangeDetail): void {
this.page = 1;
this.perPage = Number(event.value);
this.pageUsers = this.users.slice(0, this.perPage);
}<goabx-table width="100%" mb="xl">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of pageUsers">
<td>{{ user.firstName }}</td>
<td>{{ user.lastName }}</td>
<td>{{ user.age }}</td>
</tr>
</tbody>
</goabx-table>
<goab-block alignment="center" width="100%">
<goab-block mb="m" alignment="center">
Show
<goabx-dropdown
(onChange)="handlePerPageCountChangeEvent($event)"
value="10"
width="9ch">
<goabx-dropdown-item value="10" label="10"></goabx-dropdown-item>
<goabx-dropdown-item value="20" label="20"></goabx-dropdown-item>
<goabx-dropdown-item value="30" label="30"></goabx-dropdown-item>
</goabx-dropdown>
<span style="width: 75px">per page</span>
</goab-block>
<goab-spacer hSpacing="fill"></goab-spacer>
<goabx-pagination
[itemCount]="users.length"
[perPageCount]="perPage"
[pageNumber]="page"
(onChange)="handlePageChange($event)">
</goabx-pagination>
</goab-block>const firstNames = ["Emma", "Liam", "Olivia", "Noah", "Ava", "James", "Sophia", "William", "Isabella", "Oliver", "Mia", "Benjamin", "Charlotte", "Elijah", "Amelia", "Lucas", "Harper", "Mason", "Evelyn", "Logan"];
const lastNames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Wilson", "Anderson", "Taylor", "Thomas", "Moore", "Jackson", "Martin", "Lee", "Thompson", "White"];
const users = [];
for (let i = 1; i <= 100; i++) {
users.push({
id: "user-" + i,
firstName: firstNames[(i - 1) % firstNames.length],
lastName: lastNames[(i - 1) % lastNames.length],
age: 20 + (i % 40),
});
}
let page = 1;
let perPage = 10;
const tableBody = document.getElementById("table-body");
const pagination = document.getElementById("pagination");
const dropdown = document.getElementById("per-page-dropdown");
function renderTable() {
const offset = (page - 1) * perPage;
const pageUsers = users.slice(offset, offset + perPage);
tableBody.innerHTML = pageUsers
.map(
(u) => `
<tr>
<td>${u.firstName}</td>
<td>${u.lastName}</td>
<td>${u.age}</td>
</tr>
`
)
.join("");
}
pagination.addEventListener("_change", (e) => {
page = e.detail.page;
renderTable();
});
dropdown.addEventListener("_change", (e) => {
perPage = parseInt(e.detail.value);
page = 1;
pagination.setAttribute("perpagecount", perPage);
pagination.setAttribute("pagenumber", "1");
renderTable();
});
renderTable();<goa-table version="2" width="100%" mb="xl">
<table width="100%">
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
<th>Age</th>
</tr>
</thead>
<tbody id="table-body">
<!-- Rows populated by JavaScript -->
</tbody>
</table>
</goa-table>
<goa-block alignment="center" width="100%">
<goa-block mb="m" alignment="center">
Show
<goa-dropdown version="2" id="per-page-dropdown" value="10" width="9ch">
<goa-dropdown-item value="10" label="10"></goa-dropdown-item>
<goa-dropdown-item value="20" label="20"></goa-dropdown-item>
<goa-dropdown-item value="30" label="30"></goa-dropdown-item>
</goa-dropdown>
<span style="width: 75px">per page</span>
</goa-block>
<goa-spacer hspacing="fill"></goa-spacer>
<goa-pagination version="2"
id="pagination"
itemcount="100"
perpagecount="10"
pagenumber="1">
</goa-pagination>
</goa-block>Combine pagination with a dropdown selector to let users control how many results appear per page, improving data browsing for different use cases.
When to use
Use this pattern when:
- Displaying paginated data in tables
- Users may want to see more or fewer items
- Different tasks benefit from different page sizes
- The total result count should be visible
Considerations
- Show “of X” to indicate total results
- Reset to page 1 when changing page size
- Use reasonable default (10 is common)
- Provide sensible options (10, 20, 30, etc.)