Skip to main content
Version: 13.x (Current)

Table

<bk-table></bk-table>

table

The Table displays a dataset in rows and columns according to a given data-schema. An actions column can be configured to add extra functionalities.

The Table listens to the display-data event to initialize its form.

By clickinging on a row, the Table issues a request to prompt the user with a way of editing/visualizing the corresponding item - ie, emits a selected-data event. A component like the Dynamic Form Modal could act upon such request.

By default, rows can be selected through a checkbox. When this happens, the Table notifies it by emitting a selected-data-bulk event.

How to configure

The Table needs to be provided with a data-schema in order to understand the structure of the dataset to render

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"surname": {"type": "string"}
}
}
}
}

Object and Array Fields

While rendering an array or an object from a compliant data-schema (either array or object key type), multiple options are available

Object

The Table can render object fields in various ways, depending on the field description in the provided data-schema.

  1. When no extra key is explicitly set, the object renders either as {...} or {} depending on whether there are keys or not.
  2. When a data-schema is set to the object field description, the Table triggers nested visualization of objects.
  3. When the object field is specified to have format equal to "localized-text", the object must be interpreted as a localized string. The Table will render the proper language key according with browser settings.
  4. When the object field is set to have specific visualization-options, the Table renders the field accordingly. In particular, the template key of the visualization-options is useful with object fields, as it interpolates an handlebars template using the current cell context.
    {
    "user": {
    "type": "object",
    "visualizationOptions": {
    "template": "{{name}} {{surname}}"
    }
    }
    }
    Hence if datum is given by
    {
    "name": "john",
    "surname": "does"
    }
    and template is "{{name}} {{surname}}", then the table renders john doe.

An example is available showcasing how a Table can be configured to display object data.

Array

The Table can render array fields in various ways, depending on the field description in the provided data-schema.

  1. When no extra key is explicitly set, the array informs about the number of elements contained within the array.
  2. When a data-schema is set to the object field description, the Table triggers nested visualization of arrays.
  3. When the array field is set to have specific visualization-options, the Table renders the field accordingly.
    • The joinDelimiter key of the visualization-options joins the array elements using the given delimiter as argument of Array.prototype.join
    {
    "users": {
    "type": "array",
    "visualizationOptions": {
    "joinDelimiter": ","
    }
    }
    }
    • The template key of the visualization-options interpolates an handlebars template using the current cell context.
    {
    "users": {
    "type": "array",
    "visualizationOptions": {
    "template": "{{[0]}} {{[1]}}"
    }
    }
    }
    Hence if datum is given by
    [
    "Ding", "Magnus", "Ian"
    ]
    and template is {{[0]}}, {{[1]}}, ..., then the table renders Ding, Magnus, ....

An example is available showcasing how a Table can be configured to display array data.

Nested Data

By default, the Table is responsive to emitted requests for showing nested data. Namely, the Table listens to events:

Upon receiving these events, the Table updates itself to show the details of the currently displayed nested field.

This behavior can be disabled by setting property allowNavigation to false.

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {"type": "string"},
"name": {"type": "string"},

"spouse": {
"type": "object",
"dataSchema": { // <-- nested data-schema, for spouse object
"type": "object",
"properties": {
"mame": {"type": "string"},
"address": {"type": "string"}
}
}
},

"children": {
"type": "array",
"items": { // <-- nested data-schema, for children array
"type": "object",
"properties": {
"firstName": {"type": "string"},
"dateOfBirth": {"type": "string", "format": "date"}
}
}
}
}
}
}
}

The Table allows to emit nested-navigation-state/push events by clicking on cells that contain nested objects or arrays, as long as a nested schema is provided for the corresponding field. If a component such as the Pagination receives such requests, a nested-navigation-state/display event is emitted, triggering the Table to update itself and display the nested data.

By default, the Table renders a button in the action column in nested visualizations, if the field is not readonly, which allows to request the object represented by the corresponding row to be deleted. To remove the default actions rendered by the Table in nested visualization, navigationRowAction property should be set to:

{
"kind": "icons",
"actions": []
}
caution

