Custom Columns

Custom columns allow you to override or extend ZingGrid’s default cell behavior. You can achieve this via Slotted Tokens, Slotted Row/Card Content, renderer, and registerCellType.

Slotted Tokens

You can format column data by adding slotted data (e.g., a <span> tag) to <zg-column>. ZingGrid has two interchangeable tokens, index and record, that you can use to access any data key from your grid using index.key or record.key, like so:

<zg-column index="status">
  <span class="build-status build-[[index.status]]"></span>
<zg-column index="branch,commitId" header="Branch - Commit - RunTime">
  <span>[[index.branch]] - [[index.commitId]] - [[record.runTime]]</span>

Slotted Tokens Grid

Here is a complete grid which utilizes index.key and record.key to access slotted data:


Slotted Row Content

Directly put markup in a cell with the type attribute, like so:

<zg-column type="custom">
    <option value="1">Restart Build</option>
    <option value="2">Reset Cache</option>

Slotted Row Content Grid

Here is a complete grid with markup as slotted row content:


Slotted Card Content

You can also directly put markup in the card mode of the grid with the <zg-card> tag, like so:

    <h2>Pipeline Information</h2>
    <div>Status: [[record.status]]</div>
    <div>Branch: [[record.branch]]</div>
    <div>Run Time: [[record.runTime]]</div>
    <div>Commit: [[record.status]]</div>
      <div>Username: [[record.status]]</div>
      <img src="[[record.avatar]]">
        <option value="1">Restart Build</option>
        <option value="2">Reset Cache</option>

In this case, we don't define any <zg-column> tags because we are only displaying card mode.

Slotted Card Grid

Here is a complete grid with slotted content in card mode:


renderer Function

You can use a custom renderer function to add actions on each cell (see below). Default arguments to the renderer function are indices that reference the cell. For example, if you have index="branch, username", the function definition will be function(branch,username,$cell). In the callback, you have direct access to the <zg-cell> DOM contents through $cell.dom() and direct information related to the row through $cell.record.

function addChangeEvent(customIndex, $cell) {
  // $cell.record gives us us direct information related to this row
  const record = $cell.record;
  // $cell.dom() gives us direct access to zg-cell DOM contents
  const selectRef = $cell.dom().querySelector('select');
  selectRef.addEventListener('change', e => {
    const changeValue =;
    if (changeValue == 1) alert(`Restarting pipeline on branch: ${record.branch}-${record.commitId}`);
    else alert('Resetting cache');

Only attempt to bind events to contents of <zg-cell> and not the tag itself! The code snippet above does not break any rules because it binds an event to the <select> element, a content of <zg-cell>. Do not bind events directly to <zg-cell> or <zg-row> as these components are reused to enhance performance. To bind events to <zg-cell> or <zg-row>, please use ZingGrid's custom events.

renderer Function Grid

Here is a complete grid with custom renderer functions on the cells:


registerCellType Function

Easily register your own column type by creating a custom renderer function and/or editor function, like so:

ZingGrid.registerCellType('upper', {
  renderer: upperRenderer,

Read more about registerCellType() in our ZingGrid Object Methods docs.

Custom Registered Column Type Grid

Here is a complete grid with custom registered column types:


Column Tag Type

The <zg-column> tag can render any single DOM element inside itself with the type-element-tag-name attribute, like so:

<zg-column index="name" type="element" type-element-tag-name="h1"></zg-column>
<zg-column index="number" type="element" type-element-tag-name="em"></zg-column>
<zg-column index="age" type="element" type-element-tag-name="b"></zg-column>

Column Tag Type Grid

Here is a complete grid with DOM elements rendered in <zg-column>:


Single Row/Cell

You can combine all the concepts above to create a single row template, like so:

  caption="Current Pipelines">
      index="status, branch, username, commitId, runTime, avatarUrl"

We force a row layout with layout="row" so that the card layout is not applied on smaller browsers (i.e., tablet and mobile devices).

Single Row/Cell Grid

Here is a complete grid with a single row template:


Related Resources

Here are some extra resources related to this feature to help with creating your grid: