Given a list of users, build a user data table that displays users in a paginated format.
1<script>2 export let data;34 const columns = [5 { label: "ID", key: "id" },6 { label: "Name", key: "name" },7 { label: "Age", key: "age" },8 { label: "Occupation", key: "occupation" },9 ];10 const pageSizes = [5, 10, 20];1112 let page = 1;13 let pageSize = 5;1415 function changePageSize(event) {16 pageSize = Number(event.currentTarget.value);17 page = 1;18 }1920 $: totalPages = Math.ceil(data.length / pageSize);21 $: pageUsers = data.slice((page - 1) * pageSize, page * pageSize);22</script>2324<table>25 <thead>26 <tr>27 {#each columns as column}28 <th>29 {column.label}30 </th>31 {/each}32 </tr>33 </thead>34 <tbody>35 {#each pageUsers as user (user.id)}36 <tr>37 {#each columns as column}38 <td>{user[column.key]}</td>39 {/each}40 </tr>41 {/each}42 </tbody>43</table>4445<hr />4647<div class="pagination">48 <select aria-label="Page size" value={pageSize} on:change={changePageSize}>49 {#each pageSizes as size}50 <option value={size}>Show {size}</option>51 {/each}52 </select>53 <div class="pages">54 <button type="button" disabled={page === 1} on:click={() => (page -= 1)}>55 Prev56 </button>57 <span aria-label="Page number">Page {page} of {totalPages}</span>58 <button59 type="button"60 disabled={page === totalPages}61 on:click={() => (page += 1)}62 >63 Next64 </button>65 </div>66</div>
page and pageSize are component variables. Reactive declarations derive the total page count and current slice whenever either value changes.
Data tables are frequently asked about during front-end interviews, as displaying paginated data with filtering functionality is a UI pattern built at almost every company.
Since the table skeleton has been provided, we can focus on the state and data manipulation aspects of the data table.
State is straightforward. Only two state values are needed: the current page and the page size. Since the data does not change in this case, there's no need for the user data to be part of state.
These state values are manipulated by the page size <select> and prev/next buttons.
The maximum number of pages can be derived from the number of users divided by the page size, so it does not need to be part of state.
We implement a function paginateUsers that takes in the list of users, the page number, and the page size. It will return the list of users for the current page and the total number of pages.
To determine the list of users for the current page, we can determine the start and end indices, then use Array.prototype.slice() to extract the appropriate slice from the users list:
Array.prototype.slice(), it doesn't matter if the end index exceeds the size of the list.paginateUsers() will be called in the render path, and the returned pageUsers array contains the current page of users to be rendered. The rendering code doesn't need to be changed much.
Some other user experience improvements we can make:
console.log() statements will appear here.