Components such as the Breadcrumbs and the Pagination should always be included in the plugin when navigation is enabled.

Display Path

Property displayedDataPath enables to display a nested array of an element of the received data. It consists of the path to the desired object, like: data.[0].orders. The first key is always data.

Upon listening to a display-data event, which lists fetched data, the Table uses property displayDataPath to reach an array field, and attempts to display that field according to the provided data-schema. Therefore, the data-schema must describe the field reached by displayDataPath, rather than the all the fields of the underlying collection.

{
"tag": "bk-table",
"properties": {
"displayedDataPath": "data.[0].orders", // -> enters `orders` field of first data item
"dataSchema": { // -> data-schema of `orders` field
"type": "object",
"properties": {
"name": {
"type": "string"
},
"price": {
"type": "number"
}
}
}
}
}

Refer to the provided example for further details.

Dynamic Context

Several properties of the Table allow dynamic configurations. By default, such properties are parsed with handlebars, injecting the the following data as context:

  • args: an array with the arguments of a table cell:
    • value: containing the value of the cell
    • record: an object representation of the corresponding row
    • index: a number with the index of the corresponding row into the table
  • currentUser: an object with the logged user's data
  • headers: an object containing the headers

All the above parameters can be dynamically interpolated into properties that allow dynamic configurations through handlebars.

Web Component into cells

The Table allows to insert a generic web-component into the the cells of a specific column by defining, in the data-schema description of the corresponding field, all the web-components properties inside the visualization-options.

Refer to the below example for an example of configuration.

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"label": "Name as Button",
"visualizationOptions": {
"tag": "my-button",
"properties": {
"content": "Click Me!"
}
}
}
}
}
}
}

Dynamically mounted components are automatically injected with the property eventBus, which is the communication channel shared by components. This allows mounted components to communicate with other components by events emission.

The Table supports dynamic configurations in dynamically mounted components properties, providing access in its configuration to its context.

An example is available showing how to configure a Table to include a button inside a cell that performs a POST request with the corresponding row as body, as well as an example to include a button that is active or disabled based on the value of a within in the corresponding row.

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"label": "Name as Button",
"visualizationOptions": {
"tag": "my-button",
"properties": {
"content": "{{args.[0]}}" // the value of the `name` field is injected as property to the component
}
}
}
}
}
}
}

Actions

The Table allows to configure an actions column. Configurable buttons or generic components are rendered inside the actions columns, and can be controlled through properties rowActions, customActions, navigationRowActions.

Configuring actions via rowActions

Each action specified through property rowActions is rendered as a button inside the action cell of each row of the table.

Actions configured this way can either

  • emit an event, or
  • perform an POST call

in both cases, the payload/body is set to an object representation of the corresponding row.

Property rowActions accepts an object with keys kind and actions.

propertytypevaluesdescription
kindstring"icons", "cta"how to display the action triggers
actionsarray-available actions
{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {"type": "string"}
}
},
"rowActions": {
"kind": "icons",
"actions": [
{
"kind": "event",
"danger": "true",
"content": "duplicate-data",
"label": "Duplicate Data",
"icon": "far fa copy",
"meta": {},
"requireConfirm": false
}
]
}
}
}

Each entry of key actions is mapped to a call to action and rendered as a button.

propertytypevaluesdescription
kindstringhttpPost, eventwhen event fires an event in the eventBus, otherwise performs a POST request with the content of the row as body
dangerbooleantrue, false, undefinedset danger mode on action. Defaults to false
contentstring-when event it is the label of the events to emit, otherwise the POST request destination href
labelstring-a label to render with the row action button
iconstring-Fontawesome fas or far icon
metaobject-the meta of the event when kind is event
requireConfirmobject or boolean-signals the need to prompt user confirmation before executing the action. Defaults to false

An example is available to showcase how to configure rowActions property in the Table.

If the key requireConfirm is undefined or set to false, the corresponding CTA does not expect user confirmation before execution. When set to true, the CTA indicates the need for user confirmation before execution. This is achieved by emitting a require-confirm event. Additionally, the property requireConfirm can be configured as an object to request specific labels to be associated with the confirmation prompt presented to the user. This is achieved by emitting a require-confirm event, injecting the specified object into the event payload, and involves specifying the following keys:

