DHTMLX Pivot. Adding HTML content for table and header cells example
Demo of custom HTML content in DHTMLX Pivot table and header cells. Insert country flag icons, star ratings, and status arrow indicators using the render-table intercept and pivot.template() API.
Live example
const widget = new pivot.Pivot("#pivot", {
tableShape: {
tree: true,
totalColumn: true,
totalRow: true
},
fields,
data: dataset,
config: {
rows: [
"id",
"protocol",
"user_score"
],
columns: [
"status"
],
values: [
{
field: "bandwidth",
method: "average"
}
]
}
});
function idTemplate(value) {
if (value) {
const name = value.toString().split("-")[0];
value = `<span class="cell-id flag-${name}"></span> ${value}`;
}
return value;
}
function scoreTemplate(value, method) {
return value = `<i class="cell-score wxi-star"></i> ${value}`;
}
function rowsHeaderTemplate(value, field) {
let icon = "";
if (field == "id") icon = "<i class='icon wxi-earth'></i>"
if (field == "user_score") icon = "<i class='icon wxi-star'>";
return value + icon;
}
function statusTemplate(value) {
let icon = "";
if (value == "Up") icon = "<i style='color:green' class='icon wxi-arrow-up'></i>"
if (value == "Down") icon = "<i style='color:red' class='icon wxi-arrow-down'>";
return value + icon;
}
function cellTemplate(value, method, row, column) {
const field = column.fields ? column.fields[row.$level] : column.field;
if (field == "id")
return idTemplate(value);
if (field == "user_score")
return scoreTemplate(value);
else return value;
}
widget.api.intercept("render-table", ({ config: tableConfig }) => {
tableConfig.columns = tableConfig.columns.map((c) => {
if (c.area == "rows") {
c.cell = pivot.template(({value, method, row, column}) => cellTemplate(value, method, row, column))
c.header[0].cell = pivot.template(({value, field}) => rowsHeaderTemplate(value, field));
}
else{
const row = c.header.find((c) => c.field == "status");
if(row)
row.cell = pivot.template(({value, field}) => statusTemplate(value, field));
}
return c;
});
});
<!-- component container -->
<div id="pivot" class="pivot" style="width: 100%; height: 100%;"></div>
<!-- custom styles -->
<style>
.pivot .icon{
margin-left: 10px;
font-size: 18px;
cursor: pointer;
}
.pivot .cell-score{
color: #fdbf4c;
margin-right: 2px;
}
.pivot .wx-grid .wx-cell .cell-id {
padding-left: 30px;
background-size: 20px 15px;
background-repeat: no-repeat;
background-position: 0px center;
height: 15px;
}
.flag-de {
background-image: url("https://snippet.dhtmlx.com/codebase/data/combobox/01/img/de.png");
}
.flag-es {
background-image: url("https://snippet.dhtmlx.com/codebase/data/combobox/01/img/es.png");
}
.flag-fr {
background-image: url("https://snippet.dhtmlx.com/codebase/data/combobox/01/img/fr.png");
}
.flag-it {
background-image: url("https://snippet.dhtmlx.com/codebase/data/combobox/01/img/it.png");
}
.flag-se {
background-image: url("https://snippet.dhtmlx.com/codebase/data/combobox/01/img/se.png");
}
.flag-uk {
background-image: url("https://snippet.dhtmlx.com/codebase/data/combobox/01/img/se.png");
}
</style>
<script>
const dataset = [
{
"id": "fr-0001",
"status": "Up",
"rtt": 20,
"bandwidth": 1200,
"protocol": "OpenVPN",
"encryption": "AES-256",
"active_users": 100,
"uptime": 72,
"downtime": 1,
"p2p": "yes",
"streaming": "yes",
"ip_pool": 3500,
"ping": 98,
"user_score": 4.7
},
{
"id": "de-0001",
"status": "Up",
"rtt": 15,
"bandwidth": 1500,
"protocol": "OpenVPN",
"encryption": "AES-256",
"active_users": 90,
"uptime": 96,
"downtime": 0,
"p2p": "yes",
"streaming": "yes",
"ip_pool": 3595,
"ping": 99,
"user_score": 4.8
},
// ... 148 more items (see Live Editor for full data)
];
const fields = [
{
"id": "id",
"label": "ID",
"type": "text"
},
{
"id": "status",
"label": "Status",
"type": "text"
},
{
"id": "rtt",
"label": "RTT",
"type": "number"
},
{
"id": "bandwidth",
"label": "Bandwidth",
"type": "number"
},
{
"id": "protocol",
"label": "Protocol",
"type": "text"
},
{
"id": "encryption",
"label": "Encryption",
"type": "text"
},
{
"id": "active_users",
"label": "Active Users",
"type": "number"
},
{
"id": "uptime",
"label": "Uptime",
"type": "number"
},
{
"id": "downtime",
"label": "Downtime",
"type": "number"
},
{
"id": "p2p",
"label": "p2p",
"type": "text"
},
{
"id": "streaming",
"label": "Streaming",
"type": "text"
},
{
"id": "ip_pool",
"label": "IP Pool",
"type": "number"
},
{
"id": "ping",
"label": "Ping",
"type": "number"
},
{
"id": "user_score",
"label": "User score",
"type": "number"
}
];
</script>Plain text values in pivot tables often lack the visual context users need for quick scanning. When displaying server IDs with country prefixes, status indicators, or rating scores, raw text forces users to mentally parse each value. Adding visual cues like flag icons, directional arrows, and star symbols dramatically improves data comprehension at a glance.
DHTMLX Pivot provides the render-table intercept event and pivot.template() function for injecting custom HTML into both data cells and header cells. This approach lets you transform plain values into rich visual content - country flags next to server IDs, colored arrows for Up/Down status, and star icons for user scores - without modifying the underlying data.
This example demonstrates custom HTML templates applied to multiple cell types simultaneously: row data cells with flag icons and star ratings, and column header cells with colored status arrows. The implementation uses the widget.api.intercept("render-table", ...) method to modify column configurations before rendering.
Solution overview
To add custom HTML content to pivot cells, intercept the render-table event and modify column configurations. For each column, assign a cell property using pivot.template() which accepts a function returning an HTML string. The template function receives the cell's value, aggregation method, row data, and column metadata.
For row area columns, the code applies cellTemplate() which dispatches to idTemplate() (adds country flag icons via CSS background images) or scoreTemplate() (prepends a star icon). Header cells in the row area use rowsHeaderTemplate() to append earth and star icons. For data columns, the statusTemplate() adds colored up/down arrows to header cells based on the status field value.
Key points
- Intercept-based approach: The
widget.api.intercept("render-table", ...)method modifies column configs before rendering, allowing HTML injection without changing the Pivot's internal data structure - Separate templates for areas: Row area columns use
c.cellfor data cells andc.header[0].cellfor header labels, while data columns target specific header rows by field name - CSS-driven flag icons: Country flags are rendered as CSS background images on
<span>elements, with flag classes (.flag-de,.flag-fr, etc.) mapped from the ID prefix - Icon library integration: The
wxi-*icon classes (wxi-earth, wxi-star, wxi-arrow-up, wxi-arrow-down) come from DHTMLX's built-in icon set, requiring no additional icon library
API reference
- Pivot render-table intercept: Event fired before table rendering, allowing modification of column configurations.
- pivot.template(): Creates a template function for rendering custom HTML content in cells.
- Pivot tableShape: Configuration object for table appearance including tree mode, totals, and templates.