mirror of
https://git.hmsn.ink/kospo/svcm/oa.git
synced 2026-03-20 06:53:29 +09:00
4.5 KiB
4.5 KiB
example_bottom
| example_bottom |
|---|
| true |
Make VFlexTable yours with slots
The easiest way to create complex tables with <VFlexTable /> is to uses slots.
This allow to use other components and having great control
inside rows (with #body-cell slot) and columns (with #header-column slot).
To update data dynamically, use reactive props so your interface will know
that data is updated, this is disabled by default to prevent
performance issues.
Check the markup for more details about usage.
<script setup lang="ts">
const selectedRowsId = ref<number[]>([])
const editCompanyIndex = ref<number>()
const isAllSelected = computed(
() => flexRowsContacts.length === selectedRowsId.value.length,
)
// this is our data
const data = [
{
id: 0,
company: 'Grubspot',
type: 'New Lead',
industry: 'Software',
status: 'Active',
contacts: [
{
id: 0,
picture: 'https://media.cssninja.io/content/avatars/25.jpg',
initials: 'AC',
color: 'info',
},
// and more contacts ..
],
},
// and more data ...
]
// this is the columns configuration
const columns = {
select: {
label: '',
cellClass: 'is-flex-grow-0',
},
company: {
label: 'Company',
grow: true,
},
type: 'Type',
industry: 'Industry',
status: 'Status',
contacts: {
label: 'Contacts',
align: 'end',
},
}
// the select all checkbox click handler
function toggleSelection() {
if (isAllSelected.value) {
selectedRowsId.value = []
}
else {
selectedRowsId.value = flexRowsContacts.map((_, index) => index)
}
}
// this it the row click handler (enabled with clickable props)
function clickOnRow(row: any) {
if (selectedRowsId.value.includes(row.id)) {
selectedRowsId.value = selectedRowsId.value.filter(i => i !== row.id)
}
else {
selectedRowsId.value = [...selectedRowsId.value, row.id]
}
}
// this is the "Contact me" click handler
function contactUser(row: any) {
alert(`Contacting "${row.company}" ...`)
}
// this is a local directive (it begins with V..., usable with v-focus)
// that is used to force the focus on input when mounted
const VFocus = {
mounted(el: HTMLInputElement) {
el.focus()
},
}
</script>
<template>
<VFlexTable
:data="data"
:columns="columns"
clickable
compact
rounded
@row-click="clickOnRow"
>
<!-- header-column slot -->
<template #header-column="{ column }">
<VCheckbox
v-if="column.key === 'select'"
class="ml-2 mr-3"
:checked="isAllSelected"
name="all_selected"
color="primary"
square
@click="toggleSelection"
/>
</template>
<!-- body-cell slot -->
<template #body-cell="{ row, column, value }">
<!--This is the slot for row.select cells-->
<VCheckbox
v-if="column.key === 'select'"
v-model="selectedRowsId"
:value="row.id"
name="selection"
square
/>
<!--This is the slot for row.company cells-->
<template v-else-if="column.key === 'company'">
<VControl v-if="editCompanyIndex === index">
<VField>
<input
v-model="row[column.key]"
v-focus
type="text"
class="input is-primary-focus"
@blur="editCompanyIndex = undefined"
@keydown.enter="editCompanyIndex = undefined"
>
</VField>
</VControl>
<a
v-else
class="is-overlay m-3 is-flex is-align-items-center is-clickable edit-icon-link"
role="button"
tabindex="0"
@click="editCompanyIndex = index"
@keydown.enter="editCompanyIndex = index"
>
{{ value }}
<VIcon
class="is-inline ml-1"
icon="lucide:edit"
role="img"
aria-label="edit-3"
/>
</a>
</template>
<!--This is the slot for row.status cells-->
<VTag
v-else-if="column.key === 'status'"
rounded
:color="
value === 'Suspended'
? 'orange'
: value === 'New'
? 'info'
: value === 'Active'
? 'primary'
: undefined
"
>
{{ value }}
</VTag>
<!--This is the slot for row.contacts cells-->
<VAction v-if="column.key === 'contacts'" @click.stop="contactUser(row)">
Contact me
</VAction>
<!--The default slot is used then-->
</template>
</VFlexTable>
</template>