Adding custom content to cells
Grid allows adding custom components to table cells as well as header and footer cells.
Adding components
Basically, what you need is four simple steps:
- create a component (using HTML or ready-made components from the @svar-ui/vue-core library)
- in the component, access Grid properties via
defineProps, if needed - import the configured component to the application page with Grid
- add this component to the needed cell in Grid
Accessing Grid properties in components
Components in cells have access to the following Grid data via defineProps:
api- Grid API, using which you can call actions or listen to themrow- row data for body cells (data item)
- row index for header cells
column- column data (its id, dimensions, etc.)cell- for header cells only, cell properties (its text, colspan, rowspan, etc.)onaction- callback using which you can call built-in or custom actions
Let's look at some basic examples.
Creating static components
Embedding HTML to table cells
The example below demonstrates how to customize cells by adding images to them.
<script setup>
const props = defineProps({ row: {} }); // access Grid row data
</script>
<template>
<div class="container">
<div class="avatar">
<div class="user-avatar">
<img v-if="props.row.avatar" class="user-photo" alt="" :src="props.row.avatar" />
</div>
</div>
<div class="info">
<div class="name">{{ props.row.lastName }}</div>
<div class="mail">{{ props.row.email || "" }}</div>
</div>
</div>
</template>
<style scoped>
.container {
display: flex;
align-items: center;
height: 56px;
padding: 0 12px;
}
.avatar {
width: 70px;
}
.name, .mail {
flex: 1;
}
.user-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #dfe2e6;
text-align: center;
}
.user-photo {
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #dfe2e6;
}
</style>
Now you can import your component and apply it to a cell by adding its name to the cell parameter of a column element in the columns array:
<script setup>
import { Grid } from "@svar-ui/vue-grid";
import { getData } from "../data";
import AvatarCell from "../custom/AvatarCell.vue"; //import the component
const { data } = getData();
const columns = [
{ id: "id", width: 50 },
{ id: "avatar", cell: AvatarCell, width: 350 }, //apply the component to a cell
];
</script>
<template>
<Grid :sizes="{ rowHeight: 70 }" :data="data" :columns="columns" />
</template>
Embedding HTML to header/footer
The next example customizes a footer cell by rendering its text and the icon in it.
<script setup>
const props = defineProps({ cell: {} }); //access cell data
</script>
<template>
<div class="footer-content">
<span>{{ props.cell.text }}</span>
<i class="wxi-check"></i>
</div>
</template>
<style scoped>
.footer-content {
display: flex;
align-items: center;
gap: 6px;
}
.footer-content i {
display: inline-flex;
font-size: 20px;
}
</style>
Now we can import the component and apply it by adding its names as the value of the cell parameter of the footer element in the columns array.
<script setup>
import { Grid } from "@svar-ui/vue-grid";
import { getData } from "../data";
import FooterTextCell from "../custom/FooterTextCell.vue";
const { data } = getData();
const columns = [
{
id: "id",
width: 50,
footer: [
{
cell: FooterTextCell,
colspan: 3,
text: "Custom footer content",
},
],
}
];
</script>
<template>
<Grid :data="data" :columns="columns" footer />
</template>
Embedding Core components
The snippet below shows how to add a Button to a column cell. To connect button state with item data, use defineProps to access row and column objects. This is how the component looks like:
<script setup>
import { Button } from "@svar-ui/vue-core";
const props = defineProps({ row: {}, column: {} }); // access row and column data
</script>
<template>
<Button type="primary" :disabled="!props.row[props.column.id]">
Show on map
</Button>
</template>
Now you can render it in a column cell by adding its name to the cell parameter of a column element in the columns array:
<script setup>
import { Grid } from "@svar-ui/vue-grid";
import { getData } from "../data";
import ButtonCell from "../custom/ButtonCell.vue"; // import
const { data } = getData();
const columns = [
{
id: "city",
cell: ButtonCell, // add to a cell
width: 260,
},
//other columns
];
</script>
<template>
<Grid :data="data" :columns="columns" />
</template>
Similarly, you can create a button within a header cell.
<script setup>
import { Button } from "@svar-ui/vue-core";
</script>
<template>
<Button type="secondary" icon="wxi-plus">Add row</Button>
</template>
Now we can import the component and apply it to a header cell by adding its name as the value of the cell parameter of the header element in the columns array.
<script setup>
import { Grid } from "@svar-ui/vue-grid";
import { getData } from "../data";
import HeaderButtonCell from "../custom/HeaderButtonCell.vue";
const { data } = getData();
const columns = [
{
id: "id",
header: [{ cell: HeaderButtonCell }],
},
//other columns
];
</script>
<template>
<Grid :data="data" :columns="columns" />
</template>
Enabling interactivity
To enable communication between custom components and Grid, use either of the following ways:
Executing Grid actions
Use defineProps to access Grid api and execute actions directly, e.g. add-row:
<script setup>
import { Button } from "@svar-ui/vue-core";
const props = defineProps({ api: {} });
function onClick() {
props.api.exec("add-row", { row: { city: "New York"}});
}
</script>
<template>
<Button type="secondary" icon="wxi-plus" :onclick="onClick">Add row</Button>
</template>
Or, you can use the onaction property that allows sending a callback event to Grid. You can pass any existing Grid action with its parameters, and it will be executed by inner code:
<script setup>
import { Button } from "@svar-ui/vue-core";
const props = defineProps({ onaction: { type: Function } });
function onClick() {
props.onaction?.({
action: "add-row", //Grid action name
data: { row: { city: "New York"}}, //action parameters
});
}
</script>
<template>
<Button type="secondary" icon="wxi-plus" :onclick="onClick">Add row</Button>
</template>
Calling custom events
You can send a custom event in the onaction callback and handle it at your Grid level. For example:
<script setup>
import { Button } from "@svar-ui/vue-core";
const props = defineProps({ row: {}, column: {}, onaction: { type: Function } });
function onClick() {
props.onaction?.({
action: "custom-button", // call custom event
data: {
column: props.column.id,
row: props.row.id,
},
});
}
</script>
<template>
<Button type="primary" :disabled="!props.row[props.column.id]" :onclick="onClick">
Show on map
</Button>
</template>
Now handle this custom event in Grid. Beware that the on prefix should be added and a hyphen in the event name should be removed:
<script setup>
import { Grid } from "@svar-ui/vue-grid";
import ButtonCell from "../custom/CheckboxCell.vue"
import { getData } from "../data";
const { data } = getData();
const columns = [
{
header: "City",
cell: ButtonCell,
width: 260,
},
//other columns
];
function action(ev) {
const { row, column } = ev;
// e.g. open in Maps the city from row data
}
</script>
<template>
<Grid
:data="data"
:columns="columns"
:oncustombutton="ev => action(ev)"
/>
</template>
Use cases
Practical usage examples you can find here:
- Applying custom editors
- Adding an Action menu
- Adding custom content to cells
- Creating a master checkbox in header
If you are interested to know how to apply custom styles to a cell, see the Styling section.
Related samples
Related articles: