# Tab Panel

## Overview

The TabPanel component is a tabbed container that can hold one or more forms. But only one of them is visible at a time.\
The active/visible form can be changed using the tab buttons or from code. At runtime, tabs can be added from code, and can be removed either from code or from the UI. Tabs can optionally show related data.

It can be used in both responsive and anchored layouts.

## Get Started

<div align="left"><figure><img src="/files/Ru0Kf5PZC63FIb4zHfxB" alt=""><figcaption><p>Tab Panel</p></figcaption></figure></div>

### Creating a Tab Panel

<div align="left"><figure><img src="/files/PCrIGhPFz3nLhtQyldbd" alt=""><figcaption><p>Create a Tab Panel</p></figcaption></figure></div>

Here are the steps for creating a Tab Panel:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor.md) of the form where you need to place an **Accordion Panel**
2. Find **TabPanel** in *Form Containers* section in the components' pallet
3. Drag and drop the **TabPanel** component in the desired place of the form
4. Set the tabs; this can be done via [wizard](/guides/develop/application-design/forms/form-containers/accordion-panel.md#setting-the-tabs-property-via-the-wizard) or in the [properties panel](#setting-the-tabs-property-in-the-properties-panel)
5. Edit other [**TabPanel** properties](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#properties) if needed

{% hint style="info" %}
It is recommended to set a specific `name` in the **Tab Panel** properties in order to make it easier to use it later in scripting.\
Example: `"tabpanel_orders"`.

<img src="/files/oFW8lsVuhOhjPM4amDYr" alt="Tab Panel name" data-size="original">
{% endhint %}

{% hint style="info" %}
It is recommended to set a specific `name` in the **Tab Panel tab** properties in order to make it easier to use them later in scripting.\
Example: `"tab_customers"`.

<img src="/files/DWp776pXd7aJM6o1QzRN" alt="Tab Panel tab name" data-size="original">
{% endhint %}

### Setting the tabs property via the wizard

<figure><img src="/files/1Kmkloww5Ou1rMGjd3hM" alt=""><figcaption><p>Property configurator for tabs wizard</p></figcaption></figure>

After dragging the container in the form, the `Property configurator for tabs` wizard appears. In order to set the tabs using the wizard, you need to do the following steps:

1. Find in the left side of the wizard the contained form you need: it can have a related or unrelated datasource
2. Click on the form name
3. The selected form will appear on the right side of the wizard, showing some of the tab properties:
   1. `CONTAINEDFORM` : the form shown in the tab
   2. `RELATIONNAME` : the name of the relation between datasources of main and contained forms; this field will be empty if the relation doesn't exist
   3. `TEXT`: the tab's title text ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n.md#i18n) and custom HTML supported)
   4. `delete` icon : you can remove a tab by clicking the icon
4. Click `OK` button after all tabs have been added

### Setting the tabs property in the properties panel

<figure><img src="/files/G9vsxkO6szQtZa2fynhs" alt=""><figcaption><p>Adding and editing tab properties</p></figcaption></figure>

After dragging the container in the form, the `Property configurator for tabs` wizard appears. Close the editor without setting anything here, find the **Accordion Panel** in the form editor, click it and proceed with the following steps:

1. Add a tab. There are 2 ways of adding a tab:
   1. Select the [`tabs`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#tabs) property and click the `+` button in order to add a tab. Next tabs can be added the same way or by clicking the `+` button (`insert a new array item below`) of another tab. You can change the tabs' order by dragging them into the desired placed inside the **TabPanel** (in the form editor).
   2. Drag and drop `tab` component (of an **TabPanel** in *Form Containers* section in the components' pallet) into the **TabPanel** container (in the form editor)
2. Expand the [`tabs`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#tabs) property to see the list of tabs. They are also shown in the **TabPanel** container (in the form editor)
3. In order to edit each tab, expand it or click the tab name in the **TabPanel** container (in the form editor) and set the properties:
   1. [`containedForm`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#containedform): the form shown in the tab
   2. [`disabled`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#disabled): whether that tab is enabled or not
   3. [`hideCloseIcon`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#hidecloseicon): whether a close icon is shown or not (only applicable when [`showTabCloseIcon`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#showtabcloseicon) is set to `true`)
   4. [`iconStyleClass`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#closeiconstyleclass): style class for the tab's icon
   5. [`imageMedia`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#imagemediaid): image to be drawn in tab header
   6. [`name`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#name): a name for this tab
   7. [`relationName`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#relationname): optional relation for the form to be shown
   8. [`text`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#text): the tab's title text ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n.md#i18n) and custom HTML supported)
   9. [`toolTipText`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#tooltiptext): the text message when a user hovers their cursor ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n.md#i18n) and custom HTML supported)

### Using a relation

The contained form of the tabs can show related data. In order to do this, you need to have the following:

1. Set the [`datasource`](/reference/servoycore/object-model/solution/form.md#datasource) property on the main form
2. Set the [`datasource`](/reference/servoycore/object-model/solution/form.md#datasource) property on the contained form
3. Make sure that the [relation](/guides/develop/application-design/data-modeling/relations.md) from datasource table of the main form to datasource table of the contained form exists, otherwise it needs to be created
4. Set the above relation in the [`relationName`](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#relationname) property of the corresponding tab

Once everything is set, the contained form will show related data according to the selected record in the main form. When the selected record changes in the main form, so will the related data from the contained form.

## Customizing the Tabs

### Setting the tab text

Tab's title [text](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#text) property can be set by entering a value in the property field or by entering the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor.md). Usually this will be plain text or it can contain data from table columns, aggregations, calculations, relations or from and scopes variables, all of them can be combined, as well. [i18n](/reference/servoy-developer/solution-explorer/resources/i18n.md#i18n) is also supported.

Examples:

<figure><img src="/files/7tIE4XxpsdQq4YlYEHYd" alt=""><figcaption><p>Tab text - plain text</p></figcaption></figure>

<figure><img src="/files/MwImKByS8iWNuzjBNpxh" alt=""><figcaption><p>Tab text - including database column</p></figcaption></figure>

<figure><img src="/files/8ZBHApSvLipCCU3lP0Id" alt=""><figcaption><p>Tab text - including form variable</p></figcaption></figure>

<figure><img src="/files/aYg23C6qWVLtjout3OW8" alt=""><figcaption><p>Tab text - i18n</p></figcaption></figure>

### Setting the tooltip text

Tab's [tooltip text](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#tooltiptext) property can be set by entering a value in the property field or by entering the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor.md). Most often, this will just be plain text that describes what will happen on-click. It can also contain data from table columns, aggregations, calculations, relations or from and scopes variables - all of them can be combined. [i18n](/reference/servoy-developer/solution-explorer/resources/i18n.md#i18n) is also supported.

### Closable Tabs

TabPanel component can also have closable tabs, when needed.

#### Enabling/Disabling Tab Close

In order to enable the option to have closable tabs, the user must check [showTabCloseIcon](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#showtabcloseicon) property of the TabPanel component. This applies to all tabs, so in case when not all tabs should be closable, the user can check [hideCloseIcon](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#hidecloseicon) property of the **tab**; this will remove the close icon of the tab.

#### Setting the close Icon

The close icon can be set by editing the [closeIconStyleClass](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#closeiconstyleclass) property of the TabPanel.

### Custom Tab Markup

Tab's title [text](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#text) property supports custom HMTL content.

Example:

<figure><img src="/files/hUsvcLhVcCb2HcxZxdks" alt=""><figcaption><p>Tab text - custom HMTL</p></figcaption></figure>

{% hint style="warning" %}
In order for the custom HTML content to be correctly displayed we need to make sure that it will not be sanitized by using `.putClientProperty(UICONSTANTS.TRUST_DATA_AS_HTML,true)`

```javascript
function onShow(firstShow, event) {
	// TODO Auto-generated method stub
    elements.tabpanel_orders.putClientProperty(UICONSTANTS.TRUST_DATA_AS_HTML,true);
}
```

**Only enable this setting if the data shown can always be trusted and is never composed of data from an external system or user.**
{% endhint %}

## Scripting a Tabpanel

[**TabPanel** properties](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#properties) can be also set in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md).\
You can find a list of AccordionPanel API methods [here](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#api).

### Changing Selected Tab

Here is an example of how to programmatically set the active tab in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md) of the main form:

```javascript
/**
 * TODO generated, please specify type and doc for the params
 * @param index {Number}
 *
 * @properties={typeid:24,uuid:"78CE78AF-AC5A-458B-A611-84DDC07878B3"}
 */
function setActiveTab(index){
	elements.tabpanel_orders.selectTabAt(index)
} // call this function after the TabPanel container is fully loaded on the page and set the desired index value
```

### Adding a Tab

Here is an example of how to programmatically add a tab in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md) of the main form:

```javascript
function onShow(firstShow, event) {
	// TODO Auto-generated method stub
    elements.tabpanel_orders.addTab(forms.suppliers,'Suppliers'); // Adds a tab to this accordion with that form and text
} 
```

### Removing a Tab

Here is an example of how to programmatically remove a tab in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md) of the main form:

```javascript
function onShow(firstShow, event) {
	// TODO Auto-generated method stub
    var x = elements.tabpanel_orders.tabs.length;
    elements.tabpanel_orders.removeTabAt(x-1);  //Removes a tab of the given index. Returns true if this was sucessfull.  
} 
```

### Handling Tab Change Event

Here is an example of how to use the [`onChange` event](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#onchangemethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md) of the main form:

Saving the active tab index in the `onChange` event(fired after a different tab is selected) of the TabPanel container:

```javascript
/**
 * Fired after a different tab is selected.
 *
 * @param {Number} previousIndex The previous tab index
 * @param {JSEvent} event
 *
 * @private
 *
 * @properties={typeid:24,uuid:"0A044286-CB21-4CCC-A8AA-284137F1D22E"}
 */
function onChange(previousIndex, event) {
	// TODO Auto-generated method stub
	application.setUserProperty(controller.getName()+"."+elements.tabpanel_orders+".activeTab",elements.tabpanel_orders.activeTabIndex.toString())
}
```

Checking if there is a saved previous active tab index and set it in the `onShow` main form event:

```javascript
/**
 * @type {String}
 *
 * @properties={typeid:35,uuid:"2FD6AD36-9779-49D2-B4A7-985C7C73B66C",variableType:8}
 */
var activeTab;

/**
 * Callback method for when form is shown.
 *
 * @param {Boolean} firstShow form is shown first time after load
 * @param {JSEvent} event the event that triggered the action
 *
 * @private
 *
 * @properties={typeid:24,uuid:"37E091B7-6FD0-47E8-94E4-A22585A3C717"}
 */
function onShow(firstShow, event) {
    // TODO Auto-generated method stub
    activeTab = application.getUserProperty(ontroller.getName()+"."+elements.tabpanel_orders+".activeTab");
    if (activeTab)
    {
        elements.tabpanel_orders.selectTabAt(parseInt(activeTab));
    }   
}
```

#### Blocking a tab change

Here is an example of how to block a tab change using the [`onTabClicked` event](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#ontabclickedmethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md) of the main form:

```javascript
/**
 * Fired when the user clicks on a tab. When false is returned, the tab switch is prevented.
 *
 * @param {JSEvent} event The event that triggered the action
 * @param {Number} clickedTabIndex The index of the tab that was clicked
 * @param {String} dataTarget The value of the closest data-target attribute when found
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"0C9D0DEA-5D52-4E2E-B5D9-2E510FC2BE9F"}
 */
function onTabClicked(event, clickedTabIndex, dataTarget) {
	var editedRecords = databaseManager.getEditedRecords();
	if (editedRecords.length>0) {
		var button = plugins.dialogs.showInfoDialog('Pending changes', 'Some fields have changes. How would you like to proceed?', 'Stay on tab', 'Leave')
		if (button == 'Leave') {
			return true;
		}
	} else {
		return true;
	}
	return false;
}
```

### Handling a Tab Close Event

Here is an example of how to use the [`onTabClose` event](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#ontabclosemethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md) of the main form:

```javascript
/**
 * @type {Array<Object>}
 * @properties={typeid:35,uuid:"A5B0105B-1663-44DF-AC5B-3E8ABE63CA69",variableType:-4}
 */
var closedtabs = [];

/**
 * @properties={typeid:35,uuid:"7F15F51E-6AB9-41CC-9BC9-8A635CD2F298",variableType:-4}
 */
var closedtabsIndexes = []; 
/**
 * Fired when the user clicks on the tab close icon. When false is returned, the tab close is prevented.
 *
 * @param {JSEvent} event The event that triggered the action
 * @param {Number} clickedTabIndex The index of the tab that was clicked
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"2C20175F-CC95-4A35-8C78-0791981B4D9F"}
 */
function onTabClose(event, clickedTabIndex) {
	// TODO Auto-generated method stub
	closedtabsIndexes.push(clickedTabIndex)
	return true;
    // saves the indexes of closed tabs
}
```

#### Blocking a tab close

Here is an example of how to block a tab close using the [`onTabClose` event](/reference/servoyextensions/ui-components/form-containers/tabpanel.md#onchangemethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor.md) of the main form:

```javascript
/**
 * Fired when the user clicks on the tab close icon. When false is returned, the tab close is prevented.
 *
 * @param {JSEvent} event The event that triggered the action
 * @param {Number} clickedTabIndex The index of the tab that was clicked
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"2C20175F-CC95-4A35-8C78-0791981B4D9F"}
 */
function onTabClose(event, clickedTabIndex) {
	// TODO Auto-generated method stub
	if (databaseManager.getEditedRecords(foundset).length>0)
	{
		return false;
	}
	else {
		return true;
	}
    // prevents tab close when there is edited and unsaved data
}


```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.servoy.com/guides/develop/application-design/forms/form-containers/tab-panel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