propertytypevaluesdescription
cancelTextobject-Cancel button localized label
contentobject-Localized label used as content of the modal
okTextobject-Confirm button localized label
titleobject-Localized label used as title of the modal

Keys content and title support interpolation via handlebars using the current row values with resolved lookups. For instance, the following is a valid entry for key "content":

Confirmation needed before deleting item: {{name}}. Continue?

where {{name}} is resolved with the content of field "name" in the row corresponding to the clicked row.

Configuring actions via customActions

Property customActions allows to mount web-components inside the action column of the Table.

{
{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {"type": "string"}
}
},
"customActions": [{
"tag": "bk-button",
"properties": {
"content": "My button"
}
}]
}
}
}

Property customActions shape is either an array of tag-properties pairs or an array of nested custom actions, as per the following schema:

{
"type": "array",
"oneOf": [
{
"type": "object",
"properties": {
"tag": "string",
"properties": {
"type": "object"
}
}
},
{
"type": "object",
"properties": {
"keys": {
"type": "array",
"items": {
"type": "string"
}
},
"customActions": {
"type": "object",
"properties": {
"tag": "string",
"properties": {
"type": "object"
}
}
}
}
}
]
}

In the first case, each element of the array is a tag-properties pair, respectively representing the html tag of the component to mount and its properties.

propertytypevaluesdescription
tagstringstringcustom component to mount
properties{[key: string]: any}objectproperties injected into the component

It is often useful mounting the Button components inside the actions columns of the Table because of its flexibility.

An example is available to showcase how to configure customActions property in the Table.

The Table supports dynamic configurations in the properties field of web-components mounted this way, providing access in its configuration to its context.

An example is available to show how dynamic configurations can be integrated with customActions property.

Nested navigation does not preserve customActions. To configure customActions in nested navigation mode the second type of customActions allowed by the JSON schema above is helpful.

A full configuration example is available to show how customActions can be used to set CTAs inside a Table in a nested view.

{
"customActions": [
{
"keys": [],
"customActions": [ // <-- Table actions before entering nested data
{
"tag": "bk-button",
"properties": {...}
}
]
},
{
"keys": ["level1", "level2"],
"customActions": [ // <-- Table actions when visualizing data inside "level1.level2"
{
"tag": "bk-button",
"properties": {...}
}
]
}
]
}

Configuring nested actions via navigationRowActions

The Table does not preserve actions created with rowActions property when is rendering nested data. Property navigationRowActions allows to specify actions available when the table is displaying nested data.

As of now, actions created via navigationRowActions only allow to signal the need to edit the data of the corresponding table row, or to delete the item represented by the corresponding Property customActions should be utilized in order to configure actions in nested views with a greater degree of freedom.

navigationRowActions is an object such as

propertytypevaluesdescription
kindstringcta, iconswhether to display the action in form of text or icon.
actionsarray of actionsanydescribes the behavior of each.

Where each entry of actions represent

propertytypevaluesdescription
requireConfirmbooelan-Whether or not to require confirm before executing the action
dangerboolean-set danger mode on action
typestring"delete" | "detail"whether to request deletion or edit of the object associated to the corresponding row.
disableInReadonlyboolean-Whether or not to disable the action for read-only nested objects.
iconstringstringThe fontawesome icon for the button
  {
"kind": "icons",
"actions": [{
"danger": true,
"requireConfirm": true,
"type": "delete",
"disableInReadonly": true,
"icon": "far fa-trash-can"
}]
}

Property navigationRowAction defaults to:

{
"kind": "icons",
"actions": [{
"requireConfirm": true,
"type": "delete",
"disableInReadonly": true
}]
}

which will alllow to request rows to be deleted when the displayed nested data is not read-only.

To remove the default actions rendered by the Table in nested visualization, navigationRowAction should be set to:

{
"kind": "icons",
"actions": []
}

Fix columns

