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 wx-svelte-core library)
- in the component, access Grid properties via
$props
, 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 $props
:
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>
let { row } = $props();// access Grid row data
</script>
<div class="container">
<div class="avatar">
<div class="user-avatar">
{#if row.avatar}
<img class="user-photo" alt="" src={row.avatar} />
{/if}
</div>
</div>
<div class="info">
<div class="name">{row.lastName}</div>
<div class="mail">{row.email || ""}</div>
</div>
</div>
<style>
.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>
import { Grid } from "wx-svelte-grid";
import { getData } from "../data";
import AvatarCell from "../custom/AvatarCell.svelte"; //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>
<Grid sizes={{ rowHeight: 70 }} {data} {columns} />
Embedding HTML to header/footer
The next example customizes a footer cell by rendering its text and the icon in it.
<script>
let { cell } = $props(); //access cell data
</script>
<div class="footer-content">
<span>{cell.text}</span>
<i class="wxi-check"></i>
<style>
.footer-content {
display: flex;
align-items: center;
gap: 6px;
}
.footer-content i {
display: inline-flex;
font-size: 20px;
}
</style>
</div>
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>
import { Grid } from "wx-svelte-grid";
import { getData } from "../data";
import FooterTextCell from "../custom/FooterTextCell.svelte";
const { data } = getData();
const columns = [
{
id: "id",
width: 50,
footer: [
{
cell: FooterTextCell,
colspan: 3,
text: "Custom footer content",
},
],
}
];
</script>
<Grid {data} {columns} footer />
Embedding Core components
The snippet below shows how to add a Button to a column cell. To connect button state with item data, use $props
to access row and column objects. This is how the component looks like:
<script>
import { Button } from "wx-svelte-core";
let { row, column } = $props();// access row and column data
</script>
<Button type="primary" disabled={!row[column.id]}>
Show on map
</Button>
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>
import { Grid } from "wx-svelte-grid";
import { getData } from "../data";
import ButtonCell from "../custom/ButtonCell.svelte"; // import
const { data } = getData();
const columns = [
{
id: "city",
cell: ButtonCell,// add to a cell
width: 260,
},
//other columns
];
</script>
<Grid {data} {columns} />
Similarly, you can create a button within a header cell.
<script>
import { Button } from "wx-svelte-core";
</script>
<Button type={"secondary"} icon="wxi-plus">Add row</Button>
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>
import { Grid } from "wx-svelte-grid";
import { getData } from "../data";
import HeaderButtonCell from "../custom/HeaderButtonCell.svelte";
const { data } = getData();
const columns = [
{
id: "id",
header: [{ cell: HeaderButtonCell }],
},
//other columns
];
</script>
<Grid {data} {columns} />
Enabling interactivity
To enable communication between custom components and Grid, use either of the following ways:
Executing Grid actions
Use $props
to access Grid api and execute actions directly, e.g. add-row
:
<script>
import { Button } from "wx-svelte-core";
let { api } = $props();
function onClick() {
api.exec("add-row", { row: { city: "New York"}});
}
</script>
<Button type={"secondary"} icon="wxi-plus" onclick={onClick}>Add row</Button>
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>
import { Button } from "wx-svelte-core";
let { onaction } = $props();
function onClick() {
onaction &&
onaction({
action: "add-row", //Grid action name
data: { row: { city: "New York"}}, //action parameters
});
}
</script>
<Button type={"secondary"} icon="wxi-plus" onclick={onClick}>Add row</Button>
Calling custom events
You can send a custom event in the onaction
callback and handle it at your Grid level. For example:
<script>
import { Button } from "wx-svelte-core";
let { row, column, onaction } = $props();
function onClick() {
onaction &&
onaction({
action: "custom-button", // call custom event
data: {
column: column.id,
row: row.id,
},
});
}
</script>
<Button type="primary" disabled={!row[column.id]} onclick={onClick}>
Show on map
</Button>
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>
import { Grid } from "wx-svelte-grid";
import ButtonCell from "../custom/CheckboxCell.svelte"
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>
<Grid
{data}
{columns}
oncustombutton={ev => action(ev)} //handle the custom event
/>
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 articles: