Skip to content

Commit aa5937d

Browse files
refactor: add pagination example (refs SFKUI-7692) (#1088)
1 parent c20fc10 commit aa5937d

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<script setup lang="ts">
2+
import { ref, useTemplateRef } from "vue";
3+
import { assertRef } from "@fkui/logic";
4+
import { FPaginateDataset, FPaginator, FSortFilterDataset } from "@fkui/vue";
5+
import { type TableColumn, FTable, defineTableColumns, removeRow } from "@fkui/vue-labs";
6+
7+
const tableRef = useTemplateRef("table");
8+
9+
interface Row {
10+
id: string;
11+
name: string;
12+
receivedAt: string;
13+
expandableRows?: Row[];
14+
}
15+
16+
const columns = defineTableColumns<Row>([
17+
{
18+
type: "text",
19+
header: "Namn",
20+
key: "name",
21+
editable: true,
22+
label: (row) => `Namn för rad ${row.id}`,
23+
validation: {
24+
required: {},
25+
minLength: { length: 3 },
26+
},
27+
},
28+
{
29+
type: "text",
30+
header: "Mottaget",
31+
key: "receivedAt",
32+
},
33+
{
34+
type: "button",
35+
header: "Åtgärd",
36+
icon: "trashcan",
37+
text() {
38+
return "Ta bort";
39+
},
40+
onClick(row) {
41+
onRemoveRow(row);
42+
},
43+
},
44+
]);
45+
46+
const rows = ref<Row[]>([
47+
{
48+
id: "1",
49+
name: "Sofia Lindgren",
50+
receivedAt: "2023-11-12",
51+
expandableRows: [
52+
{
53+
id: "1a",
54+
name: "Detalj 1",
55+
receivedAt: "2023-11-12",
56+
},
57+
{
58+
id: "1b",
59+
name: "Detalj 2",
60+
receivedAt: "2023-11-13",
61+
},
62+
],
63+
},
64+
{
65+
id: "2",
66+
name: "Filip Gustafsson",
67+
receivedAt: "2024-02-20",
68+
expandableRows: [
69+
{
70+
id: "2a",
71+
name: "Detalj 1",
72+
receivedAt: "2024-03-02",
73+
},
74+
],
75+
},
76+
{
77+
id: "3",
78+
name: "Tina Jansson",
79+
receivedAt: "2024-05-15",
80+
},
81+
{
82+
id: "4",
83+
name: "David Lindqvist",
84+
receivedAt: "2024-08-30",
85+
expandableRows: [
86+
{
87+
id: "4a",
88+
name: "Detalj 1",
89+
receivedAt: "2024-09-05",
90+
},
91+
{
92+
id: "4b",
93+
name: "Detalj 2",
94+
receivedAt: "2024-09-10",
95+
},
96+
],
97+
},
98+
{
99+
id: "5",
100+
name: "Elin Andersson",
101+
receivedAt: "2024-11-12",
102+
},
103+
{
104+
id: "6",
105+
name: "Victor Nilsson",
106+
receivedAt: "2025-02-20",
107+
expandableRows: [],
108+
},
109+
{
110+
id: "7",
111+
name: "Sofia Lindström",
112+
receivedAt: "2025-05-15",
113+
},
114+
{
115+
id: "8",
116+
name: "Olle Bergström",
117+
receivedAt: "2025-08-30",
118+
expandableRows: [
119+
{
120+
id: "8a",
121+
name: "Detalj 1",
122+
receivedAt: "2025-09-19",
123+
},
124+
],
125+
},
126+
]);
127+
128+
function hasKey<T, K extends keyof T>(
129+
column: TableColumn<T, K>,
130+
): column is TableColumn<T, K> & { key: K } {
131+
return Boolean("key" in column && column.key);
132+
}
133+
134+
const sortableAttributes = Object.fromEntries(
135+
columns.filter(hasKey).map((column) => [column.key, column.header]),
136+
);
137+
138+
const selectedRows = ref<Row[]>([]);
139+
const itemsPerPage = ref(3);
140+
const nextId = ref(9);
141+
142+
function onAddRow(): void {
143+
const id = String(nextId.value);
144+
nextId.value += 1;
145+
146+
rows.value.push({
147+
id,
148+
name: "Ny person",
149+
receivedAt: "2026-03-10",
150+
expandableRows: [
151+
{
152+
id: `${id}a`,
153+
name: "Detalj 1",
154+
receivedAt: "2026-03-10",
155+
},
156+
],
157+
});
158+
}
159+
160+
function onRemoveRow(row: Row): void {
161+
assertRef(tableRef);
162+
163+
tableRef.value.withTabstopBehaviour("row-removal", () => {
164+
rows.value = removeRow(rows.value, row, "expandableRows");
165+
});
166+
}
167+
168+
function onRemoveSelectedRows(): void {
169+
rows.value = rows.value.filter((row) => !selectedRows.value.includes(row));
170+
}
171+
</script>
172+
173+
<template>
174+
<button type="button" class="button button--secondary" @click="onRemoveSelectedRows">
175+
Ta bort markerade rader
176+
</button>
177+
178+
<f-sort-filter-dataset :data="rows" :sortable-attributes>
179+
<template #default="{ sortFilterResult }">
180+
<f-paginate-dataset :items="sortFilterResult" :items-per-page>
181+
<template #default="{ items: currentPageItems }">
182+
<f-table
183+
ref="table"
184+
v-model:selected-rows="selectedRows"
185+
:rows="currentPageItems"
186+
:columns
187+
key-attribute="id"
188+
selectable="multi"
189+
expandable-attribute="expandableRows"
190+
>
191+
<template #caption>Tabell med paginering</template>
192+
</f-table>
193+
<f-paginator />
194+
</template>
195+
</f-paginate-dataset>
196+
</template>
197+
</f-sort-filter-dataset>
198+
199+
<button type="button" class="button button--secondary" @click="onAddRow">Lägg till rad</button>
200+
</template>

0 commit comments

Comments
 (0)