Property fixedColumns can be used to fix columns with respect to horizontal scrolling. It takes either a number that represents the number of columns to fix from left or an object with left and/or right keys and a number as value.

The following are all valid configurations of fixedColumns property:

{
"tag": "bk-table",
"properties": {
"fixedColumns": {
"left": 2,
}
}
}
{
"tag": "bk-table",
"properties": {
"fixedColumns": {
"right": 1
}
}
}
{
"tag": "bk-table",
"properties": {
"fixedColumns": {
"left": 2,
"right": 1
}
}
}
{
"tag": "bk-table",
"properties": {
"fixedColumns": 2 // equivalent to: "fixedColumns": {"left": 2}
}
}

Highlighted rows

It is possible to use property highlightedRows to map a color (expressed as a CSS-valid color string) to a mongo-like query. The background of rows that match any of these queries is set to the corresponding color. In particular, rows are highlighted with the color of the first matching query.

Property highlightedRows should be expressed as an array of objects with keys color and query.

  • the color can be expressed as the CSS valid string representation of a color, or an object with keys r, g, b The following are all valid entries:
    #f2e8e2
    rgb(230, 155, 114)
    {r: 230, g: 155, b: 114}
    Broadly speaking, color key supports all types supported as input by TinyColor library.
  • the query is the object representation of a mongo-like query

An example is available to show how to configure highlighted rows in the Table.

info

Input colors are converted to their RGB representation. If an alpha channel is present, a white background is assumed. For instance, color rgba(255, 0, 0, 0.5) is converted to rgb(255, 128, 128).

Queries support dynamic values through handlebars notation. The Table provides inline queries with context:

  • args: an array with row arguments:
    • first element and second element both have an object containing the row content
    • third element stores the number with the cell index within the table rows
  • currentUser: an object with the logged user's data
  • headers: an object containing the headers

An example is available to show how to leverage dynamic configuration when configuring highlighted rows in the Table.

Browse on row click

The property browseOnRowSelect allows to navigate to a specified link when a table row is clicked, overriding the default behavior. browseOnRowSelect accepts an object such as

{
"href": "destination/url",
"target": "_self",
"query": {
"id": "{{data._id}}"
},
"navigationType": "push"
}
propertytypevaluesdescription
hrefstring-link reference. Only relative links are accepted.
targetstring-where to open the href. Defaults to "_self"
query{[key: string]: any}-query parameters
navigationTypestring"push", "replace", "href"method used for navigation if target is "_self"

Where navigationType values are mapped to navigation methods as follows:

valuemethod
pushwindow.history.push
replacewindow.history.replace
hrefwindow.location.replace

File Fields

Fields that have type array or object and format file contain metadata information about one or multiple files stored in file storage service. Property openFileInViewerRegex allows to control how the Table interacts such file fields.

openFileInViewerRegex is either a string, an array of strings, or an object that maps a string to one between "view" and "download".

type FileInViewerRegex = string | string[] | {
[regex: string]: "view" | "download"
}

openFileInViewerRegex represents a set of regex expressions, which are matched against the name of the files stored in file cells. If one matches, the corresponding cell becomes clickable and the file is requested to be opened inside a viewer (default) or is requested to be downloaded. Both actions are achieved by emitting a download-file event, injecting key showInViewer to the meta of the event to control whether to download or visualize the file.

Locale

The texts of the Table can be customized through the property customLocale, which accepts an object shaped like the following:

type Locale = {
actionsTitle?: LocalizedText
element?: LocalizedText
elements?: LocalizedText
moreActions?: LocalizedText
}

where LocalizedText is either a string or an object mapping language acronyms to strings.

Examples

Example: Object Visualization

Assuming an instance of the Table configured like:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "object",
"format": "localized-text"
},
"book": {
"type": "object",
"visualizationOptions": {
"template": "{{code}} - {{price}} $"
}
}
}
}
}
}

displaying data like:

[
{
"name": "Deledda",
"description": {
"en": "Nobel prize winner in 1926",
"it": "Vincitrice del premio nobel nel 1926"
},
"book": {
"code": "cv-432",
"name": "Canne al vento",
"price": 10
},
},
{
"name": "Hesse",
"description": {
"en": "Nobel prize winner in 1946",
"it": "Vincitore del premio nobel nel 1946"
},
"book": {
"code": "st-123",
"name": "Steppenwolf",
"price": 12
}
}
]

