# Table

## Overview

A **Table** is an iterating component that allows you to display structured data from a Data Source with multiple objects (Cardinality *Many*).&#x20;

{% hint style="info" %}
An example setup of a Table is showcased in our [Showroom](https://showroom.appfarm.app/ui-components/table)! You may view a demo, as well as access the setup in Appfarm Create. If you do not have access, you may register [here](https://showroom.appfarm.app/sign-up).
{% endhint %}

### Usage and basic settings

The Data Source (or [multi-reference property](https://docs.appfarm.io/reference/data-model/object-class-properties#general-properties)) to be displayed in rows is set in the setting **Data Source**. Which properties to display as columns are selected by adding **Columns** to the table and mapping the property to display in the **Value** setting of each column, and the column header name in the **Column Title** setting. Setting a **Value** is not mandatory, for example, if you want a column with just a button (adding an **Adornment** to the column). The value may also be defined as a Function: For example, you may add Full Name as a Column Title, and have its value calculated by a function (`return firstname + " " + lastname`).

All data in a Data Source or some subset of the data can be shown in the table. The subset can be fixed using a **Filter** on the Table or changed runtime, using **Conditional Filters**.&#x20;

{% tabs %}
{% tab title="Example" %}
Consider a solution displaying Projects in a table. Above the table, you have a radio button for the selection of the Project state. When a user selects one of the states, a conditional filter is enabled on the table data, filtering Projects according to the selected Project state.
{% endtab %}
{% endtabs %}

Each row in the table represents an object and within each row, the given object is the *Object in context*. This allows, for example, adding adornments with events that can be run with *Object in Context* to access details of the row object.

The table allows initial sorting, as well as letting the end-user sort the table by clicking on the column header. Initial sorting is applied in the setting **Sorting.**

You can turn on either single or multiple row selection for the table, from the setting **Enable Row Selection**.

The table is read-only by default, but it is possible to enable **Edit mode,** which turns the cells into input fields. After enabling edit mode, you can set specific cells *read-only* or *disabled,* if some columns should not be editable.&#x20;

{% tabs %}
{% tab title="Example" %}
Consider an inventory table that lists products, with product details and a column for inventory status. In this case, the product details might be read-only, while the column for inventory stock allows for entering and adjusting stock levels.
{% endtab %}
{% endtabs %}

{% hint style="info" %}
If you are displaying a lot of data, it might be better to allow the user to click on an adornment button, which opens a dialog where the context object can be changed, instead of setting the whole table editable. This might lead to a better user experience in the performance aspect, and it is often more clear and less overwhelming for the user.
{% endhint %}

It is possible to enable a **Toolbar** for the table. Here you can add toolbar actions and enable some built-in actions such as **Search, Filter, Show/hide columns,** and **Download as CSV**. Download as CSV is very powerful for administrative applications, where the user would like to export data to be e.g. used in Excel.

It is also possible to **Enable Footer** and show aggregated values for the columns. Once enabled for the Table, you may specify which columns should have a footer and aggregate function from the setting **Footer Type** (defined per column).

If there are great amounts of data to be displayed it might take time to render all rows in the table. If you experience that the table seems sluggish you can enable **Pagination** to limit the number of rows per page or try to decrease the visible data in the table some other way. This is especially important if the table uses a lot of adornments and property conditions.

### When should Tables be used?

Tables are very powerful in terms of data overview, search, filtering and structure. Tables are the thing to use in administrative applications, where the end-user typically needs to access the data with various filters, and the data may have many columns. Tables are quite user-friendly, however, when the priority of the application is a fancy UI for e.g. consumers or customers, you might want to consider creating a more custom UI for this purpose.

## Details on the Table Settings

### Data

The **Table** component is used to display a set of data in a Data Source. Specify the **Data Source** you want to display data for in the table. By default, all data in the Data Source will be displayed in the table, but it is possible to display a subset of the data by applying a **Filter** on the table. Furthermore, you can add **Conditional filters** which can be enabled and disabled runtime. Set a *condition* specifying if the filter should be applied, and specify the *filter*. All conditional filters evaluated as enabled will be applied in addition to the top-level table filter.

Furthermore, the table data can be **Sorted** and it is possible to apply a **Skip** and **Limit** to the data. **Skip** will skip the *n* number of objects, while **Limit** specifies the maximum number of objects to be displayed.

If the amount of data to be displayed is big, it might be necessary to enable **Pagination**. This will render the *n* number of rows per page and let you flip between pages, thus decreasing the time it takes to render the table.

### Columns

Each column specifies a **Value** to be shown in the cell, typically a property on the Data Source, but static values or some sort of function can also be displayed. Each column lets you specify a **Column Title** (header value) and an associated **Tooltip**. It is possible to add a **Visibility Condition** to the column. For instance, this can be used if you have a table that several user groups have access to, but where some of the columns should not be visible for all user groups.

To display line breaks for string values, **Multiline** must be enabled. The table will then render line breaks in read mode and support their entry in edit mode.

A column is set to be **Sortable** by default. This allows the user to sort data in columns by clicking the header.

The column has several settings related to the table's other settings. If **Edit mode** is enabled you can specify if a given column should be editable. You can specify which options should be available for properties referencing other objects (Enumerated Types or Object Classes). Furthermore, you can set a column **Initially Hidden** if the setting **Show/hide Columns** is enabled, or **Exclude from Search / Filter** if **Search** and **Filter** are enabled on the toolbar.

**Conditional Column Properties** can be used to set a column **Initially Hidden** based on a condition. This setting does not require the **Show/hide Columns** setting on the table to be enabled. &#x20;

You can change the color of the text and background in a cell based on conditions using **Conditional Cell Properties**. The conditions are evaluated in the context of the current table row. This allows you to style the cell based on all properties stored on the object being displayed.

Button **Add all Properties as columns** will add all the Object Class Properties (and runtime properties) of the selected Data Source as Table Columns. Reference properties will only be added if the refered Object Classes have a [Display Property](https://docs.appfarm.io/reference/data-model/object-classes#general-properties) set. *Example: Adding all columns for Data Source `Contacts` (having a reference `Contact.Company`) will add `Contact.Company.Name` as a columns if the Object Class `Company` has `Name` as Display Property.*

### Row Selection

It is possible to enable **Row selection** on the table. The setting is data-bound, which allows Row selection to be toggled on and off runtime. The default selection type is *multiple,* and enabling row selection will include a checkbox at the beginning of each row. There is an explicit setting **Single Select,** which can be checked if the table should allow for only one selection. Furthermore, the **Toolbar** has a setting for displaying the number of items selected, **Selection Count**.

Note that enabling Row Selection will flag the objects in the Data Source as *Selected* when the user selects rows, and vice versa when deselecting them.&#x20;

### Edit mode

The table is read-only by default but can be set editable using the data-bound setting **Edit mode**. If the table has edit mode enabled, the table columns will be rendered as input fields. At the column level, there is a separate section for Edit mode which allows you to specify if the column should be *read-only* or *disabled* in the edit mode. Reference properties will be shown as selects, and they have their own settings on which options should be available. Furthermore, it is possible to add an action that should be run **On value change**.

### Toolbar

It is possible to enable a **toolbar** on the table. On the toolbar, you can specify a data-bound title, which also has a parameter *totalRowCount,* which can be added using handlebars `{{totalRowCount}}` in the title, to display the total number of rows.

If *Row selection* is added to the table, it is possible to show the **Selection Count** in the toolbar.

There are predefined events for **Search**, **Filter**, **Show/Hide Columns** and **Download as CSV** that can be enabled, but you can also add your own toolbar actions. **Search** is an inline search field searching across all columns, while **filter** opens a popover with filters for the columns. At the column level, you can check the box **Exclude from Search** or **Exclude from Filter** if you want to exclude a specific column from search or filtering. **Show/Hide Columns** provide the end-user with a possibility to add or remove columns from the table. If this option is set, it is also possible to **Initially hide** a column at the column level. **Download as CSV** lets the user export the table content to a CSV file. Note that Download as CSV should have a **CSV Value Delimiter** set to `;` for European users (where CSV files are stored with a semicolon as column separator), as opposed to US users (where `,` is used).

As previously mentioned, it is possible to add your own **toolbar actions** either in a dropdown menu in the toolbar or as single actions. It is possible to limit the action to only be available when some rows are selected.

### Header

The header can be set to be **fixed,** meaning that the header sticks to the top of the page when scrolling. There is also an option to completely **hide** the header.

{% hint style="warning" %}
For a fixed header to work, you may need to set the height of the table to 100%.
{% endhint %}
