Display value derived from field instead of field itself in q-table column
I have a role for a specific user with these numbers.
- Instead of number 1 it will display the word "Super Admin"
- Instead of number 2 it will display the word "Admin"
- Instead of number 2 it will display the word "User" and so on.
I am using q-table
<q-table
flat
bordered
title="USERS"
:data="allUsers"
:columns="columns"
:filter="filter"
:pagination.sync="initialPagination"
row-key="id"
>
<template v-slot:top-right>
<q-input
outlined
dense
debounce="300"
placeholder="Search"
v-model="filter"
>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
<div class="q-pa-sm q-gutter-sm"></div>
<q-btn
outline
color="white"
text-color="black"
@click="openCreateUserModal"
label="Create Users"
/>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td
v-for="col in props.cols.filter(col => col.name !== 'actions')"
:key="col.name"
>
{{ col.value }}
</q-td>
<td key="actions">
<q-btn dense flat color="primary" field="edit" icon="edit" />
<q-btn
dense
flat
color="negative"
field="delete"
icon="delete"
/>
</td>
</q-tr>
</template>
</q-table>
The role in my column
{
name: "role",
align: "center",
label: "Role",
field: "role",
sortable: true
},
Is this possible what I'm trying to achieve?
Solution 1:
Column definition can contain format
field to define a custom formatting function. The function is called with the 2 arguments - the value retrieved from field
and row
(which can be useful to create display values by combining data from multiple fields)
const roleIdToRoleName = {
1: "Super Admin",
2: "Admin",
3: "User"
}
...
{
name: "role",
align: "center",
label: "Role",
field: "role",
sortable: true,
format: (val, row) => roleIdToRoleName[val]
},
This works out of the box if you do not override default rendering by providing body
slot. This is problematic because you will loose a lot of provided functionality:
-
field
can be string but it can also be a function (useful to drill down to some nested object data) -
format
is of course not applied
Default "get cell value" functionality of q-table
looks like something like this:
const getCellValue(row, col) {
const val = typeof col.field === 'function' ? col.field(row) : row[col.field]
return col.format ? col.format(val, row) : val
}
You can of course replicate it in your code and use it:
<q-td :props="props" // !! you are missing props here
v-for="col in props.cols.filter(col => col.name !== 'actions')"
:key="col.name"
>
{{ getCellValue(props.row, col) }}
</q-td>
but since it seems only reason you are overriding body
slot is because you need custom rendering of the actions
column, why not just use body-cell-actions
slot instead? This will override only rendering of actions
column and other columns will use default q-table
rendering
Just add actions
column in columns definition:
{ name: 'actions', label: 'Action', sortable: false}
<template v-slot:body-cell-actions="props">
<q-td :props="props">
<q-btn dense flat color="primary" field="edit" icon="edit" />
<q-btn dense flat color="negative" field="delete" icon="delete" />
</q-td>
</template>