assuming the browser language to be English, then the rendered data can be represented by an array as:

[
["Deledda", "Nobel prize winner in 1926", "cv-432 - 10 $"],
["Hesse", "Nobel prize winner in 1946", "st-123 - 12 $"]
]

Example: Array Visualization

Assuming an instance of the Table configured like:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"colors": {
"type": "array",
"visualizationOptions": {
"template": "{{[0]}}, {{[1]}} and more"
}
},
"sizes": {
"type": "object",
"visualizationOptions": {
"joinDelimiter": ","
}
}
}
}
}
}

displaying data like:

[
{
"name": "Pants",
"colors": ["black", "blue", "gray"],
"sizes": ["s", "m", "l", "xl"]
},
{
"name": "Shirt",
"colors": ["red", "yellow", "blue", "brown"],
"sizes": ["m", "xl"]
}
]

then the rendered data can be represented by an array as:

[
["name", "colors", "sizes"], // table header
["Pants", "black blue and more", "s, m, l, xl"],
["Shirt", "red yellow and more", "m, xl"]
]

Example: Web Component inside cells

An instance of the Table configured like the following:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"label": "Name as Button",
"visualizationOptions": {
"tag": "bk-button",
"properties": {
"content": "Click Me!"
}
}
}
}
}
}
}

mounts a Button component inside each cell of the "name" column, injected with the specified properties.

Example: Dynamic Web Component (POST call with row as body)

Given the following configuration for an instance of the Table:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"label": "CTA",
"visualizationOptions": {
"tag": "bk-button",
"properties": {
"content": "{{currentUser.name}}",
"action": {
"type": "http",
"config": {
"method": "POST",
"url": "/path?{{args.[1].id}}={{args.[1]}}",
"body": "{{rawObject args.[1]}}",
"config": {
"headers": "{{rawObject headers}}"
}
}
}
}
}
}
}
}
}
}

And this (simplified) context:

  • args

      ["Column Name", {"id": "row-id"}, 4]
  • currentUser

      { "name": "Bob" }
  • headers

      { "content-type": "application/json" }

Then the above configuration is equivalent to:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"label": "CTA",
"visualizationOptions": {
"tag": "bk-button",
"properties": {
"content": "Bob",
"action": {
"type": "http",
"config": {
"method": "POST",
"url": "/path?row-id=4",
"body": {
"id": "row-id"
},
"config": {
"headers": {
"content-type": "application/json"
}
}
}
}
}
}
}
}
}
}
}

which renders a table in which cells of column "name" include a Button that perform a POST call. The Button properties depend on the data in the the clicked row.

info

rawObject is a helper keyword that prevents "values" from being stringified in the body of the request.

Example: Dynamic Web Component (disable button depending on row value)

It is possible to provide a template-configMap pair instead of a value for a property. In such cases, the value of the property is taken from the configMap using template as key (or $default, if the template does not match any configMap key).

For instance, the following configuration:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"label": "CTA",
"visualizationOptions": {
"tag": "bk-button",
"properties": {
"content": "Abort order",
"disabled": {
"template": "{{currentUser.role}}",
"configMap": {
"Superadmin": false,
"Admin": false,
"$default": true
}
}
}
}
}
}
}
}
}

renders a table in which cells of column "name" include a Button that is always disabled unless the current user has property role set to "Admin" or "Superadmin".

Example: visualize one element's array field (displayedDataPath)

In this example, the Table displays the value of the orders array field of the first element received.

{
"tag": "bk-table",
"properties": {
"displayedDataPath": "data.[0].orders", // -> enters `orders` field of first data item
"dataSchema": { // -> data-schema of `orders` field
"type": "object",
"properties": {
"name": {
"type": "string"
},
"price": {
"type": "number"
}
}
}
}
}

