Testning av tabell
Den här sidan används vid testning av komponent tabell.
Exempel för test
<script setup lang="ts">
import { h, ref, useTemplateRef } from "vue";
import { assertRef, formatNumber } from "@fkui/logic";
import { FSortFilterDataset } from "@fkui/vue";
import { type TableColumn, FTable, defineTableColumns } from "@fkui/vue-labs";
const tableRef = useTemplateRef("table");
const selectFieldOptions = ["Hund", "Katt", "Hamster", "Papegoja", "Spindel", "Guldfisk"];
interface Row {
id: string;
animal?: string;
level: string;
start: string;
end: string;
antal: string;
expandableRows?: Row[];
expandableContent?: Array<{
id: string;
content: string;
}>;
aktiv?: boolean;
}
const columns = defineTableColumns<Row>([
{
type: "text",
header: "Oformaterad text",
value(row) {
return String(row.antal);
},
},
{
type: "checkbox",
header: "Kryssruta",
key: "aktiv",
size: "shrink",
label: (row) => `Välj rad ${row.id}`,
editable: true,
},
{
type: "text",
header: "Formatterad text",
label: (row) => `Text för rad ${row.id}`,
value(row) {
return formatNumber(row.antal) ?? "";
},
editable: true,
},
{
type: "text",
header: "Redigerbar text",
editable: true,
key: "level",
label: (row) => `Text för rad ${row.id}`,
value(row) {
return row.level;
},
update(row, newValue) {
row.level = newValue;
},
validation: {
required: {},
maxLength: { length: 5 },
},
},
{
type: "button",
header: "Knapp",
icon: "trashcan",
size: "shrink",
value(row) {
return `Ta bort ${row.id}`;
},
onClick: onRemoveRow,
},
{
header: "Länk",
type: "anchor",
href: "#",
value() {
return "Länktext";
},
},
{
header: "Dropplista",
type: "select",
key: "animal",
label: (row) => `Djur för rad ${row.id}`,
options: selectFieldOptions,
editable: true,
},
{
header: "Render function",
render() {
return h("td", { id: "foo", class: "bar" }, ["👻"]);
},
},
// {
// header: "Custom component",
// type: "render",
// render() {
// return XTableChip;
// },
// },
]);
const rows = ref<Row[]>([
{
id: "1",
animal: "Katt",
level: "Föräldrapenning",
start: "2022-04-11",
end: "2022-04-20",
antal: "10000",
aktiv: false,
expandableRows: [
{
id: "1a",
level: "Sjukpenningsnivå",
start: "2022-04-18",
end: "2022-04-20",
antal: "30000",
},
{
id: "1b",
level: "Lägstanivå",
start: "2022-04-16",
end: "2022-04-17",
antal: "20000",
},
{
id: "1c",
level: "Sjukpenningsnivå",
start: "2022-04-11",
end: "2022-04-15",
antal: "50000",
},
],
expandableContent: [
{
id: "1a",
content: "Anledning: Tar hand om barnet",
},
],
},
{
id: "2",
animal: "Spindel",
level: "Tillfällig föräldrapenning",
start: "2022-05-02",
end: "2022-05-04",
antal: "30000",
aktiv: false,
expandableRows: [
{
id: "2a",
level: "Heldag",
start: "2022-05-02",
end: "2022-05-04",
antal: "30000",
},
],
expandableContent: [
{
id: "2a",
content: "Anledning: Tar hand om barnet",
},
],
},
{
id: "3",
animal: "Hamster",
level: "Föräldrapenning",
start: "2022-05-16",
end: "2022-05-27",
antal: "11000",
aktiv: true,
expandableRows: [
{
id: "3a",
level: "Sjukpenningsnivå",
start: "2022-05-23",
end: "2022-05-27",
antal: "40000",
},
{
id: "3b",
level: "Lägstanivå",
start: "2022-05-21",
end: "2022-05-22",
antal: "20000",
},
{
id: "3c",
level: "Sjukpenningsnivå",
start: "2022-05-16",
end: "2022-05-20",
antal: "50000",
},
],
expandableContent: [
{
id: "3a",
content: "Anledning: Tar hand om barnet",
},
],
},
]);
function hasKey<T, K extends keyof T>(
column: TableColumn<T, K>,
): column is TableColumn<T, K> & { key: K } {
return Boolean("key" in column && column.key);
}
const sortableAttributes = Object.fromEntries(
columns.filter(hasKey).map((it) => [it.key, it.header]),
);
const mySelectedRows = ref<Row[]>([rows.value[0]]);
function onAddRow(): void {
rows.value.push({
id: String(rows.value.length + 1),
animal: "Katt",
level: "Föräldrapenning",
start: "2022-04-11",
end: "2022-04-20",
antal: "10000",
aktiv: false,
});
}
function onRemoveRow(row: Row): void {
assertRef(tableRef);
tableRef.value.withTabstopBehaviour("row-removal", () => {
rows.value.splice(rows.value.indexOf(row), 1);
});
}
function onRemoveSelectedRows(): void {
rows.value = rows.value.filter((row) => !mySelectedRows.value.includes(row));
}
</script>
<template>
<button type="button" class="button button--secondary" @click="onRemoveSelectedRows">
Ta bort markerade rader
</button>
<f-sort-filter-dataset :data="rows" :sortable-attributes>
<template #default="{ sortFilterResult }">
<f-table
ref="table"
v-model:selected-rows="mySelectedRows"
:rows="sortFilterResult"
:columns
key-attribute="id"
striped
selectable="multi"
>
<template #caption>Tabell</template>
<template #footer>Footer</template>
</f-table>
</template>
</f-sort-filter-dataset>
<button type="button" class="button button--secondary" @click="onAddRow">Lägg till rad</button>
</template>
<style>
body {
padding: 1rem;
}
.icon-button {
margin: 0;
padding: 0;
background: inherit;
border: 0;
cursor: pointer;
}
.level-2 {
margin-left: 0.5rem;
}
.level-3 {
padding-left: 1rem;
}
.bar {
background: hotpink;
}
</style>
Specialiserade inmatningsfält
<script setup lang="ts">
import { computed, ref } from "vue";
import { ValidationService } from "@fkui/logic";
import { FTable, defineTableColumns } from "@fkui/vue-labs";
interface TableRow {
id: string;
text: string;
pnr: string;
bankAccountNumber: string;
bankgiro: string;
clearingNumber: string;
date: string;
epost: string;
orgnr: string;
tele: string;
postnr: string;
plusgiro: string;
currency: number | string;
percent: number | string;
number: number | string;
}
const columns = defineTableColumns<TableRow, keyof TableRow>([
{
type: "text",
header: "Text",
key: "text",
editable: true,
},
{
type: "text:personnummer",
header: "Pnr",
key: "pnr",
editable: true,
},
{
type: "text:bankAccountNumber",
header: "Kontonr",
key: "bankAccountNumber",
editable: true,
},
{
type: "text:bankgiro",
header: "Bankgiro",
key: "bankgiro",
editable: true,
},
{
type: "text:clearingNumber",
header: "Clearingnr",
key: "clearingNumber",
editable: true,
},
{
type: "text:currency",
header: "Valuta",
key: "currency",
editable: true,
},
{
type: "text:date",
header: "Datum",
key: "date",
editable: true,
},
{
type: "text:number",
decimals: 3,
header: "Nummer, tre decimaler",
key: "number",
editable: true,
},
{
type: "text:percent",
decimals: 2,
header: "% två decimaler",
key: "percent",
editable: true,
},
{
type: "text:email",
header: "Epost",
key: "epost",
editable: true,
},
{
type: "text:organisationsnummer",
header: "Orgnr",
key: "orgnr",
editable: true,
},
{
type: "text:phoneNumber",
header: "Tele",
key: "tele",
editable: true,
},
{
type: "text:postalCode",
header: "Postnr",
key: "postnr",
editable: true,
},
{
type: "text:plusgiro",
header: "Plusgiro",
key: "plusgiro",
editable: true,
},
]);
const rows = ref<TableRow[]>([
{
id: "1",
text: "aaa",
pnr: "19120211-9150",
bankAccountNumber: "12345678",
bankgiro: "9999996",
clearingNumber: "5678",
date: "2023-06-15",
currency: 3453455,
number: 5.4,
percent: 9.987,
epost: "a.b@example.net",
orgnr: "9999999999",
tele: "12345678901234567",
postnr: "37324",
plusgiro: "11111119",
},
{
id: "2",
text: "bbb",
pnr: "201812312385",
bankAccountNumber: "0012345678",
bankgiro: "999-9996",
clearingNumber: "56781",
currency: 24233,
date: "2024-01-20",
number: 5.5,
percent: 19.987,
epost: "a.b@example.net",
orgnr: "9999999999",
tele: "12345678901234567",
postnr: "39359",
plusgiro: "11111119",
},
{
id: "3",
text: "ccc",
pnr: "197006121144",
bankAccountNumber: "123456",
bankgiro: "999-9996",
clearingNumber: "5678-1",
currency: 234623546,
date: "2022-11-05",
number: 5.55,
percent: 3.1,
epost: "a.b@example.net",
orgnr: "9999999999",
tele: "12345678901234567",
postnr: "37332",
plusgiro: "111112",
},
]);
const sum = computed(() => {
return rows.value.reduce((sum, row) => {
if (typeof row.number === "number") {
return sum + row.number;
} else {
return sum;
}
}, 0);
});
function validataAll(): void {
ValidationService.validateAllElements("all");
}
</script>
<template>
<button type="button" class="button button--secondary" @click="validataAll">
Interagerbart element före
</button>
<div id="all">
<f-table :rows :columns="columns.slice(0, 5)" key-attribute="id" striped> </f-table>
<f-table :rows :columns="columns.slice(5, 10)" key-attribute="id" striped> </f-table>
<f-table :rows :columns="columns.slice(10)" key-attribute="id" striped> </f-table>
</div>
<pre>Summa: {{ { sum } }}</pre>
<h3>Rows ({{ rows.length }} items):</h3>
<pre>{{ rows }}</pre>
<button type="button" class="button button--secondary" @click="validataAll">
Interagerbart element efter
</button>
</template>