Upon listening to a display-data event, which lists fetched data, the Table uses property displayDataPath to reach the "orders" field of the first element, and attempts to display that field according to the provided data-schema. Therefore, entries of "orders" are expected to have string field "name" and numeric field "price".

If the payload of the display-data event were to be:

{
"data": [
{
"_id": "id-1",
"orders": [
{"name": "clock", "price": 100},
{"name": "pants", "price": 50},
]
},
{
"_id": "id-2",
"orders": [
{"name": "shirt", "price": 20}
]
}
]
}

then the data rendered by the Table is:

[
{"name": "clock", "price": 100},
{"name": "pants", "price": 50}
]

Example: Action with rowActions

A Table component configured like the following:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {"type": "string"}
}
},
"rowActions": {
"kind": "icons",
"actions": [
{
"kind": "event",
"content": "duplicate-data",
"label": "Duplicate Data",
"icon": "far fa copy"
}
]
}
}
}

renders an action column which includes a button that, upon being clicked, emits a duplicate-data event with an object representation of the corresponding row injected as payload.

Example: Action with customActions

A Table component configured like the following:

{
{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {"type": "string"},
"name": {"type": "string"}
}
},
"customActions": [{
"tag": "bk-button",
"properties": {
"content": "Cancel order",
"action": {
"type": "http",
"config": {
"url": "/cancel-order",
"method": "POST",
"body": "{{rawObject args.[1]}}"
}
}
}
}]
}
}
}

renders an action column which includes a Button that, upon being clicked, emits a POST call to a URL /cancel-order with an object representation of the corresponding row as body.

info

rawObject is a helper keyword that prevents "values" from being stringified in the body of the request.

In particular, assuming data like:

[
{
"_id": "id-1",
"name": "PC"
},
{
"_id": "id-2",
"name": "Mouse"
},
{
"_id": "id-3",
"name": "Smart phone"
}
]

the rendered Table includes an action "Cancel order" in each row. Clicking on the action of the first row triggers a POST request with body:

{
"_id": "id-1",
"name": "PC"
}

Example: Actions in nested table with customActions

Assuming a Table to be configured like the following:

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {"type": "string"},
"articles": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"details": {
"type": "object",
"dataSchema": {
"type": "object",
"properties": {
"code": {"type": "string"},
"fragile": {"type": "boolean"}
}
}
}
}
}
}
}
},
"customActions": [
{
"keys": [],
"customActions": [
{
"tag": "bk-button",
"properties": {
"content": "Cancel order",
"action": {
"type": "http",
"config": {
"url": "/cancel-order",
"method": "POST",
"body": "{{rawObject args.[1]}}"
}
}
}
}
]
},
{
"keys": ["articles", "details"],
"customActions": [
{
"tag": "bk-button",
"properties": {
"content": "Refresh",
"action": {
"type": "http",
"config": {
"url": "/order/{{args.[1].code}}",
"method": "GET"
}
}
}
}
]
}
]
}
}

The action with button Cancel order appears on the home of the nested setup. All other nesting level have no customAction but the details reached from articles which instead displays a button with label Refresh.

In particular, assuming data like:

[
{
"_id": "id-1",
"": [
{
"name": "Pants",
"details": {
"code": "order-123",
"fragile": false
}
},
{
"name": "Sweater",
"details": {
"code": "order-456",
"fragile": false
}
}
]
},
{
"_id": "id-2",
"": [
{
"name": "Vase",
"details": {
"code": "order-987",
"fragile": true
}
}
]
}
]

the rendered Table can be represented by the following array:

[
["_id", "articles"], // Table header
["id-1", "2 Elements"],
["id-2", "1 Element"],
]

At this stage, an action "Cancel order" is available.

Clicking on the first cell of the "articles" column, the user requests visualization of the corresponding nested data. The Table complies to such request by re-rendering and showing:

[
["name", "details"], // Table header
["Pants", "{...}"],
["Sweater", "{...}"],
]

At this stage, no action is available.

Clicking on the second cell of the "details" column, the Table re-renders and shows:

[
["code", "fragile"], // Table header
["order-456", "X"]
]

At this stage, an action "Refresh" is available. With the above from the example, the action would trigger a GET call to "/order/order-456".

Example: Disable an action if a field is empty

The following example showcases how a Button can be mounted inside the Table action column with customActions, and disabled based on whether or not the value of a cell of a specific column in the corresponding row is defined.

The configuration leverages the rawObjectOrEmptyStr custom helper, as well as the template-configMap interface.

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {"type": "string"},
"avatar": {"type": "object", "format": "file"}
}
},
"customActions": [
{
"tag": "bk-button",
"properties": {
"content": "Download Avatar Image",
"disabled": {
"template": "{{rawObjectOrEmptyStr args.[1].avatar}}",
"configMap": {
"": true,
"$default": false
}
},
"action": {
"type": "file-download",
"config": {
"url": "/order/{{args.[1]._id}}/avatar"
}
}
}
}
]
}
}

This configuration of the Table component renders a table which mounts a Button component as action button, which is always enabled unless field "avatar" of the corresponding row is empty.

Example: Disable default actions in nested table

To remove the default actions rendered by the Table in nested visualization, navigationRowAction property should be set to:

{
"kind": "icons",
"actions": []
}

For instance, the following configuration renders a Table that does not include the default data actions associated to nested visualizations.

{
"tag": "bk-table",
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"_id": {"type": "string"},
"articles": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"}
}
}
}
}
},
"navigationRowActions": {
"kind": "icons",
"actions": []
}
}
}

Example: Highlight rows

Assuming the following configuration for the Table:

{
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"severity": {
"type": "string",
"enum": ["High", "Medium", "Low"]
},
"pets": {
"type": "array"
}
}
},
"highlightedRows": [
{
"color": "#ff0000",
"query": {"severity": "High"}
},
{
"color": "blue",
"query": {"pets.0": {"$exists": true}}
}
]
}
}

Table rows with field severity equal to "High" will have a red (#ff0000) background color, while rows with array field pets having at least one element will have their background color set to blue.

Example: Highlight rows comparing fields between them

Assuming the following configuration for the Table:

{
"properties": {
"dataSchema": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"payed": {
"type": "number"
},
"owed": {
"type": "number"
}
}
},
"highlightedRows": [
{
"color": "yellow",
"query": {"email": "{{currentUser.emailAddress}}"}
},
{
"color": "green",
"query": {"payed": {"$gte": "{{rawObject args.[1].owed}}"}}
}
]
}
}

Table rows with field email equal to the emailAddress field of the logged user will be highlighted with a yellow color, while rows with field payed larger than field owed, will be set to green color.

Example: Make the table as height as the parent container

To make the table as height as the parent container, fitParentContainer property must be set to true and the bk-table component should have the correct style to make it as height as needed.

info

Please remember that maxLines and fitParentContainer properties cannot be used at the same time. If both are set, only maxLines will be used.

{
"content": [
{
"properties": {
...,
"fitParentContainer": true
},
"tag": "bk-table",
"attributes": { "style": "flex-grow: 1" }
}
],
"tag": "div",
"attributes": { "style": "display: flex; flex-direction: column" }
}

API

Properties & Attributes

propertyattributetypedefaultdescription
allowNavigationallow-navigationbooleantruewhen true, it is possible to navigate to nested objects and arrays if a dataSchema is specified
browseOnRowSelect-ClickPayload-if set, a click on a row will navigate you to another location
customActions-CustomAction[]-list of custom components, rendered in the action column
customMessageOnAbsentLookup-LocalizedText-override lookup value in case lookup is not resolved due to lack of data
dataSchema-ExtendedJSONSchema7Definition-data schema describing the fields of the collection to display
disableRowClickdisable-row-clickbooleanfalsewhen true, a click on a row does not trigger an event
disableRowSelectiondisable-row-selectionbooleanfalsewhen true, checkbox in the first column will not be displayed
disableRowSelectionChangedisable-row-selection-changebooleanfalsewhen true, selecting a row through the checkbox in the first column does not trigger an event
initialSortDirection-"descend" | "ascend"-initial sorting direction to use when component bootstraps
initialSortPropertyinitial-sort-propertystring-Initial property to sort on when component bootstraps
loadingOnStartloading-on-startbooleantruewhether the table should be in loading state on connection
maxLinesmax-linesnumber-force lines that will be displayed together. It can't be used with fitParentContainer
fitParentContainerfit-parent-containerbooleanfalseMake the table fit the parent container height. It can't be used with maxLines
navigationRowActions-NavigationDataActions{"kind": "icons", "actions": [{ "requireConfirm": true, "type": "delete", "disableInReadonly": true}]}actions in nested objects.
openFileInViewerRegex-FileInViewerRegex-regex expressions, matched against file values to request a preview of the file or for it to be downloaded.
resizableColumnsresizable-columnsbooleanfalsewhether the table columns can be resized. When true, columns can be resized from the table header
rowActions-DataActions-list of actions to render per row
showArrayPopovershow-array-popoverbooleanfalsewhether to display a popup on mouse-over on array cells, showing their value. Not available for arrays of objects or arrays of arrays.
fixedColumns-number | {'left': number; 'right': number}-either the number of columns to fix from left or an object containing how many columns to fix from left and/or right
displayedDataPath-string-specify an object path as datasource for displayed data
highlightedRows-QueryStyleRule | QueryStyleRule[]-highlights rows matched by a mongo-like queries

ClickPayload

type ClickPayload = {
/** Link reference, either relative starting with '/' or absolute */
href?: string
/** Where to open the href. Defaults to _self */
target?: LinkTarget
/** Query params appended to href */
query?: Record<string, any>

navigationType?: 'push', 'replace', 'href'
}

type LinkTarget = '_blank' | '_self' | '_parent' | '_top' | string

CustomActions

type CustomActions = ComponentTemplate[] | Array<{
keys?: string[]; customActions?: ComponentTemplate[]
}>

type CustomComponents = {
tag: string
properties: Record<string, unknown>
}

navigationRowActions is an object of type NavigationDataActions, which is an object such as

type NavigationDataActions = {
kind: 'icons' | 'cta',
actions: {
type: delete | detail,
danger?: true,
requireConfirm?: boolean | RequireConfirmOpts,
disableInReadonly?: boolean,
icon?: string
}[]
}

FileInViewerRegex

type FileInViewerRegex = string | string[] | {
[regex: string]: "view" | "download"
}

DataActions

type DataActions = {
kind: 'icons' | 'cta'
actions: DataCustomActions[]
}

type DataCustomActions = {
kind: 'icons' | 'cta'
content: string
meta?: Record<string, any>
requireConfirm?: RequireConfirmOpts | boolean
}

type RequireConfirmOpts = {
cancelText?: LocalizedText
content?: LocalizedText
okText?: LocalizedText
title?: LocalizedText
}

where LocalizedText is either a string or an object mapping language acronyms to strings.

QueryStyleRule

type QueryStyleRule = {
color: ColorInput
query: Query
}

Where:

  • ColorInput can be expressed as the CSS valid string representation of a color (for instance, #f2e8e2 or rgb(230, 155, 114)), or an object such as {r: 230, g: 155, b: 114}. Broadly speaking, color key supports all types supported as input by TinyColor library.
  • Query is the object representation of a mongo-like query

Listens to

eventaction
loading-datasets internal loading state
lookup-datareceives lookup data
display-datareceives data to display, deselects items by emitting a selected-data-bulk
nested-navigation-state/pushupdates internal representation of the current navigation path by adding one step
nested-navigation-state/backupdates internal representation of the current navigation path by removing the specified number of steps
nested-navigation-state/displayupdates internal representation of the data to display in navigation

Emits

eventdescription
configurable eventactions or custom web components can be used to emit custom events
require-confirmtriggered when trying to submit the form accordingly to property requireConfirm
change-queryrequires data sorting according with the sorted property
download-filerequires a file to be previewed or downloaded
selected-datanotifies about the click on a row
selected-data-bulknotifies about a change in the rows selected through the checkboxes in the first column
nested-navigation-state/pushnotifies to add a step in the navigation path
nested-navigation-state/displaynotifies data to display (emitetd upon column sorting)