# Home

Welcome to Servoy!

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Get Started</strong></td><td>Get up and Running with Servoy</td><td><a href="/pages/EE2OBRPoXsfh5jER7WZu">/pages/EE2OBRPoXsfh5jER7WZu</a></td><td></td></tr><tr><td><strong>Product Tour</strong></td><td>High-level overview of the platform</td><td><a href="/pages/pPYP703D8vfGkRjjzeLF">/pages/pPYP703D8vfGkRjjzeLF</a></td><td></td></tr><tr><td><strong>How-To</strong></td><td>Topical guides for every subject</td><td><a href="/pages/WEWyXDNorxI5TGpc8CGI">/pages/WEWyXDNorxI5TGpc8CGI</a></td><td></td></tr><tr><td><strong>Reference Docs</strong></td><td>Just the details</td><td><a href="https://github.com/Servoy/gitbook/blob/master/broken-reference/README.md">https://github.com/Servoy/gitbook/blob/master/broken-reference/README.md</a></td><td></td></tr><tr><td><strong>Samples</strong></td><td>Sample use cases</td><td><a href="https://samples-dev.samples.servoy-cloud.eu/">https://samples-dev.samples.servoy-cloud.eu/</a></td><td></td></tr><tr><td><strong>Videos</strong></td><td>Browse our archives</td><td><a href="https://servoy.com/webinars/tech-series/">https://servoy.com/webinars/tech-series/</a></td><td></td></tr></tbody></table>


# Platform Overview

Welcome to Servoy!

This guide will provide an introduction to the platform and key concepts.

## What is Servoy?

Servoy is a comprehensive, low-code platform to build, deploy and manage core systems and enterprise-grade applications. It combines the speed of low-code with the level of control provided by traditional tooling.

### Who uses Servoy?

Servoy is primarily used by enterprise application teams and independent software vendors (ISVs). Unlike many low-code platforms, Servoy caters directly to IT users and professional developers. This is because Servoy provides standards-based, open-source tooling in an extensible, comprehensive low code platform.

### What can be built?

Servoy developers build applications for the browser, but also mobile devices, native desktop and headless automation. The platform enables specialized user experiences, intricate workflows and powerful business logic. Developers can build both systems of record and systems of engagement that interoperate and serve many users across different devices and environments, at scale.

## How Does it Work?

The following are a few key concepts that drive the developer experience.

### Data Connectivity

Servoy applications are inherently data-connected and data-driven. Developers can connect to any database, web-service, flat file or legacy system. Servoy works particularly well with relational database systems, providing enhanced capabilities for connecting, querying and updating databases. Developers can blend data from many sources, quickly build data-bound user interfaces and easily execute logic against their data models.

### Visual Modeling

The platform provides visual modeling elements to simplify development including data modeling, entity design, business objects, UI design, navigation and event routing. This greatly simplifies complex applications.

### Scripted Logic

Servoy embodies the idea that a great low-code platform should provide a great coding interface to increase productivity and control when application logic is needed. Servoy provides a JavaScript engine and a catalog of self-documenting APIs to solve any problem. Moreover the platform includes the tooling to make the job easy, such as code completion, examples, debugging and more.

## Platform Components

The following is a summary of the basic components of the Servoy platform.

### Servoy Developer

Servoy Developer is the integrated developer environment (IDE) where most of the development is done. Servoy Developer provides all of the tools to build and debug applications in a single package, including visual editors for modeling and UI design, a robust code editor and debugging tools.

### Servoy Core

The core consists of a design-time object model and the developer API. The object model contains all the design-time elements in the application, including data sources, business objects and forms. The developer API includes a catalog of packages for many common runtime operations.

### Servoy Extensions

The Servoy platform uses an open-architecture design and provides extension points throughout the stack. By default, the platform ships with many UI components, plugins, modules and themes. Developers can also extend the platform to solve any challenge. Servoy Developer includes the Package Manager, which can be used to include the following extensions in any project.

#### UI Components

The Servoy platform includes a comprehensive catalog of UI components. These range from common input controls to specialized components for data visualization, document editing and more. UI components can be assembled in the form editor, a drag-and-drop interface to design the UI. Developers can also include 3rd-party or custom components in their projects.

#### Plugins

Servoy's toolkit includes a scripting interface to control application logic. Code is written using the core developer API and plugins for specialized logic. The platform ships with a large catalog of plugins to handle common programming tasks, such as email, http, file i/o and much more. Developers can also include 3rd-party or custom plugins in their projects to meet any integration challenge.

#### Themes

At a fundamental level, Servoy applications are styled using CSS/LESS. However developers do not need to be proficient in these technologies. Themes provide a higher-level abstraction to simplify styling, making applications consistent and easy to maintain.

#### Modules

The Servoy platform is designed on the principle of composable architecture and applications may also become modules, encapsulating business objects and code to be reused in other applications. Servoy ships a number of general and specialized modules and developer may build their own modules to use best-practices in application design.

### Servoy Application Server

Servoy provides an application server which brokers data source connections and manages all the client sessions. The server, applications and modules may be deployed together in a simple self-contained docker image or war file. Applications may be deployed in any of the following client types.

#### NG Client

The NG Client is the primary runtime of the Servoy platform. It is a light-weight web application (HTML5, CSS and JavaScript) and runs in any modern browser. It implements a model-view-controller (MVC) design.

#### NG Mobile

Responsive web applications built in Servoy may be deployed through the NG Mobile client wrapper for iOS and Android devices. Additional plugins give developers access to device APIs, such as camera, GPS, push notifications and more.

#### NG Desktop

Servoy applications may be deployed through the NG Desktop client wrapper for Windows, Mac and Linux devices. Additional plugins give developers access to desktop APIs, such as filesystem, local hardware, printers, scanners, etc.

#### Headless Client

Some applications are not meant to have and end-user or a UI. For this purpose, Servoy provides the Headless Client, which can be used for automation jobs, parallel processing and REST API generation. All the same tools and concepts apply, except for UI design.

### ServoyCloud

Applications built in Servoy can be deployed in any environment; on-premise, self-hosted, public or private clouds. In addition to the tools to build and deploy applications, Servoy provides specialized cloud infrastructure to automate software delivery and high-availability (HA) production environments to host, monitor and manage production applications.

#### Delivery Pipelines

ServoyCloud provides a flexible, low-touch DevOps control center to manage and automate the software delivery lifecycle and maintain quality.

* Revision Control (Git) Integration
* Build Automation
* Quality Control and Test Automation
* Artifact repositories
* Docker Orchestration

#### Production Environments

ServoyCloud provides specialized infrastructure and production environments to remove the burdens of hosting and provide stable, scalable and secure applications anywhere on the planet. The following are just some of the specialized components of ServoyCloud production hosting:

* Full-stack container monitoring and log management
* Application performance monitoring
* User insight and analytics
* Zero-downtime deployments
* Auto-scaling pods and infra based business hour rules
* Full backup/restore and disaster recovery scenarios
* Auto-renewal of keys and certificates


# Get Servoy

This guide will walk you through how to begin using the platform

This guide will explain how to get access to the Servoy platform

Servoy is a comprehensive, low-code platform to build, deploy and manage core systems and enterprise-grade applications. It combines the speed of low-code with the level of control provided by traditional tooling.

## Register

The first step is to [register](https://admin.servoy-cloud.eu/solution/svyCloud/index.html?a=registration) for your free ServoyCloud account. After you register and confirm your email address, you can log into ServoyCloud to continue.

## Download Servoy Developer

If you have already registered, log in to ServoyCloud and select the option "Download" from the main menu. Choose your operating system and Servoy version. It is recommended to use the "CURRENT" or "LTS" builds.

Once the download has completed, you are ready to install the Servoy Developer IDE to [get started](/guides/get-started).

## Installation

Below is a step-by-step guide to installing Servoy Developer.

### Windows, Mac and Linux

Installing Servoy Developer is easy and depending on your operating system, your experience will vary. For **Windows** and **Mac OS**, you will get an installer executable, `.exe` and `.dmg` respectively. Open this file to begin the **Installation Wizard**.

For Linux (or cross-platform) installation, you will receive a `.tar.gz` distribution. Simply extract it to your desired location; no installation wizard is needed.

<div align="left"><figure><img src="/files/Jpy5iItO6lTt276YLO4h" alt="" width="311"><figcaption><p>Servoy Installation Wizard for Windows or Mac OS</p></figcaption></figure></div>

### Choose Installation Directory

![](/files/fzPsoYtjGuoNhlE5t8P7)

Choose a directory on your local file system where you would like to install Servoy Developer.

{% hint style="info" %}
Each installation is fully stand-alone. This means that you can install as many copies of Servoy Developer as you want
{% endhint %}

## Run Servoy Developer

You have the option to run Servoy Developer at the end of the Installation Wizard. You can also run Servoy Developer at any time by opening the application installed in the following location, relative to your installation path.

`/<installation-directory>/developer/servoy`

![](/files/ITlzcFsIrFEARMTM9poN)

### Select a Workspace

When you start Servoy Developer, you will be prompted to choose a workspace[^1] directory. This will be your working directory for your first project and can be any location on your file system.

{% hint style="info" %}
Don't be shy. You can have as many workspaces as you want and you may easily switch between them.
{% endhint %}

![](/files/PSI0M7rU8EpIiSb3DgU0)

You have the option to use your selection as the default. If you select this, you will not be prompted again to choose your workspace when starting Servoy Developer.

### Install the Sample Database

When you first start Servoy Developer, you will be prompted to install the default, sample database. This is a PostgreSQL database with sample schema and data. It is highly recommended to allow the default option here, as the sample is useful for tutorials and examples.

![](/files/5iXPo9CdMyoQy5yQxGbk)

![](/files/xYuLIjpM3JNd11f2QkCj)

{% hint style="info" %}
If you already have experience or you are sure that you do not want to install the Sample Database, you may choose **advanced settings** and skip the installation of the database, the sample data or both.
{% endhint %}

Nice work! if you have made it this far, you are ready to begin the [Get Started](/guides/get-started) tutorial.

[^1]: A [workspace](/reference/servoy-developer/project-file-structure/workspace-folder) is a working directory for a Solution or set of solutions. Servoy Developer will have only one workspace folder open at a time. However, you can have many workspaces on a single machine and can switch between them easily.


# Get Started

This guide will help you to quickly build your first Servoy application

In this guide, we will build a small CRM-like application using the example database that ships with Servoy Developer. This guide is meant for beginners learning the Servoy platform.


# Chapter 0

Setup and Requirements

Before we get started, it's important to make sure that your environment is properly setup to work on this tutorial.

## Setup ServoyCloud

To start creating applications, you must first register for a free ServoyCloud account and then create your namespace. Without a namespace, you cannot create, manage, or deploy applications to the cloud.

### Create a ServoyCloud account

The first step is to [register](https://admin.servoy-cloud.eu/solution/svyCloud/index.html?a=registration) for your free ServoyCloud account. After you register and confirm your email address, you can log into ServoyCloud to continue.

### Create a namespace

Log into the [Cloud Control Center](https://admin.servoy-cloud.eu/) and from the home page, click on the button `Start Cloud Setup`.

See namespace [setup instructions here](/reference/servoy-cloud/cloud-control-center/home/setup-namespace) or follow the on-screen instructions.

After setting up your namespace, proceed with installing the developer and checking out your application.

{% hint style="warning" %}
Namespace setup may take a few minutes.
{% endhint %}

## Install Servoy Developer

It's recommended that you [download and install](/guides/get-servoy#download-servoy-developer) the latest version of Servoy Developer.

{% hint style="info" %}
If you have an existing copy of Servoy Developer that you want to use, be sure to switch into an empty workspace. This will ensure that you don't corrupt your tutorial with files from an existing project.
{% endhint %}

## Log in using Servoy Developer

Once you have downloaded and opened Servoy Developer, use the Servoy Cloud Control Center credentials to log in.

<figure><img src="/files/tMnYAU3x60a2EIydTOLR" alt=""><figcaption><p>Servoy Developer login dialog using Servoy Cloud credentials</p></figcaption></figure>

{% hint style="info" %}
If the login dialog is closed without logging in, open it by clicking the Servoy icon <img src="/files/N1WJgtPivBWYMFykPJcZ" alt="" data-size="line"> in the bottom right corner of Servoy Developer.
{% endhint %}

## Select Servoy Cloud Application

After successful sign-in, a dialog box will appear prompting you to select your application.

<figure><img src="/files/U48e1kZLhCFDG2QHgfRN" alt="" width="368"><figcaption><p>Check out application dialog box</p></figcaption></figure>

After making your selection, the source code will be automatically checked out into your local workspace.

{% hint style="info" %}
If the dialog does not show, switch into an empty workspace. This will ensure that you don't corrupt your tutorial with files from an existing project.
{% endhint %}

## Include Example Data

The subsequent chapters of this guide rely on the example database that should have been installed by default during the installation process. If for some reason, you do not have the example database, then you must reinstall Servoy Developer and be sure to include example data.

To confirm that you have the example database, look at the Database Servers node in your Solution Explorer panel. You should see a database called `example_data`.

![](/files/fEmrsWUBZFPjnRaLbfhX)

{% hint style="success" %}
Excellent! Now you are ready to begin adding features to your first solution.
{% endhint %}


# Chapter 1

Create your first form

## Overview

In this chapter, you will create your first Form in the new Solution, connect it to a data source and add some fields and labels.

### Key Concepts Covered

* **Forms**
* **Components** and data-bound fields
* **Value Lists** and **Type-Ahead** lookups
* **Labels** and data-driven text
* **Formatting** (Dates)
* **The NG Client** to preview and test
* **Publishing to Servoy Cloud**

## Create a Form

Create your first form by right-clicking the forms node in the Solution Explorer and select `Create New Form`.

![](/files/JEYzjGJ3aVD5ctMUuK4U)

Enter "orders" for the name. Select a datasource. Choose the `orders` table in the `example_data` database and click `OK`.

Choose the default values for the remaining properties and click `Next`.

![](/files/taGzjzv8CjET0fKM5ZHR)

### Place Data Providers

The next section of New Form Wizard is to optionally place data providers (data-bound fields) on the form. Components can be placed on a form at any time, but in this tutorial, we'll take advantage of this wizard, when creating the form, to quickly get some fields an labels.

You'll see a list of data providers for the `example_data.orders` data source. We will choose from this list in a moment, but first, click the `Advanced Configuration` button to get more options.

![](/files/WbvmUYmFWwjG2RdbU0Ad)

Here we can configure a few options about which components to place for different data types, as well as default sizes and spacing. We can also choose to place labels and more.

Choose the following values to control how the fields are placed.

![](/files/W1mFDv7ewBmyU4KjAEW0)

Next, you are ready to choose the data providers that will be placed on the form. Choose the following data providers and click Finish.

* `customerid`
* `employeeid`
* `orderdate`

![](/files/dy9RYsK7iTZAitvjI41p)

The Form Editor should open and you should see a form having the fields that you selected.

![](/files/4Sb0UtsTA3LfiVRjbyXy)

## Set the First Form of your Solution

To see the form `orders` as the first form in your solution, you must set it in the firstForm property of your solution.

To set your solution `firstForm` property, click on the solution name in the Solution Explorer. In the properties view, this will show all the properties of the solution you just clicked.

Double click on the property `firstForm`, select the `orders` form and click the `Ok` button to save your changes.

<div align="left"><figure><img src="/files/hFH4FFTfaRRmJGo5YRVK" alt=""><figcaption></figcaption></figure></div>

{% hint style="success" %}
The first form of the solution is now set and you are ready to run your solution.
{% endhint %}

## Run your solution

### Run your solution locally

Servoy Developer comes with a built-in instance of the **NG Client** to preview, test and debug your solution at any time during development. To launch the client, click the ![](/files/b6871TRIQVWn9JxfwbNm)icon.

![](/files/wKN3PHl718SMCItWLbZm)

Your solution will open in the default browser and you can see that the form is populated with data from the first record in the `orders` table.

![](/files/nT7Zbcr2mi8oGDsFyjPn)

### Run your solution on Servoy Cloud

Besides viewing the solution locally, you can also publish it to Servoy Cloud and view it in the browser, as a web application.

To publish your solution to Servoy Cloud, click the <img src="/files/Lh8dwr80cx05UmgvFhrR" alt="" data-size="original"> icon.

<div align="left"><figure><img src="/files/U2JXelMwq5FGDHQ2GsKG" alt=""><figcaption></figcaption></figure></div>

{% hint style="warning" %}
You must click the publish button every time you want to update your cloud application.

It may take a few minutes for changes to take effect.

For immediate results, run your solution locally.
{% endhint %}

To view your web application, use the link generated when you created your namespace with the format `https://yoursolution-dev.yournamespace.servoy-cloud.eu` or using the Cloud Control Center:

1. Login into [Cloud Control Center](https://admin.servoy-cloud.eu/) using the credentials set up in [Chapter 0](/guides/get-started/install-servoy-developer#setup-servoy-cloud)
2. Using the side menu, go to `Project Overview` > `Applications`
3. Click on your application
4. Click the button `Launch in ServoyCloud`

{% hint style="success" %}
**Nice Work!** It may not look like much, but you've created a web application, which connects to and queries your database and loads data in a form. Let's keep going and enrich the form a data labels and value lists.
{% endhint %}

## Add a Value List

In this step we will add a Value List to allow the user to choose values from other database tables. The form currently displays two fields, `employeeid` and `customerid`, both of which are foreign key columns to related tables. Therefore, the current display of the raw values is not so nice.

Let's use a `Value List` object to show more meaningful information about those foreign entities and allow the user to choose related records. To do this, we will delete the two fields and replace them with Type Ahead components, bind them to Value Lists.

### Place a Customers Type Ahead component

Start by deleting the `customerid` field (we'll leave the label). Select the component on the Form Editor and push the `del` key (or right-click the component and select `Delete`).

Locate the `Type Ahead` component in the `Pallet` and drag it onto your form, positioning and sizing it accordingly below the customer ID label.

{% hint style="info" %}
You can quickly filter the Pallet by typing in the *Search* field at the top.
{% endhint %}

<figure><img src="/files/CNUxwq9NYIdfrTa9QUZz" alt=""><figcaption><p>Place a Type-Ahead component and bind to a new Value List</p></figcaption></figure>

#### Set the Data Provider

In the component Properties Editor, double-click the `dataProvider` property to open the Data Provider Chooser. Select the `customerid` column.

#### Set the Value List

In the component Properties Editor, double-click the `valuelist` property to open the Value List Chooser. Click the button to Create New Value List. Enter the name `customers` and click `Finish`. (Click `OK` to dismiss the Value List Chooser.)

### Create a Customers Value List

Now that you have created the Customers Value List, you are ready to edit its properties in the Value List Editor. This editor should have opened upon creation of the new Value List.

<figure><img src="/files/vm5m3IlkNtXa9InWHNkx" alt=""><figcaption></figcaption></figure>

#### Set a Value List Type

Select the Value List type by choosing the `Table Values` radio option. This option specifies that the values will be queried from a data source table.

#### Set the Data Source

Click the `...` button to open the Data Source Chooser the data source for the Value List. Select the `example_data.customers` data source and click `OK`.

#### Select the Display Value

Choose the `companyname` data provider to "show in field / list". This is the value that will be used to render instead of the real value.

#### Select the Real Value

Choose the `companyid` data provider to "return in data provider". This value will not be displayed. Instead it is the value that will be stored in the target data provider / field.

Click the Save All ![](/files/KsAAh32UF1aZ8azJvEG1)button (or `ctrl+shift+s`) to save all your editors. Navigate back to your NG Client running in the browser and preview the change.

{% hint style="info" %}
If you leave your browser tab open while you are working in Servoy Developer, your changes will just be pushed to the running client when you save. You don't even have to re-launch it! (Keep in mind that certain things will require a re-launch, such as variable initialization, onLoad events, etc)
{% endhint %}

<figure><img src="/files/l5jdykGViRMAa3j3wcrP" alt=""><figcaption><p>Preview of the Customers Value List</p></figcaption></figure>

You can see that the `customerid` is now hidden and the `customers.companyname` field is shown instead. Moreover, when you edit the Type Ahead field, your results will match on records in the table based on the `companyname` but the correct value will be stored in the `orders.customerid` field.

### Create an Employees Value List

Let's create one more Value List for the employee connected to the order. This time we will create the Value List first then bind it to the `employeeid` field.

In the Solution Explorer, right-click the ValueLists node and select Create Value List. Enter the name `employees` for your next Value List. This will open the new Value List in the Value List Editor.

{% hint style="info" %}
Value Lists are completely reusable. Define them 1x and use them *anywhere* in your solution. They can even be referenced in your scripts!
{% endhint %}

<figure><img src="/files/uJ0wYUynjslHtrJ4xUBF" alt=""><figcaption><p>Create Employees Value List</p></figcaption></figure>

Follow similar steps as you did for the customers Value List. Set the **data source** to be `example_data.employees`. This time we will set multiple **display values**, using both `firstname` and `lastname` for the display. Use `employeeid` for the **real value**.

<div align="left"><figure><img src="/files/ShVBqnOqNqaIWCEIJ1it" alt=""><figcaption><p>Properties for employees value list</p></figcaption></figure></div>

### Add the Employee Type Ahead

Delete the `employeeid` Text Box from the form and similar to the customer field, drag a Type Ahead component from the pallet to replace it. Set the `dataProvider` value to `employeeid` and this time, when you set the `valuelist` property, you will choose the `employees` Value List that we just created. Save your editors and preview your changes in the NG Client.

<figure><img src="/files/njc1aSJ5JvNlcozh84o9" alt=""><figcaption><p>Preview of Employees Value List</p></figcaption></figure>

You can see that because we specified *two* display values, the employees value list shoes both `firstname` and `lastname`. Moreover the lookup will query *both* columns to match values!

## Working With Labels

In this section, we will quickly edit some of the labels that we have already placed, then we will explore how to add more data-driven text.

### Edit Label Text

The labels for each of the fields defaulted to the name of the database column, which is rather ugly. Let's quickly update those labels to something nicer.

<figure><img src="/files/cU0usTCEqOebgYjclAuV" alt=""><figcaption><p>Update label text by double-clicking</p></figcaption></figure>

To edit the content of the label, simply double-click the label in the form editor and begin editing the text.

### Adding a Data-Driven Label

In Servoy, any text can be data-driven and localized. Let's place a label that shows some plain text mixed with **merge tags**.

<figure><img src="/files/ESZfPd73iwv3pbQhhGIj" alt=""><figcaption><p>Place a data-driven label</p></figcaption></figure>

1. Drag a Label component from your pallet onto the form.
2. Select the `text` property of the label click the `...` button to open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).
3. Enter the literal value "Order #" then use the data provider chooser to append the `orderid` column to the text, giving the value: `Order #%%orderid%%`
4. Edit the `styleClass` property, selecting `h2`. This will change the style of the label. (We will cover more on styling in a later chapter)
5. Save your changes and preview the results in the NG Client. You can see that the `%%orderid%%` tag was merged with the data value from the record.

![](/files/wsdPg6NmXLvKHMJXKTn5)

## Format a Date

In the final section of this chapter, we will see how to format data values, in this case, we'll set a format for the `orderdate` field.

![](/files/pjV4Ebx7nuHdtIwE8GSn)

1. Select the `orderdate` field on the form and select its `format` property, then click the `...` button to open the [Date Format Editor](/reference/servoy-developer/object-editors/date-format-editor).
2. Edit the Display Format. Enter `yyyy-MM-dd` (or a format of your choice). This will format the value when it is being displayed.
3. Select the `Use as mask` option for editing. This will allow the user to just enter the value digits and not the separator.
4. Click OK and save your form editor and preview in the NG Client. You can see that the date is formatted and the user can enter with masking.

<div align="left"><figure><img src="/files/arBtdSR5b51yRyMoV1up" alt="" width="563"><figcaption><p>Format a date field</p></figcaption></figure></div>


# Chapter 2

Create your first data grid and enhance your layout

## Overview

In this chapter we will add a grid component to the form to show all orders and allow the user to click through records. We'll add some related data and we'll learn about positioning components.

### Key Concepts Covered

* **Relations**
* **Data Grids**
* **Simple Positioning**
* **Date format** (review)

## Create a Relation

Let's get started by creating your first Relation. We're going to create a relation from the `orders` table to the `customers` table.

<figure><img src="/files/1fXDTmjY2gUXJkEAR7Pr" alt=""><figcaption><p>The Relation Editor; creating the relation <code>orders_to_customers</code></p></figcaption></figure>

1. From the [Solution Explorer](/reference/servoy-developer/solution-explorer), right-click the "Relations" node and select "Create Relation". This will open the [Relation Editor](/reference/servoy-developer/object-editors/relation-editor).
2. Set the `Source` by clicking the `...` button to open the Data Source Chooser. Select `example_data.orders`and click OK.
3. Set the `Destination` by choosing `example_data.customers`
4. Create one relation item where `orders.customerid` `"="` `customers.customerid`
5. Save the editor.

{% hint style="info" %}
Notice you don't have to specify the relation name. The editor will always suggest `source_to_destination`, in this case **orders\_to\_customers**. This is a good convention to follow for ordinary relations.
{% endhint %}

## Create a Data Grid

In this step you will create your first **Data Grid** and position your components more precisely using **Simple Positioning**.

### Re-Position your Fields and Labels

We are going to add a Data Grid to the left side of the form, but first weEdit need to make some space for it, let's move our fields and labels out of the way.

<figure><img src="/files/babdyGtNCqRZFgxtskB8" alt=""><figcaption><p>Edit the CSS Position Left property</p></figcaption></figure>

1. Select all your components by click-dragging a box around them. Now you can edit their shared properties in one go.
2. In the **Properties Editor**, expand the `cssPosition` property and edit the left property, clicking the `...` to open the **CSS Position Property Editor**.
3. Choose the `calc` option and set it to `25% + 10px`. This will position the left edges of the component 25% of the total width of the form, plus an additional 10 pixels.

### Place the Data Grid

Now we are ready to place the Data Grid so the user can easily click through multiple order records.

<figure><img src="/files/cpB1ot0fRSFaQctkauP7" alt=""><figcaption><p>Place a Data Grid</p></figcaption></figure>

1. From the pallet, drag the Data Grid component on to your form. The [Grid Columns Configurator](https://github.com/Servoy/gitbook/blob/master/guides/get-started/broken-reference/README.md) will immediately open.
2. You will see the `orders_to_customers` relation that you have already created. Expand it and choose the `companyname` data provider.
3. Choose one more data provider, `orderdate`.
4. Edit the Header Title property, entering `Customer` and `Date` (These will appear in the column headers) and click OK.

#### Adjust the Position

Let's adjust the grid's position, similar to what we did to the other components. Select the grid and edit the cssPosition property. Enter the following values.

![](/files/TLdpge1iZsjOzB7FfIOA)

* right: 75% (75% of the width of the form from the right edge)
* bottom: 10px (10 pixels from the bottom)
* left: 10px (10 pixels from the left edge)
* min-width: -1 (this means that no minimum will be enforced)

#### Set the Date Format

Select the date column on your grid. In the **Component Properties Editor**, edit the `format` property. Enter a value of `yyyy-MM-dd`. This will format your date column year-month-day.

Save your editors and preview your changes in the NG Client.

<figure><img src="/files/JKf5TD10IkCkMkYsqHcR" alt=""><figcaption><p>Preview Data Grid in NG Client</p></figcaption></figure>

You can see that the grid is showing the related customer info with the formatted date. It occupies 25% of the form's width and it can be used to navigate records in the `orders` table.

{% hint style="success" %}
The form's grid and fields are data-bound and the Servoy platform manages all the querying, caching and record selection for you. No code needed!
{% endhint %}


# Chapter 3

Add related data, calculated data and format numbers

## Overview

In this chapter, we will add the order details to show which products have been ordered. We'll create several new relations and a data grid. We'll add a calculated value and format a number to the localized currency.

### Key Concepts Covered

* **Calculations**
* **Formatting Numbers**
* **Value Lists** (review)
* **Relations** (review)
* **Data Grid** (review)

### Create a Relation

First let's create a new relation to set up our next data grid. We will create relations to the `order_details`table. (This is a review from the previous chapter, so please review that it you need to.)

### Orders to Order Details

Let's create a relation so that we can show all the details of a single order.

<div align="left"><figure><img src="/files/0YIHfPDc9LdErErtZ54I" alt=""><figcaption><p>Relation Editor: orders_to_order_details</p></figcaption></figure></div>

Create a new relation object. Select `example_data.orders` as the *from* data source. Select `example_data.order_details` as the *destination*.

{% hint style="info" %}
Notice that the Relation Editor correctly guesses the foreign key `order_details.orderid`. This is because it has the same name as the PK column in the source table.
{% endhint %}

## Place the Order Details Grid

Next, we'll place another Data Grid on the form, this time choosing a related data source.

<figure><img src="/files/JEkSRPpIPR1qn2LcwnGJ" alt=""><figcaption><p>Place Related Data Grid</p></figcaption></figure>

1. When the Columns Configurator appears, click the `...` button to choose a different data source.
2. Expand Related Foundset to find your relation `orders_to_order_details`. Select it and click OK.
3. Now you will see the data providers for the `order_details` table. Choose the following data providers, set their title text and click OK.
   * productid
   * quantity
   * unitprice

#### Position the Grid

Position your grid to take the remaining 75% of the width and stretch near the bottom edge. Set the `cssProperty` of the grid to the following values:

* left: calc(25% + 10px) This is the same value as the other fields and labels
* right: 10px
* bottom: 10px

Save your editor and preview the changes in the NG Client. You can see that as you select different order record, the related order details records of each order are loaded in the grid. However, this grid does not look great. Let's make it nicer by adding a product lookup and formatting the price.

<div align="left"><figure><img src="/files/baXuABFdwRtuWZwMPVz3" alt=""><figcaption><p>Order Details Grid Preview in NG Client</p></figcaption></figure></div>

### Create a Products Value List

Let's create a value list to show a nicer lookup on the product name for the product id foreign key. This will also help us when we make the grid editable.

<div align="left"><figure><img src="/files/t5cEOJ0EYL4cAUEbcdkt" alt=""><figcaption><p>Value List Editor: Products Value List</p></figcaption></figure></div>

Create a new Value List with the following properties.

* Name: products
* Type: Table Values
* Data Source: `example_data.products`
* Display Value : `productname`
* Real Value: `productid`

Save the editor and attach the new Value List to the product column in the grid by editing the column's `valuelist` property and choosing the `products` Value List.

### Format the Unit Price

Next, let's make that Unit Price column look nicer by applying a Number Format.

1. Select the Unit Price column
2. Edit the format property and click the `...` to open the **Number Format Editor**.
3. Choose `¤#.00` for the Display Format
4. Choose `#.00` for the Edit Format (we'll make this grid editable in the next chapter)
5. Click OK and save your editor. You can preview your changes in the NG Client.

### Adjust the Column Widths

You may have noticed that the column widths are auto-sized, which is convenient. However, the quantity and the unit price are both reliably skinny values. Let's set a default width for these columns to leave more room for the product name.

1. Select the Quantity column and set the `max-width` property to `150`.
2. Do the same for the Unit Price column.
3. Save and preview in the NG Client.

<div align="left"><figure><img src="/files/2FPb5A8jTmKhPNEvVL1Y" alt=""><figcaption><p>Order Details Grid with Value list, formatting and column width settings</p></figcaption></figure></div>

Notice your product name is displayed instead of the ID. The Unit Price is formatted with the localized currency, and while the product column stretches, the other two maintain a max-width.

## Create a Calculation

For the last exercise in this chapter, we are going to create a **calculation**, to compute the subtotal of an order detail record.

<div align="left"><figure><img src="/files/1HVtj5z7fQToOeHnaVoX" alt=""><figcaption><p>Create a Calculation</p></figcaption></figure></div>

1. From the [Solution Explorer](/reference/servoy-developer/solution-explorer), locate your `order_details` table:\
   `Resources > Database Servers > example_data > order_details`
2. Double-click to open it in the [Table Editor](/reference/servoy-developer/object-editors/table-editor)
3. At the bottom of the Table Editor, select the Calculations tab.
4. Click the `Add` button and name your calculation `subtotal`.
5. Select `NUMBER` as the data type and save. Then, click 'Open selected calculation' to open the script editor.

### Write the Calculation Script

In the script editor, you will see a JavaScript function stub called `subtotal`. Every calculation is a function that must return a value, in this case, you will simply multiply the quantity by the unit price. Enter the following.

```javascript
function subtotal()
{
	return quantity * unitprice;
}
```

{% hint style="info" %}
When you edit code in a calculation, a number of objects, including other data providers are in scope. You can get code complete by typing `CTRL-SPACE`. This is helpful to find the names of available data providers.
{% endhint %}

### Add the Calculation to Your Grid

Now you may place your calculation on your grid, just like any other column.

<figure><img src="/files/ocSJh1YKr8UY7LXCBipk" alt=""><figcaption><p>Add the subtotal calculation to the grid</p></figcaption></figure>

1. From the pallet, drag a Column onto your grid component
2. Double-click the `dataprovider` property to open the Data Provider Chooser
3. You will see a **calculations** node, expand it and select your `subtotal` calculation
4. Set the `headerTitle` property to "Subtotal"
5. Set the `max-width` property to `150`
6. Finally, set the display `format` property to `¤#.00`, as you did for the Unit Price column

Save your editor and preview your changes in the NG Client. You can see that the subtotal column displays the calculated results for each line in each order.

<div align="left"><figure><img src="/files/HiwUjbcF8b4Lw8RMsCzD" alt=""><figcaption><p>Calculation added to grid</p></figcaption></figure></div>

{% hint style="success" %}
Calculations are called when they are displayed and referenced in your scripts. But they are also refreshed when data is changed. This means they are *always* up to date!
{% endhint %}


# Chapter 4

Working with data, scripted logic

## Overview

In this chapter you'll begin to work with data and connect some scripted logic to UI events. We'll make our Order Details grid editable, add a button and code to create a new order, create a more advanced calculation field and more.

### Key Concepts Covered

* **Editing Data**
* **Foundsets**
* **UI Events**
* **Scripted Logic**
* **Calculations** (Review)

## Make the Grid Editable

Let's begin by adjusting our Order Details grid to accept user input.

<div align="left"><figure><img src="/files/4Armt1PayWfgL2AAz96l" alt=""><figcaption><p>Set the grid column editType property</p></figcaption></figure></div>

1. In the Form Editor, select the Product column on your Order Details grid
2. In the Component Properties Editor, set the `editType` propery to `TYPEAHEAD`
3. Do the same for the Quantity column, this type setting the property to TEXTFIELD
4. Repeat the step for the Unit Price column

Save your changes and preview the result in the NG Client. You will be able to double-click into the fields and edit them. Note that the subtotal calculation is not editable .

<figure><img src="/files/gG2tidNJkVruhG1qXH1S" alt=""><figcaption><p>Preview the eidtable grid</p></figcaption></figure>

{% hint style="success" %}
**Calculation Refresh**\
Try editing the Quantity or Unit Price column. You'll notice that the subtotal calculation is instantly updated when you change the inputs.
{% endhint %}

{% hint style="info" %}
**TAB Key Support**\
After you begin editing a grid cell, try tabbing through them with the TAB key.
{% endhint %}

## Create new Records

Now that we can edit all the data on an order, it's time to give the user the ability to add new records. Let's begin by placing a button for new orders and hooking it up to some code.

<div align="left"><figure><img src="/files/kbFUQyOslYFjwwmLzzhr" alt=""><figcaption><p>Place a button for new orders and create an onAction handler</p></figcaption></figure></div>

1. From the pallet, drag a Button component to the form
2. In the Component Properties Editor, set the `text` property to "New Order"
3. Set the `cssPosition` property to have the button anchor right: `45,`**`10`**`,-1,-1,140,30`
4. Double-click the `onAction` property to open the **Method Selection Wizard**
5. Select the option to create a method in the form and give it a name: `newOrder`
6. Choose Create Private and click OK.

<div align="left"><figure><img src="/files/47V8h5x6y2rar1JlHETt" alt="" width="523"><figcaption><p>The <code>newOrder</code> method stub is created</p></figcaption></figure></div>

The `orders.js` file opens in the Script Editor and the new method stub `newOrder` is created. The `onAction` event of the New Order button is handled by this method. You are ready to fill in the logic.

{% hint style="info" %}
Each form has its own `.js` file to manage the scripting for the form. This is where most event handlers and other UI logic will be implemented.
{% endhint %}

### Add the New Record Logic

Next, you'll add some code to create the record.

```javascript
function newOrder(event) {
	foundset.newRecord();
}
```

Here you will use the form's **foundset** object, which manages all of the data access. Invoke the [newRecord](/reference/servoycore/dev-api/database-manager/jsfoundset#newrecord) method to create a new record object in the foundset.

{% hint style="info" %}
**Code Complete**\
Type `CTRL-SPACE` at any time to get code completion. You will also get completion after the dot (`.`) character.
{% endhint %}

## Lookup Ship Info from Customer

Let's explore a bit more the idea of handling UI events in code. This time we will lookup the order's shipping info from the related customer record.

### Add Ship Info Fields

First, let's get some of the ship info fields on the form.

![](/files/u5kgtMVWn7fxPPwcBe9G)

1. Click the ![](/files/3MjtQPsu8K57OtwmzwhN)Place Fields button to show the **Place Fields Wizard**. (You used this wizard when you first created the form)
2. Choose the following fields: `shipaddress`, `shipcity` and `shipcountry`.
3. You can adjust their `cssPosition` property to align next to the other fields:\
   `left=calc( 25% + 200px)`

### Add a Data Change Handler

The ship info will be empty when a new record is created, but we can add some logic to lookup from the related customer record whenever the `customerid` changes.

<div align="left"><figure><img src="/files/xKJE7YTSXlDgP4iTUE9X" alt=""><figcaption></figcaption></figure></div>

1. Select the Customer field and double-click its `onDataChange` event to open the Method Selection Wizard.
2. Create a new method in the form named `onDataChangeCustomer`
3. Create Private and click OK

The new method stub is created in the same file as the `newRecord` method.

### Add the Lookup Logic

In the new method, enter the following code to lookup the address info from the related customer and enter it as shipping info.

```javascript
function onDataChangeCustomer(oldValue, newValue, event) {
	
	// Lookup ship info from customer address
	shipaddress = orders_to_customers.address;
	shipcity = orders_to_customers.city;
	shipregion = orders_to_customers.region;
	shippostalcode = orders_to_customers.postalcode;
	shipcountry = orders_to_customers.country;
	
	return true;
}
```

That's it! Just a few lines to copy the data over. Save all your editors and preview the changes in the NG Client.

<figure><img src="/files/VoIUwai1KKkD4JmNHt1R" alt=""><figcaption><p>Preview of the ship info lookup in the NG Client</p></figcaption></figure>

You can see that a blank, new record is created and when the user selects the customer for the order, the ship info is immediately looked-up from the related table.

## Create Related Records

Now that we can create order records, the user will want to add Order Detail records as well. Let's add a button and a method to create the related records.

<div align="left"><figure><img src="/files/W3zIQGHF3hRCaX0zRKbI" alt=""><figcaption></figcaption></figure></div>

1. From the pallet, drag a button on to your form. Set the `text` to "Add Item"
2. Double-click the `onAction` event and create a new method in the form called `addItem`.
3. Set the `cssPosition` property to have the button anchor right: 240,**10**,-1,-1,115,30
4. Create private. Click OK and Show.

The `addItem` method stub is created in the `orders.js` file and ready for your logic. Enter the following code to your method.

```javascript
function addItem(event) {
	
	// create the record 
	orders_to_order_details.newRecord();
	
	// set the quantity default to 1
	orders_to_order_details.quantity = 1;
}
```

Here you can see that the relation, `orders_to_order_details`, can be used in code to reference the related JSFoundSet object and the `newRecord` method is available. You can also reference the data providers of the related foundset, such as `quantity`. Save your editors and try it out in the NG Client.

{% hint style="success" %}
**Related Foundsets**\
You just created a record through a related foundset. The Servoy platform understands your relation and will insert the record with the correct foreign key automatically!
{% endhint %}

## Lookup Product Price

Let's add a little more logic to our form, again using UI event handlers. This time, let's lookup the price of a product and auto-fill the Unit Price column for an Order Detail.

### Create a Relation to Products

To be able to lookup the price of the product, we must first create a relation to the `products` table. You've done a few of these by now, so it should just take a moment

<div align="left"><figure><img src="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjpWd52BKwABWxF2lScUK%2Fuploads%2Fi18lqU7HzrZrMADOJlRp%2Fimage.png?alt=media&#x26;token=f9ffa144-5011-473c-beb9-7f15c58ff43b" alt=""><figcaption><p>Relation Editor: <code>order_details_to_produtcs</code></p></figcaption></figure></div>

1. Create a new relation object. Select `example_data.order_details` as the *from* data source. Select `example_data.products` as the *destination*.
2. Match the `productid` column from both tables. Save your editor and continue.

### Create a Handler for Data Change Event

Next, we will implement a handler for the data change event, so that we can update the price based on the selected product.

1. Select the Order Details grid and in the Component Properties Editor, double-click the `onColumnDataChange` event to open the Method Selection Wizard.
2. Create the new method in the form and click OK
3. Once again the method stub is added to your `orders.js` file

Enter the following code into your method stub:

```javascript
function onColumnDataChange(foundsetindex, columnindex, oldvalue, newvalue, event, record) {
	
	// Check if the first column (Product) was changed
	if(columnindex == 0){
		orders_to_order_details.unitprice = 
			orders_to_order_details.order_details_to_products.unitprice;
	}
	return true;
}j
```

This data change event is a little different than the one for the Type Ahead used previously for the Custom field. This event is called when *any* of the grid's columns (or rows) have a data change. Fortunately, more information is passed in as arguments to help us figure it out.

**Evaluate which column changed**\
The `columnindex` parameter can be used to infer which column has changed. The Product column is the first column in the grid and therefore index `0`.

**Lookup Product Price**\
Once again, using the relations you have made, you can assign a value to the `unitprice` column in the `order_details` table from the `unitprice` column in the `products` table.

{% hint style="success" %}
**Relation Chaining**\
Notice how you can chain relations together to easily traverse your data model in code. The Servoy platform will handle all the querying and updating without a hitch.
{% endhint %}

## Create an Order Total Calculation

In the final step in this chapter, we will create another, more complex, calculation to derive the total value of an order.

### Using the Servoy Resource Locator

Open your orders table in the Table Editor. This time we'll learn to use the [**Servoy Resource Locator**](/reference/servoy-developer/object-editors/servoy-resource-locator) to quickly find and open the table.

<div align="left"><figure><img src="/files/1v7TfhtKHqhF6FOZd7sl" alt=""><figcaption><p>The Servoy Resource Locator</p></figcaption></figure></div>

1. From the main toolbar, click the ![](/files/NKW0AmC7WbkHZYWZZOoH) button `(alt+shift+k)` to open the Servoy Resource Locator.
2. Type the first few characters of the file you are searching for, i.e. "orders"
3. Use the mouse or down arrow key to choose the resource to open and click OK or type ENTER.

### Create the Calculation Script

Create a new calculation, just as you did in the previous chapter. The name should be `order_total` and the data type should be `NUMBER`.

<div align="left"><figure><img src="/files/QIIyhBUYaeC1FulrlWC3" alt="" width="375"><figcaption><p>Using Code Completion <code>CTRL-SPACE</code></p></figcaption></figure></div>

{% hint style="info" %}
**Code Completion is Great!**\
Notice in this image that code completion can be used to generate a template of a **for loop** and other constructs. After which you can TAB through each element of the template.
{% endhint %}

```javascript
function order_total()
{
	var sum = 0;
	for (var i = 1; i <= orders_to_order_details.getSize(); i++) {
		var record = orders_to_order_details.getRecord(i);
		sum += record.subtotal;
	}
	return sum;
}
```

In this code, we iterate over the Order Details and tally the subtotal of each line.

1. Create a local variable for the sum
2. Create a for loop (use code completion - `CTRL-SPACE`) to iterate over records in the related `orders_to_order_details` foundset.
3. Access each `order_detail` record and add its `subtotal` calculation to the sum using the `+=` operator.
4. Every calculation must return a value, in this case the `sum` variable.

### Place a Data Label - Order Total

We are finally ready to place the `order_total` calculation on the form. Let's use a new component, **Data Label** to show the total. This component is a regular label, but binds directly to a data provider and allows us to apply a format.

1. From the pallet, drag the Data Label component onto your form
2. Double-click the dataProvider property in the Component Properties Editor and select the `order_total` calculation.
3. Edit the `format` property and apply a format to a localized currency.
4. You may edit the `cssPosition` property to align it next to your Add Item button: `270,130,-1,-1,80,30`
5. Edit the styleClass property and add a style of `font-weight-bold`
6. You may add another label next to it with the text "Order Total"

Save your editors and preview your work in the NG Client.

<div align="left"><figure><img src="/files/tcgut9oqhFkpRDtWsOMd" alt=""><figcaption><p>Fully editable records and dynamic calculations</p></figcaption></figure></div>

{% hint style="success" %}
**Chapter Complete**. Nice work! Now you should be able to:

* Create a new order record
* Lookup and attach a customer, which does an auto-fill of the ship info.
* Next you should be able to add order detail records.
* As you lookup the product, you should get an auto-fill of the unit price.
* Finally, you should see your calculations for subtotal and order total automatically refreshing as you make edits.
  {% endhint %}


# Chapter 5

Working with extensions

## Overview

In this chapter we will install a few extensions to enhance our application. The Servoy platform is highly extensible and it's easy add capabilities to your project.

## Key Concepts Covered

* **Servoy Extensions**
* **Servoy Package Manager** (SPM)
* **Modules**
* **Form Variables**
* **Search Module Extension**
* **Scopes**
* **Chart Component Extension**

## Add Search Capability

In this section, we will install a special extension to enable text-based searching of our database. Then we will bind it to a **TextBox** component and process user input to find records in our example database.

### Install a Search Module

Let's install the **SvySearch** module using the **Servoy Package Manger (SPM)**.

<figure><img src="/files/3WD7weCmV5MNGcGcfuAT" alt=""><figcaption><p>Install SvySearch module via the SPM</p></figcaption></figure>

1. At the top of your pallet, click "Get more components". This opens the SPM.
2. Click "Modules" and scroll down to locate "SvySearch" Click the `+` button to install it.

{% hint style="info" %}
**The Servoy Package Manager**

Also known as the **SPM**, it makes it easy to manage the **extensions** in your project.
{% endhint %}

The SvySearch module will be installed in your workspace and will be referenced as one of your solution's modules. You will find it located under the **Modules** mode in the **Solution Explorer**.

{% hint style="info" %}
**Modules**

Servoy is modular by design. Any Solution can be reused as a "Module" and it's easy to include modules in your application via the SPM. However, you can also create your own modules to simplify larger applications, reuse code and standardize development.
{% endhint %}

### Create a Form Variable

Because we will search based on user input, we will use a **Form Variable** to capture and reference the input.

<div align="left"><figure><img src="/files/EsedjXnp4bZXOXhkz1sx" alt="" width="375"><figcaption><p>Create Form Variable</p></figcaption></figure></div>

1. From the Solution Explorer, expand your `orders` form and locate the `variables` node.
2. Right-click and select "Create Variable" to open the **Form Variable Editor**.
3. Give your variable a name `searchText`, the Type as `TEXT` and the default `null` value.
4. This also opens the `orders.js`, showing your variable declaration in source.

{% code fullWidth="false" %}

```javascript
/**
 * @type {String}
 *
 * @properties={typeid:35,uuid:"02248C57-9D99-427A-99FB-748B405F2022"}
 */
var searchText = null;
```

{% endcode %}

{% hint style="info" %}
**Form Variables** work like any other Data Provider, such as database columns, except that they are not stored to a database. They hold session state, such as user input. You can also **manually type** the variable declaration into your form.js file.
{% endhint %}

### Add a Search Field

Let's add a field to the form and bind it to our form variable to capture the user input.

1. From the pallet, drag the **TextBox** component to the form, placing it above your orders grid.\
   (You can use the `cssPosition` property `10,75%,-1,10,140,30`)
2. Double-click the `dataProvider` property to open the **Data Provider Chooser**. Select the `searchText` form variable that you just created.
3. Edit the `placeholderText` property to be "Enter Search Criteria" This text will be displayed when the field is empty.

### Handle Input Event

To run the search, we'll need to bind an event handler to call the search module that we added. This time, we'll use the **onAction** event, which we've seen for buttons. However, for an input field, this will be triggered when the user hits the `ENTER` key.

1. Double-click the `onAction` event of the TextBox component that you just added. This opens the **Method Selection Wizard**.
2. Choose "Create method in Form". Name your method `onSearch` and select "Create Private". Click "OK and Show" to finish. The new method stub is opened in the `orders.js` file.
3. Let's add a few lines to the method. Don't be shy, you will get help from code completion based on the installed module.

{% code lineNumbers="true" %}

```javascript
function onSearch(event) {
	var search = scopes.svySearch.createSimpleSearch(foundset);
	search.setSearchAllColumns();
	search.setSearchText(searchText);
	search.loadRecords(foundset);
}
```

{% endcode %}

* Line `2` we access the **SvySearch** module and create a new search object based on this form's **DataSource** or **FoundSet**.
* Line`3` we indicate that the search will look across all `TEXT` columns in the data source.
* Line 4 we indicate that the search object should use the user input, captured in our form variable `searchText`.
* Line `5` we bring it home by applying the search object to this form's **FoundSet**. This will run the search and load records in our form.

{% hint style="info" %}
**Scopes**

You'll notice a new keyword `scopes` in this example. So far, we've only looked at form-level script files. Scopes are another kind of script file used to reference top-level packages of code in your solution and other modules. Enter `"scopes."` to get code completion on all available scopes.
{% endhint %}

Save your editors and preview the change in the NG Client. Enter some text in your search input field and hit `ENTER`.

<figure><img src="/files/fNUhZI2KaaJRhvR4To91" alt=""><figcaption><p>Search by Country</p></figcaption></figure>

Here you can see that the search module is able to match on all orders where the `shipcountry` column = Germany. Try it out! What happens when you enter a string fragment, such as "germ" or part of a city name instead?

### Search on Related Data

This is nice, but let's try something a little more...."advanced". Suppose we wanted to search on a customer name or a product in and order? Fortunately the **SvySearch** module is quite powerful and this can be done by adding just a little code.

<pre class="language-javascript" data-line-numbers><code class="lang-javascript">function onSearch(event) {
	var search = scopes.svySearch.createSimpleSearch(foundset);
	search.setSearchAllColumns();
	search.setSearchText(searchText);
	search.addSearchProvider('orders_to_customers.companyname');
<strong>	search.addSearchProvider('orders_to_order_details.order_details_to_products.productname');
</strong>	search.loadRecords(foundset);
}
</code></pre>

Let's examine the two lines of code added to enable a related search.

* Line `5` we add the related data provider for the company name
* Line `6` we add the order detail records and the related product name.

Save your editor and preview the results in the NG Client.

Enter "big" and you will match on the orders of the customer "The Big Cheese". Enter "coffee Germany" and you will match on all orders shipped to Germany having coffee as one of the products.

{% hint style="success" %}
**Robust Searching**\
Well done. You added a robust user text search to your application in just a few lines of code. The Servoy platform handles all the parsing of terms, caching and querying. This approach works equally well on very large databases.
{% endhint %}

## Add a Chart Component

Let's finish the chapter by adding a simple chart to our orders form to help visualize the breakdown of the products. It takes just a few clicks and demonstrates how to add extend your pallet of components.

### Install the ChartJS Component

In the previous example, we added a **module**, which included some code libraries we took advantage of. In this example, we'll add a new **component** package.

<figure><img src="/files/W4B4yJam5wyaaNzDSmI4" alt=""><figcaption><p>Chart Component</p></figcaption></figure>

1. Open the **Servoy Package Manager** (SPM) as you did in the previous example. In the list of components, scroll to find the **ChartJS** package and click the `+` button to install.
2. After the package installs, the component is available drag a chart component from the pallet onto your form.
3. You may position the component right of your input fields, by setting the `cssProperty` to `86,-1,-1,calc(25% + 390px),200,170`
4. Next, we'll set the data binding for the component. Double-click the `foundset` property to open the **Foundset Chooser**. Select your `orders_to_order_details` relation and click `OK`.
5. Expand the `dataproviders` sub-property and double-click the `label` property to open the Data Provider Chooser. Select `order_details_to_products.productname.` This will be the display value for the chart.
6. Do the same for the `value` sub-property and choose the `subtotal` calculation that you made in a previous chapter.
7. Just for fun, let's switch the chart type. Edit the `type` property and select `DOUGHNUT`.

Save your editors and preview the changes in the NG Client.

<div align="left"><figure><img src="/files/tuTJdaSGja0yykgxmqMd" alt=""><figcaption><p>Chart Component Preview</p></figcaption></figure></div>

You can see that the chart labels match the product name and the values match the subtotal. When the selected order record changes, the chart is redrawn. Moreover, when the input values to the subtotal calculation change (i.e. unit price), the chart is redrawn.

{% hint style="success" %}
**Data-Bound Components**\
Nice work! In only a few clicks (and zero lines of code) you have a working chart. Most UI Components in Servoy are data-bound by default, meaning they *always* reflect the real-time values in the connected data source....automatically.
{% endhint %}


# Get Help

This guide will explain how to get support when building with Servoy

## Community Forum

Whether you are just getting started or have become a Servoy expert, the [Servoy Forum](https://forum.servoy.com/) is perhaps the fastest way to get help from the vibrant Servoy developer community. Your questions will be answered by people who have walked in your shoes.

## Just Ask the Docs!

Did you know that Servoy's documentation site comes with AI-powered search? We've trained a large-language-model on our docs and it is ready to answer your question. You can try it out...right now! Just click `Ctrl-K` |`Cmd-K`.

The search dialog has two options: `Search` provides a traditional key-word search and `Lens` gives a prompt to ask an open question. The response includes an AI-generated natural language answer, plus suggested follow-up questions and most important, links to the pages where the content can be found.

<figure><img src="/files/CEcCYPwBz576ilokvek3" alt="" width="375"><figcaption><p>Example AI prompt and response in Lens mode</p></figcaption></figure>

## Appsurance Program

Servoy provides a best-in-class expert services program for onboarding, training and project steering to help ensure the success of critical software projects. We call it "Appsurance" (Application+Assurance). Our experts live it everyday and we know how to help. Please contact your account representative or <sales@servoy.com> for more info.

## Support Level Agreement


# SuLA Instructions

Instructions on how to receive commercial support.

### Overview

As an open-source platform, Servoy allows anybody to file bugs and feature requests in our case management system. However, we offer preferred Support Levels to paying customers with guaranteed response metrics. This page covers the instructions for receiving commercial support.

{% hint style="info" %}
If you are uncertain if you have a SuLA, contact your designated account manager or <sales@servoy.com>.
{% endhint %}

### Accessing the Incident Portal

You can access the [**Incident Portal**](https://servoy-cloud.atlassian.net/servicedesk/customer/portal/7) directly and log in if you have an account. You can also link to it from our general case management system at [**support.servoy.com**](https://support.servoy.com)**.**

{% hint style="info" %}
Case Management System vs Incident Portal. **What's the difference?!**\
Because Servoy is an open source platform, we publish our bugs and features transparently on our case management system [**support.servoy.com**](https://support.servoy.com)**.** The [**Incident Portal**](https://servoy-cloud.atlassian.net/servicedesk/customer/portal/7) is for private support for SuLA customers.
{% endhint %}

#### Creating a Support Account

On both the [**Incident Portal**](https://servoy-cloud.atlassian.net/servicedesk/customer/portal/7) and the case management system, You will be prompted to log in. If have not already created an account, you can do so using your **email**.

{% hint style="info" %}
**Which email address to use ?**

In order for your account to be linked to the proper SuLA, you must use your **company email** that is associated with the organization which holds the SuLA.

For example, use **<me@mycompany.com>** instead of **<me@gmail.com>**
{% endhint %}

Once you have provided your email, you will be sent a password reset link. Check your spam/promotion folders to ensure you have received the email.

Enter a secure password to finish creating your account. Your user profile will be associated to the SuLA company by domain name.

<figure><img src="/files/hUiYJolH8qNZZVYPIHkV" alt=""><figcaption><p>Use your company email to register for a support account</p></figcaption></figure>

### Creating a Request

Once you have logged in, you are ready to create a support request.

<figure><img src="/files/QYKWTJVW8h92BV7V3fsI" alt=""><figcaption><p>Select an issue type and enter the required info</p></figcaption></figure>

1. The first step is to select the **type of issue** that you are experiencing. The available issue types include:

* **Bug** - Select this issue type if you believe that you are experiencing a bug with the Servoy Platform or developer environment that is impacting your organization.
* **Feature Request** - Select this issue type if you believe that the Servoy Platform is missing an essential feature which will help your organization
* **Technical Question** - Select this issue type if you are experiencing an issue in development and deployment, but you don't believe (or you are uncertain) that it is caused by a Servoy Bug.
* **General Question** - Select this issue if you have a non-technical or general question about the Servoy Platform, such as billing or company policies or procedures.

2. Next, provide a **summary** and **description** of your issue. Be sure to be specific and provide all relavent information. The more information we have up front, the faster our agents can help to resolve your issue.\
   \
   Please include any supporting **attachments**, such as log files or screenshots of errors or warnings, etc. (Dont worry, your issue's details will be **private** to just you, and your organization if you choose to share it with colleagues).\
   \
   Finally, don't forget to enter the **Servoy Version**(s) on the developer or deployment environment(s) where you are experiencing the issue. This will help us to narrow down the caue more quickly.

### Confirmation

After you have submitted your support request, you will receive **confirmation via email** with links to monitor your issue in the [**Incident Portal**](https://servoy-cloud.atlassian.net/servicedesk/customer/portal/7).

<figure><img src="/files/vAx9AgyxvonN2SJRaLwW" alt="" width="375"><figcaption><p>Email confirmation of support request</p></figcaption></figure>

You will continue to receive notifications via email for any activity on this support issue. You may also **reply directly** in the email to message the support team.


# SuLA Terms

Servoy Support-Level Agreements (SuLA)

### Overview

As an open-source platform, Servoy allows anybody to file bugs and feature requests in our case management system. However, we offer preferred Support Levels to paying customers with guaranteed response metrics. This page covers the terms of Servoy's commercial support.

{% hint style="info" %}
If you are uncertain if you have a SuLA, contact your designated account manager or <sales@servoy.com>.
{% endhint %}

### 1. Support Levels/Types

Customers having a commercial license contract with Servoy will have indicated in their Product Order Form (POF) the agreed Support Level. In this document the details per level are indicated:

| Support Level | Coordinator | Response Time \* | Blocker Items \*\* |
| ------------- | ----------- | ---------------- | ------------------ |
| A             | No          | Best Effort      | 5 days             |
| B             | No          | 40 Hours         | 8 Hours            |
| C             | Yes         | 8 Hours          | 4 Hours            |
| D             | Yes         | 4 Hours          | 2 Hours            |

\* Response time during the SuLA support windows; see below par 6.\
\*\* Most critical Bugs (Blocker) must be reported to a live person of Servoy by phone.

### 2. Technical Support General Process

Servoy utilizes a 3-step support model for problem & feature resolution:\
● Qualification\
● Resolution design\
● Start of the Resolution

\
When initial contact with Servoy is made, a team member of Servoy will validate all information details relevant to the question or issue. Once all relevant information is available, the case is considered qualified. Part of this is separating issues into Bugs, feature requests, technical questions and other questions. Required information for a case to be qualified is described in Addendum 5 as attached hereto. A unique case number will be assigned and delivered to the contact person by Servoy, either verbally, via web request or via e-mail. This case number will be used to track any given issue from initial contact to final problem resolution. All cases can be monitored in the support system at on our [**Incident Portal**](https://servoy-cloud.atlassian.net/servicedesk/customer/portal/7)

\
Once a case is qualified, the resolution for it is designed and if applicable presented to Partner/End-User. After resolution approval by Partner/End-User, the designed resolution will be planned and implemented. The response time between a question/case and the provision of a qualification is called: T1. The time between a qualified question and resolution design is called: T2. The time between an approved resolution design and start of resolution is called: T3.

### 3. Contacting Support

All cases must be entered into the case system of Servoy which can be found on our [**Incident Portal**](https://servoy-cloud.atlassian.net/servicedesk/customer/portal/7).

If Partner/End-User is entitled to phone support, the numbers are:

* **USA Dial: + 1 866 489 5147** (support level agreement)
* **NL Dial: +31 (0)20 229 3641**

### 4. Communications

Extreme severity situations (Blocker) may require the parties to use the telephone for immediate communications. The parties will follow up such communications using: [**https://support.servoy.com**](https://support.servoy.com). For tracking and recording purposes, each party is responsible for funding the cost of this communication at their own location. In circumstances where materials have to be exchanged using facsimile, courier services, or other delivery services, each party is responsible for funding the cost of these exchanges at their own location.

### 5. Non-Servoy Bugs / Errors

If during the normal Support processes and appropriate management review, Servoy believes that a problem reported by Partner/End-User may not be due to a Bug, Servoy will notify Partner/End-User accordingly. In such event Partner/End-User may instruct Servoy:

1. to proceed with problem determination at its possible expense as set forth herein; or
2. that Partner/End-User does not wish the problem to be further pursued at its expense.

If Partner/End-User requested Servoy to continue with the problem determination at its expense and Servoy determines that the problem was not caused by a Bug, Partner/End-User shall pay Servoy at the Servoy's then-current standard hourly consulting rate at a time and material basis for all work performed in connection with such determination (including the discovery time spent), plus reasonable related expenses incurred therewith. Partner/End-User shall not be liable for the payment of the Servoy's then-current standard consulting rates in the event:

1. Problem determination or repair to the extent problems has been caused by a Bug; or
2. Work performed after Partner/End-User has notified Servoy in writing that it no longer wishes problem determination to be continued at its possible expense (such notice shall be deemed given when actually received by Servoy). If Partner/End-User instructs Servoy that it does not wish the problem pursued at its possible expense or such determination requires effort in excess of Partner/End-User's instructions, Servoy may, at its sole discretion, investigate the issue without any liability.

### 6. Support Windows

There are 2 types of Support windows:

* 5 (working days) \* 12: Extended business hours 7AM-7PM
* 5 (working days) \* 8: Normal business hours 9AM-5PM

The support window/working days are depending on the SuLA type as agreed upon the Product Order Form as well as the timezone of the Servoy branch providing the Support.

* USA time zone is PST
* NL time zone is CET

### 7. Designated Contacts

Servoy requires that designated contacts be identified with person-specific e-mail addresses.

* It is important to know and authenticate with whom Servoy is working; person-specific e-mail addresses assist in identifying valid contacts.
* The Partner/End-User can always "cc" their Support alias (if they have one and if they so choose) and Servoy will "reply all" in the Support request response, alleviating concerns the Partner/End-User has on situations where the contact who originally initiated the request for Support is "out of the office" but the organization has other support experts on hand working the issue.
* All Partner/End-User personnel contacting Servoy for Support must be familiar with the latest Major\
  Release of the Software and the current issue as to which Partner/End-User requires assistance.
* Partner/End-User agrees that contact with Servoy will be through a limited number of contacts

### 8. Coordination (Levels C and D)

For the SuLA level (C\&D), Servoy will dedicate a coordinator to assist in facilitating escalation. The coordinator is a non-technical representative, whose goal is to build close relationships and promote an understanding of infrastructure and processes. Some work items (especially those associated with critical situations) may need to be expedited. In such event, Partner/End-User will notify Servoy of the critical situation (Blocker) and Servoy will agree to work with Partner/End-User on providing the appropriate solution for each critical situation. If appropriate, Partner/End-User can also contact the support coordinator of Servoy

### 9. Program Upgrades

Servoy permits upgrades of Support at any time during the Term at the beginning of each calendar month. Servoy shall not issue prorated refunds. Notwithstanding the aforementioned, in the event Servoy modifies this SuLA and such modification has or will have substantial impact on the contents of the Support, Partner/End-User may terminate the Support forthwith upon Servoy implementing any such modification.

### 10. Offince Locations

<table><thead><tr><th valign="top">Servoy USA</th><th valign="top">Servoy NL</th></tr></thead><tbody><tr><td valign="top">30721 Russell Ranch Rd Suite 140, Westlake Village, CA 91362<br>Tel +1 866 489 514</td><td valign="top">Fred. Roeskestraat 97c,<br>1076 EC Amsterdam, Netherlands<br>Voice: +31 (0)20 229 3641</td></tr></tbody></table>

Servoy Web Site: [**https://www.servoy.com**](https://www.servoy.com)


# Develop

This guide will cover all the aspects of how to develop applications


# Application Design


# Forms

This guide will introduce the fundamental concept of Forms

## Overview

Forms are the fundamental unit of UI space in a Servoy application. Each form represents an area of screen on which interactions with UI Components, data and scripted logic takes place.

## Placing Components

### Layout Manager

Layout managers control how components are arranged and behave in forms. Each form uses one of the following layout managers and a solution may mix forms having any of these types.

* [**Simple Layout**](/guides/develop/application-design/forms/layout-management/css-position) **(CSS Position)**
* [**Advanced Layout**](/guides/develop/application-design/forms/layout-management/home) **(Responsive)**
* [**Abstract**](/guides/develop/application-design/forms/layout-management/abstract-form) **(No UI)**

## Data Binding

A Servoy Form is typically bound to a single database table and the form will always contain a single foundset which is bound to the same table. Much of the action in the user interface, such as a user editing data fields, directly affects the form's foundset. Conversely, actions taken on the foundset, such as programmatically editing data, is immediately reflected in the form.

Often, there can be several different forms which are bound to the same table. In most cases the forms will share the same foundset and thus provide a unified view. For example, imagine a form showing a list of customer records, where clicking on one of the records switches to another form showing a detailed view of only the selected record. The forms will automatically stay in sync and there is no need to coerce the forms to show the same record. Exceptions to this behavior include scenarios where forms are shown through different relations, or have been explicitly marked to use a separate foundset.

## Properties

Each form has a set of [properties](/reference/servoycore/object-model/solution/form#property-summary) that can be easily set and customized at design time using the form editor in Servoy developer, but also at runtime.

## Events

The form's behavior can be handled using the specific [events](/reference/servoycore/object-model/solution/form#events-summary) list, which can be found in each form's properties tab.

## Nesting Forms

Servoy developer allows users to nest forms, meaning a form can contain one or more other forms. This practice is helpful when a form needs to be used in more than one place, in order to avoid time consuming, repetitive work and also when it comes to changes, they would be done in one place only and applied everywhere the form is used. Nesting forms is done by using [form containers](/reference/servoyextensions/ui-components/form-containers#form-containers).

## Scripting Forms

A developer can create or add form and form elements related business logic to the application using the form scope, by accessing the [script editor](/reference/servoy-developer/object-editors/scripting-editor).

## Form Inheritance

A way of reusing objects is by [form inheritance](/guides/develop/application-design/forms/form-inheritance#form-inheritance). Servoy allows you to extend forms by other forms, which is a mechanism of creating new Forms (Child Form) that extend existing Forms (Super or Parent Form). As forms contain UI as well as variables and methods, all of this can be inherited and thus reused.

## Form Security

Servoy allows users to quickly set up user groups and enable multilevel security access to solutions. Form level security settings can be specified at the group level for an entire form or for selected form elements via the [Form Editor Security](/guides/develop/application-design/forms) subtab.


# Layout Management

## Overview

Layout managers control how components are arranged and behave in forms. Each form uses one of the following layout managers and a solution may mix forms having any of these types.

* [**Simple Layout** ](/guides/develop/application-design/forms/layout-management/css-position)**(CSS Position)**
* [**Advanced Layout**](/guides/develop/application-design/forms/layout-management/home) **(Responsive)**
* [**Abstract**](/guides/develop/application-design/forms/layout-management/abstract-form) **(No UI)**


# Simple Layout

This section of the guide covers the Simple (CSS Position) layout manager

## Overview

When creating a form, one must always select a layout type. **Simple** (CSS Position) is the easiest and most common way to arrange components on a form. It is the recommended approach for most projects.

## Quick Start

When creating a form, leave the default option for Simple (CSS Position) layout on the [New Form Wizard](/reference/servoy-developer/object-editors/new-form-wizard). Drag components onto the form, or set the [**cssPosition**](/reference/servoycore/dev-api/application/cssposition) property. See [examples](#examples) below.

## How it works

**Simple** or CSS Position layout is the default layout type for building forms. It controls the location and dimensions of the components on the form and the dynamic behavior of the components as the form size changes.

{% hint style="info" %}
Just to clarify, one does not need to know *anything* about CSS technology to use this layout type. The mechanism for laying out components is straightforward and can be learned in a few minutes.
{% endhint %}

### Form (min)sizes in the browser

A form has in its properties 4 values that are used to set or not set the minimum sizes (min-width and min-height) of the form when showing in a container (like tabpanel).

First the form has "minWidth" and "minHeight" properties that should be set, those are also the design size what you see in the Form Editor in the developer.

Those 2 properties are set at runtime also on the form based on the other 2 properties: useMinHeight and useMinWidth, those 2 properties can have 3 states: true,false and not\_set When it is true the min-width/height is set in the browser that could result in a tabpanel showing scrollbars because it tries to fit the form for that minimum size. If it is false then the min-xxx are not set, and the form size is as big as the viewport (the visible area). If the form has some components outside this viewport, the form will overflow and scrollbars will appear. The scrolling area will be exactly as big so it can fit exactly all the components.

The difference between true and false is that the size of the form is bigger when true because it has also marging to the right and bottom when you have designed marging there around the button that is placed in the bottom right corner. But also if you have button that is right, bottom alligned, see CSS Postion below, then the button is alligned to the min size of the form instead of the viewport that you see, but the button will still move down or to the right if it has more space.

|If the value is not\_set then it will fallback to a default, the standard default value is 'true', but this can be overwritten by setting a client property for 1 of both sizes:

```
application.putClientProperty(UICONSTANTS.DEFAULT_FORM_USE_MIN_HEIGHT,false);
```

### CSS Position

When using CSS Position, you will specify the [cssPosition](/reference/servoycore/dev-api/application/cssposition) property of every component that you place on the form. The position property contains six values to control location and behavior. They are expressed as a single string having the form: `top, right, bottom, left, min-width, min-height`. Each value can be expressed as an absolute [pixel](#pixel-values) value or a relative [percentage](#percentage-values) value. The property can also be set a [calculated](#calculated-values) (pixel & percentage) value.

<table><thead><tr><th width="142">Property</th><th>Description</th></tr></thead><tbody><tr><td><strong>Top</strong></td><td>The top edge of the component, expressed as a distance from the top of the form.</td></tr><tr><td><strong>Right</strong></td><td>The right edge of the component, expressed as a distance from the right of the form.</td></tr><tr><td><strong>Bottom</strong></td><td>The bottom edge of the component, expressed as a distance from the bottom of the form.</td></tr><tr><td><strong>Left</strong></td><td>The left edge of the component, expressed as a distance from the left of the form.</td></tr><tr><td><strong>Min-Width</strong></td><td>The width of the component</td></tr><tr><td><strong>Min-Height</strong></td><td>The height of the component</td></tr></tbody></table>

#### Pixel Values

You can use pixel values to dictate the *exact* location or dimension. This means that the value will not change, regardless of the form's changing size.

```json
// Example 10 pixels from top of form
top: 10     
```

#### Percentage values

You can use percentage values to specify the *relative* location or dimension. This means that the value will change, depending on the form's changing size.

```
// example 10% of the form's height from top of form
top: 10%
```

#### Calculated Values

You can combine percentages and pixel values to specify a calculated location or dimension. This is ideal for adding absolute gaps between relatively positioned components.

```
// example 50% of the form's height from top, plus additional 10 pixels
top: calc(50% + 10px)
```

#### Ignored Values

You can also choose to ignore a property. To do this, enter a value of `-1` to skip the property. Doing so will allow another property to have precedence. For example, suppose that you wanted to have a component placed 10 pixels from the left edge and always occupy 25% width of the form. In this case, you may choose to ignore one of the `right` location property.

```
// 10 px from left, 25% width
left: 10
right: -1
width: 25%
```

{% hint style="info" %}
**Conflicts**: Sometimes position values can be in conflict. In this case there is an order of precedence. **Location** values will always override their corresponding **dimension** values. For example, a component having both values for `left` and `right` will take precedence and the `width` value will be ignored (except to enforce the minimum)
{% endhint %}

### Dragging Components

When editing a Simple layout form, you can also drag to move and resize components inside the [Form Editor](/reference/servoy-developer/object-editors/form-editor). This will update the **cssPosition** property.

## Examples

Below are a few examples of simple layout arrangements. Try them out on your own components.

**Fully-Anchored, ignore dimensions**\
In this example, This component will always be 10 pixels from each edge of the form. It will grow and shrink with a changing form size, but it will never move. (width and height are ignored)

```
cssPosition: 10,10,10,10,-1,-1
```

<div align="left" data-full-width="false"><figure><img src="/files/rWSNgnWAxiOumE5pLLYa" alt="" width="375"><figcaption></figcaption></figure></div>

**Anchored top-left, fixed dimensions**\
In this example, the component will maintain a fixed position on its top-left corner and it will maintain a fixed size. It will not grow, shrink or move.

```
cssPosition: 10,-1,-1,10,400,200
```

<div align="left"><figure><img src="/files/tsDfREB0wwYS5wjDE0A6" alt="" width="375"><figcaption></figcaption></figure></div>

**Anchored top, bottom & left, relative width**\
In this example, the component is anchored to the left and it will grow and shrink vertically. It will also grow and shrink horizontally, relative to the width of the form. (height is ignored)

```
cssPosition: 10,-1,10,10,50%,-1
```

<div align="left"><figure><img src="/files/ei28JfpaxAjnLewHUhgU" alt="" width="375"><figcaption></figcaption></figure></div>

**Anchored top, bottom & left, calculated right**\
This example shows two components which occupy two columns and leave a 10px gap. Their respective `right` and `left` values use a calculated value (50% of the form width, plus an extra 10px). This is ideal to create a gap between components

```
cssPosition: 10,calc(50% + 10px),10,10,-1,-1
cssPosition: 10,10,10,calc(50% + 10px),-1,-1
```

<div align="left"><figure><img src="/files/DVRD4jK63KoQ2CzuYXJ8" alt="" width="375"><figcaption></figcaption></figure></div>


# Fully Responsive

## Fully Responsive

## Overview

When creating a form, one must always select a layout type. **Advanced** (Responsive) is the most complex layout manager, but allows developer the greatest flexibility to dictate how components and containers respond to different form sizes.

## How it works

**Advanced** (Responsive) is the most complex layout manager, differently from the [Simple CSS](/guides/develop/application-design/forms/layout-management/css-position), you don't define the exact location and the size in pixels with simple drag and drop; instead you will create a layout stucture with Layout Containers nesting components into them. Location and dimension of the components, as well how it responds to changes of the Browser size, is determined by the structure you create with Layout Containers, the custom style you may apply and for certain components by the actual content of the components; for instance a label containing a long text can overflow to the next line instead of having the text cutted.

{% hint style="info" %}
**Advanced (Responsive) vs** [**Simple CSS**](/guides/develop/application-design/forms/layout-management/css-position) In most cases it is recommended to use [Simple CSS](/guides/develop/application-design/forms/layout-management/css-position), but Advanced (Responsive) is purposed for specific situations:

* for applications that need to show/hide components at different scales
* for applications where the layout should respond to the internal content, etc.
  {% endhint %}

## [Bootstrap 12-Grid Layout](/guides/develop/application-design/forms/layout-management/home/b12grid#bootstrap-12-grid-layout)

* [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container)
* [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
* [Column](/guides/develop/application-design/forms/layout-management/home/b12grid#column)

## [Bootstrap 12-Grid Layout Templates](/guides/develop/application-design/forms/layout-management/home/b12grid#bootstrap-12-grid-layout-templates)

* [Row-With-Column](/guides/develop/application-design/forms/layout-management/home/b12grid#row-with-column)
* [Label-And-Field](/guides/develop/application-design/forms/layout-management/home/b12grid#label-and-field)
* [Responsive-Form-Template](/guides/develop/application-design/forms/layout-management/home/b12grid#responsive-form-template)

## [Flexbox](/guides/develop/application-design/forms/layout-management/home/flexbox#flexbox)

* [Flex-Container](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-container)
* [Flex-Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item)
* [Flexbox Layout](/guides/develop/application-design/forms/layout-management/home/flexbox#flexbox-layout)

## Other Layout Containers

On addition to the Bootstrap Grid system there are several Layout Containers which can be combined to build a complex responsive form:

* [Custom Div](/guides/develop/application-design/forms/layout-management/home/custom-div#custom-div)
* [Collapsible Container](/guides/develop/application-design/forms/layout-management/home/collapsible-container#collapsible-container)
* [Simple Collapsible](/guides/develop/application-design/forms/layout-management/home/simple-collapsible#simple-collapsible)
* [Center Container](/guides/develop/application-design/forms/layout-management/home/center-container#center-container)
* [Inline Group Container](/guides/develop/application-design/forms/layout-management/home/inline-group-container#inline-group-container)

## Mixing Simple CSS and responsive forms

Here is the webinar section that covers mixing Simple CSS and Responsive forms:

{% embed url="<https://www.youtube.com/watch?t=285s&v=_Ivr95tjR9w>" %}
Webinar
{% endembed %}

### CSS Position Container

The CSS Position Container is a special container which can be used to create as a [Simple CSS](/guides/develop/application-design/forms/layout-management/css-position) a block of the Advanced (Responsive) Form offering a great flexibility for the design of your form.

To edit the content of the CSS Position Container is requested to use [Form Editor](/reference/servoy-developer/object-editors/form-editor) Zoom mode which strips out from the editor any outer layout container and allows you to work only with the Zoomed section; as soon you drop a CSS Position Container into the Form you are requested to Zoom in for editing; you can Zoom out any moment using the Zoom Out icon and come back to edit the content of the CSS Position Container using the Zoom In icon.

You can place any component into the CSS Position Container as if is a [Simple CSS Form](/guides/develop/application-design/forms/layout-management/css-position), therefore using same rules; the location of the elements in it will be relative to the CSS Position Container block.

Set the size property **width** and **height** to control the height and the minimum width of the CSS Position container.

**Constraints** : can be edited only when Zoom in [Form Editor](/reference/servoy-developer/object-editors/form-editor), the contained elements cannot be moved into a different container.

![Simple CSS](/files/bqCrqRQm5aY2IamboG5J)

Webinar section for CSS Position Container:

{% embed url="<https://www.youtube.com/watch?t=620s&v=_Ivr95tjR9w>" %}
Webinar
{% endembed %}

#### Create a CSS Position Container

<div align="left"><figure><img src="/files/tPCEVdphrDAYWek3wfwD" alt=""><figcaption><p>Create a CSS Position Container</p></figcaption></figure></div>

These are the steps for creating a CSS Position Container:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **CSS Position Container** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **CSS Position Container** component inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Click on the "Yes" button of the pop-up that appears after adding the **CSS Position Container**, in order to get into Zoom mode and be able to edit the content of the component
5. While in Zoom mode you can add and edit other needed components available for [Simple CSS](/guides/develop/application-design/forms/layout-management/css-position) forms

## Nesting responsive forms

In responsive layouts, when you nest multiple forms using tab panels or other types of container-components it may happen that a tab/child form that has in it directly "*row*" layout containers (so no root layout "*container*" or layout "*container-fluid*") shows unwanted scroll-bars. That happens because bootstrap requires that all '*row*' divs must either be put in a '*container*', a '*container-fluid*' or in a '*column*', while in the case of a tabpanel for example the parent DOM Element is just some intermediate div. Because '*row*' has negative margins of -15px and parent intermediate div might not have padding of 15px, the scrollbars can appear (if that div has overflow: auto). For example:

```javascript
 container  
     row  
          column  
               div style="overflow: auto" // the intermediate div of container-component  
                   row // results in a scrollbar because of margin -15px  
                       columns  
```

The problem does not appear when a '*row*' is inside a '*column*', a '*container*' or a '*container fluid*' - because those have a padding of 15px defined. However, bootstrap doesn't allow nesting of containers in it's layout docs - so adding a container layout as root of child/contained form is not an option. But as the tabpanel might want to contain absolute forms as well (for example), that intermediate div cannot always set a 15px padding - as that might not be necessary... So we just need to change the margins of such rows as in the rule below (that is included already in "*standard\_ngclient.css*"):

```css
div:not(.container):not(.container-fluid):not([class^="col-xs-"]):not([class^="col-sm-"]):not([class^="col-md-"]):not([class^="col-lg-"])
 > .row {
    margin-right: 0;
    margin-left: 0;
}
```


# Bootstrap 12-Grid

## Bootstrap 12-Grid Layout

### Overview

This is the bootstrap 12 grid layout package for making [**responsive forms**](/guides/develop/application-design/forms/layout-management/abstract-form). It is meant to work with the bootstrap components package or any other compatible component packages. You can build a responsive layout for your form using this combination or components and layouts. 12grid is based on bootstrap grid system, see <https://getbootstrap.com/docs/5.0/layout/grid/> for more details.

See below the Layout Containers which can be found within the Bootstrap 12-Grid Layout package:

### Container

Container, based on the Bootstrap [Container](https://getbootstrap.com/docs/5.0/layout/containers) is used to contain, pad, and (sometimes) center the content within them. While containers can be nested, most layouts do not require a nested container.

**Constraints** : A Container can be dropped only at the root of the form layout and can contain **only** [Row](#row), therefore you will be allowed to drag & drop into it **only** [Row](#row) layout or templates starting with rows (e.g. Row and 1 Column, Label and Field...).

![Container](/files/8vITbmT5bUV5zNqOqHeW)

#### Create a Container

<div align="left"><figure><img src="/files/wbvoX0vd9z6lbbRgUVnE" alt=""><figcaption><p>Create a Container</p></figcaption></figure></div>

These are the steps for creating a Container:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your [**responsive form**](/guides/develop/application-design/forms/layout-management/abstract-form)
2. Find **Container** in *Bootstrap 12-Grid* section of the components' pallet
3. Drag and drop the **Container** component in the form
4. Add at least one [Row](#row) component

### Row

Rows are wrappers for columns. Each column has horizontal padding (called a gutter) for controlling the space between them. This padding is then counteracted on the rows with negative margins to ensure the content in your columns is visually aligned down the left side. Rows also support modifier classes to uniformly apply column sizing and gutter classes to change the spacing of your content.

**Constraints** : A row can contain **only** [Column](#column) containers.

![Row](/files/isF81x5nPH9YipH8LI3g)

#### Create a Row

<div align="left"><figure><img src="/files/RvM9nYFt6IC0pIbxOUVq" alt=""><figcaption><p>Create a Row</p></figcaption></figure></div>

These are the steps for creating a Row:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your [**responsive form**](/guides/develop/application-design/forms/layout-management/abstract-form)
2. Find **Row** in *Bootstrap 12-Grid* section of the components' pallet
3. Drag and drop the **Row** component in:
   * empty space of the form, as an independent component
   * inside a [Container](#container) component
   * inside a [Column](#column) component
4. Add at least one [Column](#column) component

### Column

Columns are at the core of the 12 Grid Layout system. Nested within [Row](#row) containers, they can divide the parent row's width to up 12 blocks of same relative size, allowing you to create different combinations of elements that span any number of columns. Column classes indicate the number of template columns to span (e.g., col-4 spans four). widths are set in percentages so you always have the same relative sizing.

**Constraints** : A column can contain any component and any layout containers **except** for [Container](#container), [Column](#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item).

![Column](/files/pmmTIl065FaDz723DVa6)

Can nest rows into a column to further organize the layout:

![Column Nested](/files/oRk0vxSWHxIVg30NyVrm)

#### Create a Column

<div align="left"><figure><img src="/files/lbB86DtPvTAOGRG1y73U" alt=""><figcaption><p>Create a Column</p></figcaption></figure></div>

These are the steps for creating a Column:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Column** in *Bootstrap 12-Grid* section of the components' pallet
3. Drag and drop the **Column** component in a [Row](#row) component
4. Add other needed components inside the **Column**, **except** for [Container](#container), [Column](#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item)

***

## Bootstrap 12-Grid Layout Templates

The following are ready to use layout templates based on the 12 Grid Layout.

### Row-With-Column

A quick start for a 12 Grid layout. These 3 templates *Row with 1 Column*, *Row with 2 Columns*, *Row with 3 Columns* are row layout containing already 1, 2 or 3 equally sized columns.

![Row With Column](/files/Qsa6iVm8kmXSQYHqGT7a)

#### Create a Row-With-Column

<div align="left"><figure><img src="/files/6UjM4PFh0Tw4T0ZiOgv8" alt=""><figcaption><p>Create a Row-With-Column</p></figcaption></figure></div>

These are the steps for creating a Row-With-Column:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Row with 1 Column** / **Row with 2 Columns** / **Row with 3 Columns** in the *Bootstrap 12-Grid* section of the components' pallet
3. Drag and drop the component in:
   * empty space of the form, as an independent component
   * inside a [Container](#container) component
   * inside a [Column](#column) component
4. Add other needed components inside the **Column**, **except** for [Container](#container), [Column](#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item), even other columns inside the row, if needed

### Label-And-Field

A predefined template which comes with a row and 2 columns ( md-4 and md-8 ) having a [Label](/guides/develop/application-design/ui-components/buttons-and-text/label) component in the first column and a [Textbox](/guides/develop/application-design/ui-components/input-controls/textbox) component in the second column.

![Label And Field](/files/E32EayPFbrL1kqQFfG3L)

#### Create a Label-And-Field

<div align="left"><figure><img src="/files/jycmX4wEgdXN7FzZ8TF5" alt=""><figcaption><p>Create a Label-And-Field</p></figcaption></figure></div>

These are the steps for creating a Label-And-Field:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Label-And-Field** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Label-And-Field** component in:
   * empty space of the form, as an independent component
   * inside a [Container](#container) component
   * inside a [Column](#column) component
4. Edit the [Label](/guides/develop/application-design/ui-components/buttons-and-text/label) component in the first column and the [Textbox](/guides/develop/application-design/ui-components/input-controls/textbox) component in the second column, or even add other components if needed

### Responsive-Form-Template

A predefined layout of nested rows and columns; you can further edit it by adding or removing other layout containers.

![Responsive Template](/files/NOpwGsy4P8sDwOAXPhWd)

#### Create a Responsive-Form-Template

<div align="left"><figure><img src="/files/A1tzmFFn1KkP7An6xMZg" alt=""><figcaption><p>Create a Responsive-Form-Template</p></figcaption></figure></div>

These are the steps for creating a Responsive-Form-Template:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Responsive-Form-Template** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Responsive-Form-Template** component into an empty space of the form, as an independent component
4. Edit the [Columns](#column) and [Rows](#row); you can also add or remove components inside


# Flexbox

## Overview

The Flexbox layout containers are using the CSS3 [Flexbox layout](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) model; Flexbox is a one-dimensional layout method for arranging items in either rows or columns.\
The Flexbox layout involves a container ([Flex Container](#flex-container)) and one or more children ([Flex Item](#flex-item)). There are several properties which can be set in either the parent [Flex Container](#flex-container) or the [Flex Item](#flex-item) children using the [Servoy properties](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/forms/layout-management/fully-responsive/broken-reference/README.md) view in the IDE.

## Flex-Container

It is the parent container of the [Flexbox layout](#flexbox-layout). It comes already with 3 [Flex Item](#flex-item) children; you can further add or remove any [Flex Item](#flex-item).

You can modify the layout using it's 3 unique properties:

* **data-direction**: determines if the flex items in it should be arranged as rows or columns.
* **data-align-items**: determines how the flex items are laid along the flex container.
* **data-justify-content**: determines how the available space should be distributed among the flex items.

**Constraints** : Can contain only [Flex Item](#flex-item).

![Flex Container](/files/vX1rZO6CCI4cIMW1l6pJ)

Below an example of flex container with data-justify-content set to space-around.

![Flex Justify Spec](/files/AS5E7JBWFfyIveCljH0H)

![Flex Justify](/files/Pb2w9YKRLwOMO7pIjrj8)

### Create a Flex-Container

<div align="left"><figure><img src="/files/qFQwQ4izZRvW9gq0h7hR" alt=""><figcaption><p>Create a Flex Container</p></figcaption></figure></div>

These are the steps for creating a Flex Container:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Flex Container** in *Flex CSS* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Flex Container** component in:
   * empty space of the form, as an independent component
   * inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Edit the existing [Flex Items](#flex-item); you can further add or remove any [Flex Item](#flex-item)

## Flex-Item

Flex items can be dropped into [flex containers](#flex-container). As the flex containers, each flex item has its own set of unique properties used to determine how the item is layout within its container.

* **data-align-items**: determines how the flex items are laid along the flex container.
* **data-grow**: determines the ability of the item to grow, relatively to other flex items, when there is more space available.
* **data-shrink**: determines the ability of the item to shrink, relatively to other flex items, when necessary.

In the example below the first item from the left doesn't grow since has `flex-grow=0`. The middle item has `flex-grow=1`, the last item has the `flex-grow=2` therefore grows twice as much of the middle flex item.

![Flex Item Grow](/files/jVgLz5fmDa5uPsTMhaV1)

![Flex Item Spec](/files/GOAHfXbebyETBs5kJ3DO)

### Create a Flex-Item

<div align="left"><figure><img src="/files/IF7p3aRqyze1UxEBlRMu" alt=""><figcaption><p>Create a Flex Item</p></figcaption></figure></div>

These are the steps for creating a Flex Item:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Flex Item** in *Flex CSS* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Flex Item** component in:
   * empty space of the form, as an independent component
   * inside a [Flex Container](#flex-container)
4. Edit the **Flex Item** and add other needed components inside

## Flexbox Layout

## Overview

The flexbox layout divides the available height in 3 vertical sections, **header**, **content** and **footer**. The **header** and the **footer** section will grow in height depending on their content while the **content** section will take all the remaining height and show a scrollbar if the content doesn't fit.

{% hint style="info" %}
**IMPORTANT!** The Flexbox layout is using the CSS3 Flexbox layout model. Now days the Flexbox model is largely supported from modern browsers (see [supported browsers](https://caniuse.com/#feat=flexbox)). However there are few known issues with IE and Safari (open the [Known issues](https://caniuse.com/#feat=flexbox) tab).
{% endhint %}

![Flexbobx Layout](/files/fIJypPxpp3nUQmrLC9o1)

## Getting Started

You can drop Servoy any Servoy Web Components and nest other 12Grid containers into the **header**, **footer** and **content** section.

You may decide to leave empty the **header** or **footer** section, not necessarily you need to use these section; however you may use at least one of these 2 sections; otherwise you may not use this container at all since there is no benefit on using only the **content** section.

{% hint style="info" %}
**IMPORTANT!** The parent container of the flexbox layout MUST have a known height, the flexbox layout is not useful at all if the height of it's top container is 'auto' (which is an unknown value). In case the parent container of the flexbox layout is the Servoy form itself, add a CSS styleClass to the form which will let the form use 100% of the available height.
{% endhint %}

{% hint style="info" %}
**IMPORTANT!** if the form is nested within another form via a tab/tabless panel, the panel MUST have a known height as well, so that the inner form can use 100% of the panel height.
{% endhint %}

![Flexbobx Layout](/files/fIJypPxpp3nUQmrLC9o1)

![Flexbox Layout Outline](/files/5N6TeGS0ohFoDlLUuUj8)

## Create a Flex Layout

<div align="left"><figure><img src="/files/vcEDOWQKDp0jKEgzEXU5" alt=""><figcaption><p>Create a Flex Layout</p></figcaption></figure></div>

These are the steps for creating a Flex Layout:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Flex Layout** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Flex Layout** component in:
   * empty space of the form, as an independent component
   * inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Edit the **header**, **footer** and **content** sections of the **Flex Layout** and add other needed components inside

### Flexbox Layout and Table Components

When a Servoy Table Component from the [Bootstrap components](https://github.com/Servoy/bootstrapcomponents) package or from the [Servoy Extra Components](/guides/develop/application-design/data-modeling/databases/tables) package or from the Servoy NG Grids package is placed within the content section of the flexbox layout as direct child, the table height will use 100% of the available height if the `responsiveHeight` property is set to `0`.

**NOTE** for the [Table](/guides/develop/application-design/data-modeling/databases/tables) component from the Servoy Extra package the property `responsiveDynamicHeight`, should be set to `false` if you wish to use all the available height of the content section; if the `responsiveDynamicHeight` is set to `true` the [Table](/guides/develop/application-design/data-modeling/databases/tables) will have a max-height equal to the design `responsiveHeight` property of the Table; the max-height may be smaller than the available height resulting in unused space.

If instead you prefer to use the design height of the [Table](/guides/develop/application-design/data-modeling/databases/tables) component, wrap the [Table](/guides/develop/application-design/data-modeling/databases/tables) component within a different 12Grid container. However letting the table use a different height than the available height in the content section may result in bad UX for the User since may result in double vertical scrollbars.

### Nesting Flexbox Layout

You can nest multiple FlexLayout within the **content** section to sub-divide the available height of the content section.

![FlexBox Layout Nested](/files/8UQ4sJ08fOhV2d6uzFzf)

![FlexBox Layout Nested Outline](/files/Wzy8gi4V3ClmQrhTBa6z)

In the sample above the available height of the first flexbox layout content is divided in 2 blocks of 50% height using the custom styleClass `half-size`.

```css
.half-size {
	height: 50%;
}
```

### Flexbox Layout and tab/tablesspanel

If you include a [tab panel](/guides/develop/application-design/forms/form-containers/tab-panel) or tabless panel into the **content** section and you would like to let the panel use all the available height of the content section add a CSS styleClass to the [tab panel](/guides/develop/application-design/forms/form-containers/tab-panel) or tabless panel component to let the panel use 100% of the height.


# Custom Div

## Overview

A simple div, is the simplest Layout Container; can be used to divide the space in multiple blocks without additional rules.

![Custom Div](/files/7ISf1brJOhPUzBjlj3xD)

## Getting Started

### Create a Custom Div

<div align="left"><figure><img src="/files/tPCEVdphrDAYWek3wfwD" alt=""><figcaption><p>Create a Custom Div</p></figcaption></figure></div>

These are the steps for creating a Custom Div:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Custom Div** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Custom Div** component in:
   * empty space of the form, as an independent component
   * inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Add other needed components inside the **Custom Div**, **except** for [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Column](/guides/develop/application-design/forms/layout-management/home/b12grid#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item)


# Collapsible Container

## Overview

The **Collapsible Container** is a responsive container, to be used in a **Servoy Responsive Form**, which behaves as a toggle on small screen sizes. When the size of the screen is smaller than 992px it presents a toggle section on which the user can click to toggle the visibility of its content. On medium and large screens instead it always displays its content and hides its toggle section.

![Collapsible Container](/files/xsPcoAARePP93eG800W2)

**Note**: layout containers are not stateful, therefore the Collapsible Container will always return to its design state when the user navigates away from the form or the browser is refreshed.

## Getting Started

You can drop Servoy Web Components and nest other 12Grid containers into both toggle and container sections.

The Collapsible Container uses attributes of its inner *div* containers to achieve the collapsible behavior. To obtain the collapsible behavior the `data-target` attribute of the `collapsible-toggle` must target the correspondent `collapsible-container` via CSS selector.

![Collapsible Container Outline](/files/yhc6rVJbQGw9N2vPaDJz)

It is recommended to edit the default value and set an unique `id` attribute in the `collapsible-container`; adjust accordingly the `data-target` of the `collapsible-toggle`.

## Create a Collapsible Container

<div align="left"><figure><img src="/files/wVy2BYQ6y1SVtbzvw9S5" alt=""><figcaption><p>Create a Collapsible Container</p></figcaption></figure></div>

These are the steps for creating a Collapsible Container:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Collapsible Container** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Collapsible Container** component in:
   * empty space of the form, as an independent component
   * inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Add other needed components inside the **Collapsible Container**, **except** for [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Column](/guides/develop/application-design/forms/layout-management/home/b12grid#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item)

## Change default toggle to expanded

The collapsible container is collapsed by default on small screens; you can modify the classes of its sections to change the default state to be expanded.

![Expanded](/files/bGTl1vpwRE23rMT4PJkb)

Add the class `show` for Titanium Client / `in` for NGCLient to the div having the `collapsible-container` class property to expand the content by default and remove the class `collapsed` from the div having `collapsible-toggle` class property.

![Expanded Collapsible Container Outline](/files/b4xAbh4NLTsJsYNRwUU9)

## Customize the toggle icon.

You can decide to remove the icon in the toggle section and place any component of your choice to be used as icon.


# Simple Collapsible

## Overview

The **Simple Collapsible container** allows to toggle the visibility of its content in a **Servoy Responsive Form**. It has a toggle section and a content section; the toggle section is always visible and toggles the visibility of the content section when the user clicks on it.

![Simple Collapsible](/files/2YV2047F21UUQwELB5B9)

**Note**: layout containers are not stateful, therefore the Simple Collapsible will always return to its design state when the user navigates away from the form or the browser is refreshed.

## Getting Started

You can drop Servoy Web Components and nest other 12Grid containers into both toggle and content section.

The Simple Collapsible uses attributes of its inner `div` containers to achieve the collapsible behavior. To obtain the collapsible behavior the `data-target` attribute of the `simple-collapsible-toggle` must target the correspondent `simple-collapsible-content` via CSS selector.

![Simple Collapsible Outline](/files/KE0OM4G8rn87SJ63q7zQ)

It is recommended to edit the default value and set an unique `id` attribute in the `simple-collapsible-content`; adjust accordingly the `data-target` of the `simple-collapsible-toggle`.

## Create a Simple Collapsible

<div align="left"><figure><img src="/files/ZuzOe1GFz7hmR1s7qObv" alt=""><figcaption><p>Create a Simple Collapsible</p></figcaption></figure></div>

These are the steps for creating a Simple Collapsible:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Simple Collapsible** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Simple Collapsible** component in:
   * empty space of the form, as an independent component
   * inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Add other needed components inside the **Simple Collapsible**, **except** for [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Column](/guides/develop/application-design/forms/layout-management/home/b12grid#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item)

## Change default toggle to collapsed

The collapsible container is expanded by default; you can modify the classes of its sections to change the default state to collapsed.

![Collapsed](/files/ZqGSxtZWS4gAZRF3NSfR)

Remove the classes `in` and `show` from the `simple-collapsible-content` class property to collapse the content by default and add the class `collapsed` in the `simple-collapsible-toggle` class property.

![Collapsed Simple Container](/files/Cm4GLEaYWGRRCANw6E19)

## Customize the toggle icon.

You can decide to remove the icon in the toggle section and place any component of your choice to be used as icon.

You can also change the default icon in the styleSheet of your solution using CSS3.

```css
.simple-collapsible-toggle > .simple-collapsible-icon {
	font-family: "Glyphicons Halflings";
	display: inline-block;
}
.simple-collapsible-toggle > .simple-collapsible-icon:before {
	content: "\e113"; /* GlyphIcon chevron down when expanded */
}
.simple-collapsible-toggle.collapsed > .simple-collapsible-icon:before {
	content: "\e114"; /* GlyphIcon chevron up when collapsed */
}
```


# Center Container

## Overview

The **Center Container** allows its content vertically and horizontally in a **Servoy Responsive Form**.

You can drop Servoy Web Components and nest other 12Grid containers into its content section. You can also nest center container within each other.

![Center Container Vertically](/files/HstaAWZzmKjXocPiF9Gx)

![Center Container Vertically Outline](/files/dUb7XiCwK3msBF8HZr5H)

To center the content vertically the parent container must have a known height; if the height of it's parent container is not known the container will center it's content only horizontally.

Note that 12Grid rows and columns usually don't have a known height (unless their height is set in the styleSheet), therefore the center container contained in a 12Grid column will center its content vertically.

![Center Container](/files/pnFZSK380tb58TRvxJhL)

![Center Container Outline](/files/ce21ZXamMh49andGgl3r)

## Getting Started

## Create a Center Container

<div align="left"><figure><img src="/files/Ho6wejO0ae1pyAGmjy2Y" alt=""><figcaption><p>Create a Center Container</p></figcaption></figure></div>

These are the steps for creating a Center Container :

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Center Container** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Center Container** component in:
   * empty space of the form, as an independent component
   * inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Add other needed components inside the **Center Container**, **except** for [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Column](/guides/develop/application-design/forms/layout-management/home/b12grid#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item)

## Center multiple elements

You can drop Servoy Web Components and nest other 12Grid containers into its content section to center multiple elements as a single block. You can also nest multiple center containers to center sub-content within the content section; note that as for the 12Grid rows, sub-content of the center container are centered only horizontally by default (unless you define a known height or min-height to the sub center container via CSS); this is the case since the content of the top-level center container doesn't have a known height but it is 'auto' calculated depending on its content.

![Multiple Center Content](/files/DC3MiO1gDcyCx4atrAo9)

![Multiple Center Content Outline](/files/jAUyRRIcg5urgN8V9TYY)

## Width and Height of the center content

The center content section doesn't have a known height and width but its height and width are set to '*auto*'; this means that the content section will grow as much it needs (depending on its content) and not more.

Since the content section height and width are *auto*, a container or a web component which has width or height equal to 100%, will also fallback into width and height equal to *auto*. For example a textbox component having a *form-control* class, which usually takes 100% of the width, won't grow to the whole available width instead will use its default width (which has different value depending on browser version and OS system).

### Min Width

You can set a min-width to the content section (using CSS classes) to stretch its content to a minimum dimension; inner containers and components having width equal to 100% will grow up to at least the min-width of the content section.

![Center Content Min Width](/files/3QjIBCdb0f9235avMRdU)

![Center Content Min Width Outline](/files/BMIhblfwFXJPzXol5i8D)

![Center Content Min Width Style Class](/files/cJwvnqppuVcNjPItonOF)


# Inline Group Container

## Overview

The **Inline Group Container** allow syou to use at best the available width dividing the available width in 3 horizontal section, **left**, **right** and **content**; the left and the right section will use all and only the necessary width depending on their content (if any); the **content** section instead will use all the remaining width.

![Inline Group Container](/files/Vjhgr7EIUKvOV54krPis)

## Getting Started

You can drop Servoy any Servoy Web Components and nest other 12Grid containers into the **left**, **right** and **content** section.

You may decide to leave empty the **right** or **left** section, not necessarily you need to use these section; however you may use at least one of these 2 sections; otherwise you may not use this container at all since there is no benefit on using only the **content** section.

{% hint style="info" %}
**IMPORTANT!** The parent container of the inline group container MUST have a known width, the inline group container is not useful at all if the width of its top container is `auto` (which is an unknown value).
{% endhint %}

![Inline Group Container Outline](/files/j1jmGWjg70XThNC3U9T0)

## Create an Inline Group Container

<div align="left"><figure><img src="/files/Ho6wejO0ae1pyAGmjy2Y" alt=""><figcaption><p>Create an Inline Group Container</p></figcaption></figure></div>

These are the steps for creating an Inline Group Container :

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of your **responsive form**
2. Find **Inline Group Container** in *Templates* subsection of the *Bootstrap 12-Grid* section in the components' pallet
3. Drag and drop the **Inline Group Container** component in:
   * empty space of the form, as an independent component
   * inside any other container components, **except** [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Row](/guides/develop/application-design/forms/layout-management/home/b12grid#row)
4. Add other needed components inside the **left**, **right** and **content** sections of **Inline Group Container**, **except** for [Container](/guides/develop/application-design/forms/layout-management/home/b12grid#container), [Column](/guides/develop/application-design/forms/layout-management/home/b12grid#column) or [Flex Item](/guides/develop/application-design/forms/layout-management/home/flexbox#flex-item)

## Fixed Left/Right Section Size

You may force the **left** and or **right** section to a fixed width by setting the respectively the `data-leftsize` and `data-rightsize` attribute of the inline group container to one of the pre-defined values `xs`, `sm`, `md`, `lg`.

Setting a fixed size to a section is particularly useful when you want to align multiple label and fields using multiple inline group containers.

![Fixed Section width](/files/mdyMiQwe0llcGR6Advm2)

![Fixed Section width Outline](/files/uZCN4bJonV3YbcdpAnZM)

You can override the default sizes of the pre-defined values by adding the following CSS rules to the CSS styleSheet of your Solution.

```css
 /* Inline Group Sizes */
.inline-group[data-leftsize="xs"] > .inline-group-left,
.inline-group[data-rightsize="xs"] > .inline-group-right {
 	width: 40px;
}
 
.inline-group[data-leftsize="sm"] > .inline-group-left,
.inline-group[data-rightsize="sm"] > .inline-group-right {
 	width: 80px;
}
 
.inline-group[data-leftsize="md"] > .inline-group-left,
.inline-group[data-rightsize="md"] > .inline-group-right {
 	width: 120px;
}
 
.inline-group[data-leftsize="lg"] > .inline-group-left,
.inline-group[data-rightsize="lg"] > .inline-group-right {
 	width: 160px;
}
```

You can of course decide also to add your own CSS class to set a specific width to the section instead of using the pre-defined sizes.

## Responsive Section

You can enable a responsive behavior for the **left** section using the attribute `data-responsive` of the inline-group-container. You can select a breakpoint value (`sm`, `md`, `lg`) for which the left section will move into a new line when the screen size is smaller than the breakpoint value; see the [Bootstrap CSS Media Query](https://getbootstrap.com/docs/3.0/css/#grid-media-queries) for the breakpoint values.

![Responsive Section](/files/zo7svLj3ms0cdDAaOAF0)

![Responsive Section Outline](/files/cFjtu1G6KPapopplWLHK)

## Nesting Inline Group Containers

You can nest multiple inline group container within the content section to sub-divide the available width of the content section.


# Abstract Form

## Overview

When creating a form, one must always select a layout type. An **Abstract** (No UI) layout can be used to create a base form, from which other forms can inherit. The benefit of having a base form be Abstract, is to allow child forms to implement any UI, while still inheriting the properties and event bindings, as well as logic from the Abstract parent.

## Quick Start

When creating a form, select the form type option **Abstract** (No UI) in the [New Form Wizard](/reference/servoy-developer/object-editors/new-form-wizard). Then you may set form properties and event handlers, as well as implement logic to be inherited as you please.

{% hint style="info" %}
For more information on creating an Abstract Base Form see the guide on [**Form Inheritance**](/guides/develop/application-design/forms/form-inheritance).
{% endhint %}


# Form Containers

## Overview

Form Containers allow you to insert one or more form(s) into a form. This is a common practice when a form needs to be displayed in several places, it also facilitates using relations between the main and contained form when related data needs to be shown.\
Containers can be added to a form using the Place Elements Wizards toolbar, the Palette, or the Solution Explorer.

## Types of Form Containers:

[Form](/reference/servoycore/object-model/solution/form#form) containers:

* [Form Container](/guides/develop/application-design/forms/form-containers/form-container#form-container)
* [Tab Panel](/guides/develop/application-design/forms/form-containers/tab-panel#tab-panel)
* [Split Pane](/guides/develop/application-design/forms/form-containers/split-pane#split-pane)
* [Collapse](/guides/develop/application-design/forms/form-containers/collapse#collapse)
* [Accordion Panel](/guides/develop/application-design/forms/form-containers/accordion-panel#accordion-panel)

[Form Component](/reference/servoycore/object-model/solution/form-component#extendsform) containers:

* [Form Component Container](/guides/develop/application-design/forms/form-containers/form-component#form-component)
* [List Form Component Container](/guides/develop/application-design/forms/form-containers/list-form-component#list-form-component)


# Form Container

## Overview

The "Form container" component is a container that shows 1 form inside it. It has no additional UI decorations.\
The contained form can optionally show related data.

It is suited for use in both Advanced (Responsive) and Simple CSS forms.

## Get Started

### Creating a Form Container

<div align="left"><figure><img src="/files/bDRZzDRvoDc4umTwPP8M" alt=""><figcaption><p>Create a Form Container</p></figcaption></figure></div>

Here are the steps for creating a Form Container:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Form Container**
2. Find **Form Container** in *Form Containers* section in the components' pallet
3. Drag and drop the **Form Container** component in the desired place of the form
4. Select the [`containedForm`](/reference/servoyextensions/ui-components/form-containers/form-container#containedform) property, where you set the name of the form you want to be displayed in the container
5. Optionally, you can [use a relation](#using-a-relation) by selecting the [`relationName`](/reference/servoyextensions/ui-components/form-containers/form-container#relationname) property, where you set the [relation](/guides/develop/application-design/data-modeling/relations) between the main form and the contained form
6. Edit other [**Form Container** properties](/reference/servoyextensions/ui-components/form-containers/form-container#properties) if needed

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

<img src="/files/IovS6xv0PJKUUgYL1M1z" alt="Form Container name" data-size="original">
{% endhint %}

### Using a relation

The contained form 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#datasource) property on the main form
2. Set the [`datasource`](/reference/servoycore/object-model/solution/form#datasource) property on the contained form
3. Make sure that the [relation](/guides/develop/application-design/data-modeling/relations) 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/form-container#relationname) property of the Form Container

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.

## Scripting a Form Container

[**Form Container** properties](/reference/servoyextensions/ui-components/form-containers/form-container#properties) can be also set in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor).

### Setting the Contained Form

Here is an example of how to programmatically set the contained form, including relationName, in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form:

```javascript
/**
 * Callback method when form is (re)loaded.
 *
 * @param {JSEvent} event the event that triggered the action
 *
 * @properties={typeid:24,uuid:"5C166B77-060A-4E85-AD9F-EB20B194E55F"}
 */
function onLoad(event) {
	// TODO Auto-generated method stub
    // fc_order_details = the name of the form container in the main form
    // order_details = the contained form
    // orders_to_order_details = relation between datasource table of the main form to datasource table of the contained form
	elements.fc_order_details.containedForm = forms.order_details;
	elements.fc_order_details.relationName = orders_to_order_details;
}
```

Other [**Form Container** properties](/reference/servoyextensions/ui-components/form-containers/form-container#properties) can be set the same way, by using `elements.FormContainerName.FormContainerPropertyName`.


# 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) 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#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#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#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#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#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#containedform): the form shown in the tab
   2. [`disabled`](/reference/servoyextensions/ui-components/form-containers/tabpanel#disabled): whether that tab is enabled or not
   3. [`hideCloseIcon`](/reference/servoyextensions/ui-components/form-containers/tabpanel#hidecloseicon): whether a close icon is shown or not (only applicable when [`showTabCloseIcon`](/reference/servoyextensions/ui-components/form-containers/tabpanel#showtabcloseicon) is set to `true`)
   4. [`iconStyleClass`](/reference/servoyextensions/ui-components/form-containers/tabpanel#closeiconstyleclass): style class for the tab's icon
   5. [`imageMedia`](/reference/servoyextensions/ui-components/form-containers/tabpanel#imagemediaid): image to be drawn in tab header
   6. [`name`](/reference/servoyextensions/ui-components/form-containers/tabpanel#name): a name for this tab
   7. [`relationName`](/reference/servoyextensions/ui-components/form-containers/tabpanel#relationname): optional relation for the form to be shown
   8. [`text`](/reference/servoyextensions/ui-components/form-containers/tabpanel#text): the tab's title text ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n#i18n) and custom HTML supported)
   9. [`toolTipText`](/reference/servoyextensions/ui-components/form-containers/tabpanel#tooltiptext): the text message when a user hovers their cursor ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n#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#datasource) property on the main form
2. Set the [`datasource`](/reference/servoycore/object-model/solution/form#datasource) property on the contained form
3. Make sure that the [relation](/guides/develop/application-design/data-modeling/relations) 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#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#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). 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#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#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). 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#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#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#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#closeiconstyleclass) property of the TabPanel.

### Custom Tab Markup

Tab's title [text](/reference/servoyextensions/ui-components/form-containers/tabpanel#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#properties) can be also set in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor).\
You can find a list of AccordionPanel API methods [here](/reference/servoyextensions/ui-components/form-containers/tabpanel#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) 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) 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) 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#onchangemethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) 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#ontabclickedmethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) 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#ontabclosemethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) 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#onchangemethodid) of an TabPanel in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) 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
}


```


# Split Pane

## Overview

The Split Pane component is a container that shows a 'left' (1) and a 'right' (2) form in it. It will show both forms at the same time, placed either horizontally or vertically, with a divider between them. These 2 forms can optionally show related data.

The divider's location can be modified either from code or directly by the user.\
It is suited for use in both Advanced (Responsive) and Simple CSS forms.

## Get Started

<div align="left"><figure><img src="/files/FhZoW6r6EwK2GvFXMMIs" alt=""><figcaption><p>Split Pane</p></figcaption></figure></div>

### Creating a Split Pane

<div align="left"><figure><img src="/files/9ucQopJo1u2iJUcVt2YF" alt=""><figcaption><p>Create a Split Pane</p></figcaption></figure></div>

Here are the steps for creating a Split Pane:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Split Pane**
2. Find **Split Pane** in *Form Containers* section in the components' pallet
3. Drag and drop the **Split Pane** component in the desired place of the form
4. Set the panels' orientation by selecting [`splitType`](/reference/servoyextensions/ui-components/form-containers/split-pane#splittype) property

   <div align="left"><figure><img src="/files/JIOQGfgqiYnnxxeLU8QC" alt=""><figcaption></figcaption></figure></div>
5. Add `pane1` and `pane2`

   <div align="left"><figure><img src="/files/MhaueXT6YD0boKvelUx0" alt=""><figcaption></figcaption></figure></div>
6. Add forms in [`containedForm`](/reference/servoyextensions/ui-components/form-containers/split-pane#containsformid) panels' property, where you set the name of the form you want to be displayed in each panel

   <div align="left"><figure><img src="/files/ThbPRTTDVvYFlSI0vSJ5" alt=""><figcaption></figcaption></figure></div>
7. Optionally, you can [use a relation](#using-a-relation) by selecting the [`relationName`](/reference/servoyextensions/ui-components/form-containers/split-pane#relationname) property, where you set the [relation](/guides/develop/application-design/data-modeling/relations) between the main form and the contained form of the panel

   <div align="left"><figure><img src="/files/eeyxcn2d67IjEJIZUC8R" alt=""><figcaption></figcaption></figure></div>
8. Set `pane1MinSize` (minimum size of first panel in pixels) and `pane2MinSize` (minimum size of second panel in pixels)

   <div align="left"><figure><img src="/files/AKcPeRRUKwr3XVzdzAQ2" alt=""><figcaption></figcaption></figure></div>
9. Set the [divider properties](#setting-the-divider-properties)
10. Edit other [**Split Pane** properties](/reference/servoyextensions/ui-components/form-containers/split-pane#properties) if needed

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

<img src="/files/CJnTFg8fMGfUqYUsD9A7" alt="Split Pane name" data-size="original">
{% endhint %}

### Using a relation

The contained form of the panels 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#datasource) property on the main form
2. Set the [`datasource`](/reference/servoycore/object-model/solution/form#datasource) property on the contained form
3. Make sure that the [relation](/guides/develop/application-design/data-modeling/relations) 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/split-pane#relationname) property of the corresponding panel

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.

### Setting the divider properties

<figure><img src="/files/DWn1nzlsrMG7HMlY5aFT" alt=""><figcaption><p>divider properties</p></figcaption></figure>

**Divider location** is set by using the [divLocation](/reference/servoyextensions/ui-components/form-containers/split-pane#divlocation) property: sets the initial splitter div location, between 0 and 1 is a percentage, more than 1 is a value in pixels. If location is less than 1 (-1 or .5 = middle, lower then .5 = close to left/top, higher then .5 = close to right/bottom), then the location will be considered at (location \* 100) percent of the split pane from left, otherwise it will represent the pixels from left.

**Width of divider** is set by using the [divSize](/reference/servoyextensions/ui-components/form-containers/split-pane#divsize) property, which represents the divider size in pixels.

## Scripting a Split Pane

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

### Setting the forms

Here is an example of how to programmatically set the contained form, including relationName, in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form:

```javascript
/**
 * Callback method when form is (re)loaded.
 *
 * @param {JSEvent} event the event that triggered the action
 *
 * @private
 *
 * @properties={typeid:24,uuid:"2A6697C8-38B1-4264-9D8B-2C3B5758FFC6"}
 */
function onLoad(event) {
    // TODO Auto-generated method stub
    // splitpane_orders = the name of the Split Pane container in the main form
    // pane1 = panel on the left / top 
    // pane2 = panel on the right / bottom
    // order_details = the contained form in pane1
    // orders_to_order_details = relation between datasource table of the main form to datasource table of the pane1 contained form
    // orders_customers = the contained form in pane2
    // orders_to_customers = relation between datasource table of the main form to datasource table of the pane2 contained form
    elements.splitpane_orders.pane1.containsFormId = forms.order_details;
    elements.splitpane_orders.pane1.relationName = orders_to_order_details;
    elements.splitpane_orders.pane2.containsFormId = forms.orders_customers;
    elements.splitpane_orders.pane2.relationName = orders_to_customers;
}
```

### Moving the divider

Here is an example of how to save the previous divider location in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form and set the same for the next user session:

Saving the divider location in the `onChange` event(fired after divider location changed) of the Split Pane container:

```javascript
/**
 * @param {Number} previousIndex
 * @param {JSEvent} event
 *
 * @private
 *
 * @properties={typeid:24,uuid:"FC548162-34E1-4AD0-91C4-390222D478CA"}
 */
function onChange(previousIndex, event) {
    // TODO Auto-generated method stub
    application.setUserProperty(controller.getName()+"."+elements.splitpane_orders.getName()+".divider",elements.splitpane_orders.getDividerLocation().toString())
}
```

Checking if there is a saved previous divider location and set it in the `onLoad` main form event:

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

/**
 * Callback method when form is (re)loaded.
 *
 * @param {JSEvent} event the event that triggered the action
 *
 * @private
 *
 * @properties={typeid:24,uuid:"2751B88B-48CF-477C-8422-0BC79FFDDED5"}
 */

function onLoad(event) {
    // TODO Auto-generated method stub
    dividerLocation = application.getUserProperty(controller.getName()+"."+elements.splitpane_orders.getName()+".divider");
    if (dividerLocation)
    {
        elements.splitpane_orders.divLocation = parseInt(dividerLocation);
    }   
}
```


# Collapse

## Overview

The Collapse component is a collapsible container that can show either some custom html, a form or a number of so called "cards". The component can hold several collapsibles and their cards and offers an "accordionMode" property that when true will hide all other collapsibles when one collapsible is expanded.

Since the nature of this component involves content to flow, it is best suited for responsive layouts in Servoy, although it is not limited to those.

{% hint style="warning" %}
This is a more advanced container! For simple use cases, use [Accordion Panel](/guides/develop/application-design/forms/form-containers/accordion-panel).
{% endhint %}

You can find the reference documentation about this component [here](/reference/servoyextensions/ui-components/form-containers/collapse).


# Accordion Panel

## Overview

The AccordionPanel component is a container similar to a TabPanel, but instead of having tabs for showing / hiding forms, it has buttons that behave like an accordion, moving one way or the other.

It can hold one or more forms. But only one of them is visible at a time. The active/visible form can be changed via button clicks or from code. Forms can be added and removed both at design-time and at runtime. Child forms can optionally show data through a relation.

It can be used in both responsive and anchored layouts.

## Get Started

<div align="left"><figure><img src="/files/vcduZNxmsoMaD85hif3x" alt=""><figcaption><p>Accordion</p></figcaption></figure></div>

### Creating an Accordion Panel

<div align="left"><figure><img src="/files/MZfIigz40wCHRZEvJiYp" alt=""><figcaption><p>Create an Accordion Panel</p></figcaption></figure></div>

Here are the steps for creating an Accordion Panel:

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

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

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

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

<img src="/files/Q72JO3yucKe8CuqvkswT" alt="Accordion 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#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/V2UaJmWr7Bs0ROcClGRe" 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/accordionpanel#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 **Accordion Panel** (in the form editor).
   2. Drag and drop `tab` component (of an **AccordionPanel** in *Form Containers* section in the components' pallet) into the **AccordionPanel** container (in the form editor)
2. Expand the [`tabs`](/reference/servoyextensions/ui-components/form-containers/accordionpanel#tabs) property to see the list of tabs. They are also shown in the **AccordionPanel** container (in the form editor)
3. In order to edit each tab, expand it or click the tab name in the **AccordionPanel** container (in the form editor) and set the properties:
   1. [`containedForm`](/reference/servoyextensions/ui-components/form-containers/accordionpanel#containedform): the form shown in the tab
   2. [`disabled`](/reference/servoyextensions/ui-components/form-containers/accordionpanel#disabled): whether that tab is enabled or not
   3. [`name`](/reference/servoyextensions/ui-components/form-containers/accordionpanel#name): a name for this tab
   4. [`relationName`](/reference/servoyextensions/ui-components/form-containers/accordionpanel#relationname): optional relation for the form to be shown
   5. [`text`](/reference/servoyextensions/ui-components/form-containers/accordionpanel#text): the tab's title text ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n#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#datasource) property on the main form
2. Set the [`datasource`](/reference/servoycore/object-model/solution/form#datasource) property on the contained form
3. Make sure that the [relation](/guides/develop/application-design/data-modeling/relations) 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/accordionpanel#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.

## Customize the Tabs

### Set the tab text

Tab's title [text](/reference/servoyextensions/ui-components/form-containers/accordionpanel#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). 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#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>

### Custom Tab Markup

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

Example:

<figure><img src="/files/isX8CIZ9ob8MJWTkq2SV" 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.accordionpanel_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 an Accordion

[**AccordionPanel** properties](/reference/servoyextensions/ui-components/form-containers/accordionpanel#properties) can be also set in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor).\
You can find a list of AccordionPanel API methods [here](/reference/servoyextensions/ui-components/form-containers/accordionpanel#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) 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.accordionpanel_orders.selectTabAt(index)
} // call this function after the AccordionPanel 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) of the main form:

```javascript
function onShow(firstShow, event) {
	// TODO Auto-generated method stub
    elements.accordionpanel_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) of the main form:

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

### Enabling/Disabling a tab

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

```javascript
function onShow(firstShow, event) {
	// TODO Auto-generated method stub
    elements.accordionpanel_orders.getTabAt(1).disabled = true;   //disables a tab 
    elements.accordionpanel_orders.getTabAt(2).disabled = false;  //enables a tab
} 
```

### Handling Tab Change Event

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

Saving the active tab index in the `onChange` event(fired after a different tab is selected) of the AccordionPanel 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.accordionpanel_orders+".activeTab",elements.accordionpanel_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.accordionpanel_orders+".activeTab");
    if (activeTab)
    {
        elements.accordionpanel_orders.selectTabAt(parseInt(activeTab));
    }   
}
```


# Form Component

## Overview

The "Form Component Container" component shows one [Form Component](/guides/develop/application-design/forms/form-components#form-components) inside it. It has no additional UI decorations.

The contained form component can optionally show related data.

It is suited for use in both Advanced (Responsive) and Simple CSS forms.

{% hint style="warning" %}
Form Components are an advanced feature. Please first see other [Form Container](/guides/develop/application-design/forms/form-containers#types-of-form-containers) types to explore options for nesting forms within forms.
{% endhint %}

## Get Started

<div align="left"><figure><img src="/files/3XRGp6WXC0F1EnfTzPLu" alt=""><figcaption><p>Form Component</p></figcaption></figure></div>

### Placing a container on the form

<div align="left"><figure><img src="/files/cZBvZjtO456fREX2eXMJ" alt=""><figcaption><p>Create Form Component Container</p></figcaption></figure></div>

Here are the steps for placing a container on the form:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place an **Form Component Container**
2. Find **FormComponentContainer** in *Form Containers* section in the components' pallet
3. Drag and drop the **FormComponentContainer** component in the desired place of the form
4. Select the [`containedForm`](/reference/servoyextensions/ui-components/form-containers/form-component-container#containedform) property, where you set the name of the form component you want to be displayed in the container
5. Edit the elements of the contained Form Component, when it's necessary
6. Edit other [**FormComponentContainer** properties](/reference/servoyextensions/ui-components/form-containers/form-component-container#properties) if needed

<div align="left"><figure><img src="/files/aojkvvXw0vYyZmq4qxUy" alt=""><figcaption><p>Editing the elements of a contained Form Component</p></figcaption></figure></div>

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

<img src="/files/t7ljyksfcRNDsah2AGKi" alt="Form Component Container name" data-size="original">
{% endhint %}

## Working with the Form Component instance

### Connecting event bindings

Because a Form Component form doesn't have its own logic (.js file), events like `onAction` of a button must be assigned to the form.js file of the containing form, or to top-level scopes or entity methods.

Example:

<div align="center"><figure><img src="/files/8rjuaf264rnWgiUrUquy" alt=""><figcaption><p>assign event for a form component's button</p></figcaption></figure></div>

You can add logic for a button created in a Form Component form (placed in a Form Component Container) by accessing that button in the main form and assign the button events to the main form's scope (.js file):

```javascript
/**
 * Fired when the button is clicked.
 *
 * @param {JSEvent} event
 *
 * @private
 *
 * @properties={typeid:24,uuid:"28F80574-DBD2-4631-89F1-090CB57049DB"}
 */
function onAction(event) {
	var record = foundset.getSelectedRecord()
	forms.customers.controller.loadRecords(record.foundset);
	application.showForm('customers');
}
```

### Programmatic interaction with elements

Elements of a Form Component can be accessed in the main form where its Form Component Container is placed, using the following convention:

`elements.my_form_component.containedForm.my_sub_element.property`

Example:

```javascript
/**
 * 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:"476A4F16-1F03-400A-B89C-7CE92E01B443"}
 */
function onShow(firstShow, event) {
	
	elements.fc_id_name_details.containedForm.label.visible = false;
  	//fc_id_name_details = the name of the Form Component Container
}
```


# List Form Component

## Overview

The "List Form Component Container" component is a container that has 1 [Form Component](/guides/develop/application-design/forms/form-components#form-components) inside it. However, it displays in the application one instance of the contained form component **for each record of the foundset**. It has no additional UI decorations.\
The contained form component can optionally show related data.

It is suited for use in both Advanced (Responsive) and Simple CSS forms.

{% hint style="info" %}
List Form Component Container is used most often in Advanced (Responsive) forms, as the space it takes on the screen depends on how many instances of the contained form component are shown.\
When used in Simple CSS forms and the space taken by the contained form component exceeds the allocated space on the main form, there will be a scroll inside the List Form Component Container.
{% endhint %}

{% hint style="warning" %}
Form Components are an advanced feature. Please first see other [Form Container](/guides/develop/application-design/forms/form-containers#types-of-form-containers) types to explore options for nesting forms within forms.
{% endhint %}

## Get Started

<div align="left"><figure><img src="/files/NunR6jwl2sY6cOXHAGOt" alt=""><figcaption><p>List Form Component</p></figcaption></figure></div>

### Placing a container on the form

<div align="left"><figure><img src="/files/HQDj4vHFR8E4OpaQ6rqU" alt=""><figcaption><p>Create List Form Component Container</p></figcaption></figure></div>

Here are the steps for placing a container on the form:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place an **List FormComponent Container**
2. Find **List FormComponent Container** in *Form Containers* section in the components' pallet
3. Drag and drop the **List FormComponent Container** component in the desired place of the form, the `Select Form Component` wizard will appear
4. Select the desired Form Component (it can be related or unrelated to the form's dataSource), then click `OK`
5. Edit the elements of the contained Form Component, when it's necessary
6. Edit other needed [**List FormComponent Container** properties](/reference/servoyextensions/ui-components/form-containers/list-form-component-container#properties)

<div align="center"><figure><img src="/files/97xY2os4Jb7IUjlzG2XQ" alt=""><figcaption><p>List Form Component Container - properties</p></figcaption></figure></div>

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

<img src="/files/p0JXhpax5ADfZatMwxUu" alt="List Form Component Container name" data-size="original">
{% endhint %}

### List view vs Card view

Instances of the contained form component can de displayed in two ways:

* **List View** : instances are displayed one under the other

<div align="center"><figure><img src="/files/YQJxPTZPyYYwxziFw34D" alt=""><figcaption><p>List View</p></figcaption></figure></div>

This view can be obtaiend by selecting `listview` in the List Form Component Container [pageLayout](/reference/servoyextensions/ui-components/form-containers/list-form-component-container#pagelayout) property

* **Card view** : instances are displayed as cards, on multiple columns and rows (when the case)

<div align="center"><figure><img src="/files/byivb4n26AUmBq3Xqcxf" alt=""><figcaption><p>Card View</p></figcaption></figure></div>

This view can be obtaiend by selecting `cardview` in the List Form Component Container [pageLayout](/reference/servoyextensions/ui-components/form-containers/list-form-component-container#pagelayout) property

## Working with the Form Component instance

### Connecting event bindings

Because a Form Component form doesn't have its own logic (.js file), events like `onAction` of an element can be assigned only to scopes or entity methods.

Example:

<div align="center"><figure><img src="/files/6g120EH52LnXxutHVCnU" alt=""><figcaption><p>assign event for a form component's label</p></figcaption></figure></div>

You can add logic for a label created in a Form Component form (placed in a Liat Form Component Container) by accessing that label in the main form and assign the label events to the main form's scope (.js file):

```javascript
/**
 * Click event. dataTarget parameter is used to identify inner html elements (by their data-target attribute).
 *
 * @param {JSEvent} event
 * @param {String} dataTarget
 *
 * @private
 *
 * @properties={typeid:24,uuid:"63DEB955-288A-4F7C-9D04-280A9C34CE8F"}
 */
function onActionOrderID(event, dataTarget) {
	application.showForm('orders');
}
```

### Programmatic interaction with elements

Elements of a contained Form Component can be accessed in the main form where its List Form Component Container is placed.

Example:

```javascript
/**
 * 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:"9DB5DBBA-A3E2-4090-85BA-3957A1146421"}
 */
function onShow(firstShow, event) {
	elements.list_fc_orders.containedForm.label_customer_id.addStyleClass('info-text');
    //list_fc_orders = the name of the List Form Component Container
}

```

## Advanced

### Selection Class

The user can define a custom style for the selected instance of the contained form component, using the List Form Component Container [SelectionClass](/reference/servoyextensions/ui-components/form-containers/list-form-component-container#selectionclass) property.

{% hint style="danger" %}
In case `rowStyleClassDataprovider` or `rowStyleClass` are used, make sure that the selection styleclass definition is last in the solution stylesheet, to avoid overwriting it.
{% endhint %}

### Row Style Class Data Provider

This property adds a adds a styleclass to the row. It is usually used in combination with a [calculation](/guides/develop/application-design/data-modeling/databases/tables/calculations#overview) to parse a piece of text that is used as the styleclass.

Example:

<div align="center"><figure><img src="/files/VktTkKetwm7q7oQXxgjx" alt=""><figcaption><p>RowStyleClassDataProvider set on a List Form Component Container</p></figcaption></figure></div>

Having a different background color according to an order delivery date. To achieve this there are a few steps to be followed:

* create a calculation in `orders` table:

```javascript
/**
 * @properties={type:12,typeid:36,uuid:"E25F53FD-7B0D-4BAB-8843-6E5A1C86E101"}
 */
function requiredDateStyleTile()
{
	if (requireddate.getFullYear() < 1997)
	{
		return 'bg-red';
	}
	if (requireddate.getFullYear() == 1997)
	{
		return 'bg-yellow';
	}
	return '';
}
```

* make sure the the classes used in calculation exist, otherwise create them in a .less file:

```css
.bg-red{
	background-color: red;
}

.bg-yellow{
	background-color: yellow;
}
```

* access the list form component container in the main form and set the calculation name in [RowStyleClassDataprovider](/reference/servoyextensions/ui-components/form-containers/list-form-component-container#rowstyleclassdataprovider)

<div align="center"><figure><img src="/files/KwdD2zVxE7LQrYQc3suj" alt=""><figcaption><p>set RowStyleClassDataprovider</p></figcaption></figure></div>

### Row Editable Data Provider

This is a dataprovider that will return true or false. In case it is true, that row is editable, otherwise it is not.

Example:

Having a read-only card/row according to an order shipped date:

* in case there is not already a boolean table column of the foundset/datasource, then a [calculation](/guides/develop/application-design/data-modeling/databases/tables/calculations#overview) is needed:

`orders_calculations`

```javascript
/**
 * @properties={type:12,typeid:36,uuid:"05E3332F-DDA1-45BF-A428-FCD6A20EA960"}
 */
function ShippedDateEditableTile()
{
	if (shippeddate <= new Date())
	{
		return false;
	}

	return true;
}
```

* access the list form component container in the main form and set the calculation name in [RowEditableDataprovider](/reference/servoyextensions/ui-components/form-containers/list-form-component-container#roweditabledataprovider)

<div align="center"><figure><img src="/files/ZVVhYYSP7amYHJ1fwRBp" alt=""><figcaption><p>set RowEditableDataprovider</p></figcaption></figure></div>

\-->


# Form Inheritance

## Overview

Form inheritance is used to extend a form's functions and UI with those of another form (the super form).\
This will give the original form all the methods/variables/elements/properties/parts of the form that it extends.

The inheritance is not limited to 1 level, for example there is a form a, form b and form c, form b is extended with a and c with b. The result is that form c will then have all the methods/variables/elements/properties/parts of form a, b and c.

When using form inheritance, the properties and methods can still be overwritten in the sub forms. This is not the case for the datasource, the datasource can not be changed from one table to another, it can be changed from empty to a table.

## Get Started

<div align="left"><figure><img src="/files/ow1JJyvvrEbp20XRTM27" alt=""><figcaption><p>Form inheritance</p></figcaption></figure></div>

Let's consider the following main forms:

* Form `base_code`: Here are all the functions like 'new record', 'delete record' and all buttons found in `base` form. On this form there are no parts, it is strictly code. This form will have no datasource.
* Form `base`: Here are buttons for 'home', 'settings', 'employees', 'save', 'cancel' . There could be more than one, so there can be multiple designs. This form will inherit the `base_code` form and uses all it's functions. This form will have no datasource.

Sub forms, which extend `base` form and will inherit the `base` form (because the functions and buttons are already inherited only the datasource and fields have to be added) :

* Form `home`
* Form `settings`
* Form `employees`
* Form `new_employee`

The parent form (super form) can be set by selecting its form name in the subform's [extendsForm](/reference/servoycore/object-model/solution/form#extendsform) property.

<div align="center"><figure><img src="/files/mEOt9q6f7pMHO7u8tmmp" alt=""><figcaption><p>Setting the parent form</p></figcaption></figure></div>

### Override a form property

Inherited form properties can be overriden in the subform's [properties](/reference/servoycore/object-model/solution/form#property-summary).

### Override a form event binding

Inherited form [event](/reference/servoycore/object-model/solution/form#events-summary) bindings can be overriden in the subform's [scripting editor](/reference/servoy-developer/object-editors/scripting-editor). This can also be completely removed from the subform.

### Override a component property

<div align="left"><figure><img src="/files/9kgEzvawsn5aX4X23Wpb" alt=""><figcaption><p>Overriding components' properties</p></figcaption></figure></div>

Inherited component's properties can be overriden in the subform's properties tab.

### Override a component event binding

Inherited component's event binding can be overriden in the subform's [scripting editor](/reference/servoy-developer/object-editors/scripting-editor). This can also be completely removed from the subform.

### Adding a component

<div align="left"><figure><img src="/files/B3cKVLJSzAGdDNoP5BVf" alt=""><figcaption><p>Adding a component on `base` form</p></figcaption></figure></div>

When a component is added to a superform, it will also appear in all forms that extend the superform.

<div align="left"><figure><img src="/files/s3k6eCxbvO6Kwdtkp4lf" alt=""><figcaption><p>Effect of adding a component on `base` form</p></figcaption></figure></div>

### Deleting a component

When a component is deleted from a superform, it will also be removed from all forms that extend the superform.

### Updating the base form UI

<div align="left"><figure><img src="/files/4z9OLAam3JTCM1EKbxrl" alt=""><figcaption><p>Update a component UI on `base` form</p></figcaption></figure></div>

All changes made to the base form UI will be propagated to child forms unless overridden.

<div align="left"><figure><img src="/files/bceO2lpRd2KyJMLKENkl" alt=""><figcaption><p>Effect of updating a component UI on `base` form</p></figcaption></figure></div>

## Inherited Business Logic

### Overriding a method

A sub form will inherit all the methods of the super form. These methods can be overwritten. When this happens, Servoy will generate a method with a call to it's super in it. Inherited methods can be overriden in the subform's [scripting editor](/reference/servoy-developer/object-editors/scripting-editor). In order to override a method, you can right-click the method in the solex and select `Override method` from the pop-up menu.

<div align="center"><figure><img src="/files/4Tf0Xh4Oq3JkNlMI0hkH" alt=""><figcaption><p>Overriding a method</p></figcaption></figure></div>

Example:

* on `base` form:

```javascript
/**
 * Check if this form can be hidden, return false if this is not allowed.
 *
 * @param {JSEvent} event the event that triggered the action
 *
 * @return {Boolean}
 *
 * @properties={typeid:24,uuid:"FD8D9775-6F4D-42ED-8ED0-ECD4A6D5C365"}
 */
function onBeforeHide(event) {
	// TODO Auto-generated method stub
	databaseManager.revertEditedRecords();
	return true
}
```

In the generated method there will be `_super.onBeforeHide(event)` this will call the original method on the super form. This can be removed if the super code doesn't need to be called or code can be inserted before of after the call, if it is inserted after the super call don't forget to move the `return`.

* on `new_employee` form:

Sample of code before:

```javascript
/**
 * @param {JSEvent} event
 *
 * @return {Boolean}
 * @override
 *
 * @properties={typeid:24,uuid:"06BD3620-26F3-4F46-ABD4-84D200C86296"}
 */
function onBeforeHide(event) {
	elements.error.visible = false;
	return _super.onBeforeHide(event);
}
```

Sample of code after:

```javascript
/**
 * @param {JSEvent} event
 *
 * @return {Boolean}
 * @override
 *
 * @properties={typeid:24,uuid:"06BD3620-26F3-4F46-ABD4-84D200C86296"}
 */
function onBeforeHide(event) {
	_super.onBeforeHide(event);
	elements.error.visible = false;
	return;
}
```

Sample of removed super code:

```javascript
/**
 * @param {JSEvent} event
 *
 * @return {Boolean}
 * @override
 *
 * @properties={typeid:24,uuid:"06BD3620-26F3-4F46-ABD4-84D200C86296"}
 */
function onBeforeHide(event) {
	elements.error.visible = false;
	return true;
}
```

### Invoking the "super" form

The inherited form can be invoked in child forms (subforms).

Exemple:

* on `new_employee` form:

```javascript
/**
 * @properties={typeid:24,uuid:"4A5E6308-A50F-400B-AC9A-EF4EBE4E1F7F"}
 * @override
 */
function newRecord()
{
	_super.newRecord();	// this will call the original method on the super form
	foundset.hiredate = new Date();	
}
```

### Encapsulation Modifiers

Methods that are defined to be private, will not be available for the subforms. By creation of a method there is a choice to make it private, public or protected. If a method is already created it can be done by adding '@protected', '@private' to the docs.

* Public : public methods will be available because they are available everywhere
* Private : private methods will not be available for any other forms, not even the subforms
* Protected : protected methods will be available for the subform but not for other forms

## Abstract Forms

An Abstract Form is a Form that does not implement any Form Parts and as such can not be shown to the user, but can contain business logic and can act as a Super Form for Child Forms.

Example:

`base_code` form

```javascript
/**
 * @properties={typeid:24,uuid:"3317FB54-008E-4B52-AF8C-03498081B173"}
 */
function newRecord()
{
	var newRec = foundset.getRecord(foundset.newRecord())
	foundset.selectRecord(newRec)
}

/**
 * TODO generated, please specify type and doc for the params
 * @param {JSRecord} record
 *
 * @properties={typeid:24,uuid:"023612B8-4711-4059-BA48-84F3C1BD562D"}
 */
function deleteRecord(record)
{
	foundset.deleteRecord(record)
}

/**
 * @properties={typeid:24,uuid:"4A5BF651-00B6-4EFE-AD67-90EBB70B6E49"}
 */
function SaveButton()
{
	databaseManager.saveData()
}

/**
 * @properties={typeid:24,uuid:"8026B0DF-6276-4BC9-A9AB-E5F62CDA459F"}
 */
function CancelButton()
{
	databaseManager.revertEditedRecords(foundset);
}

/**
 * Fired when the button is clicked.
 *
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"1D4F5ACD-32C3-452D-864F-4651D5E0242C"}
 */
function onActionHome(event) {
	// TODO Auto-generated method stub
//var FormName = controller.getName();
//if (FormName != '')
application.showForm('home_simple');
}


/**
 * TODO generated, please specify type and doc for the params
 * @param event
 *
 * @properties={typeid:24,uuid:"177F881B-5922-481F-BCA2-5AB832DA8FE9"}
 */
function onActionSettings(event) {
	// TODO Auto-generated method stub
//var FormName = controller.getName();
//if (FormName != '')
application.showForm('settings_simple');
}

/**
 * TODO generated, please specify type and doc for the params
 * @param event
 *
 * @properties={typeid:24,uuid:"9AC1F0B5-E0FC-403A-A240-670BF8C49E91"}
 */
function onActionEmployees(event) {
	// TODO Auto-generated method stub
//var FormName = controller.getName();
//if (FormName != '')
application.showForm('employees_simple');
}
```


# Form Components

## Overview

Form Component in the Solution Explorer Tree is a special contained form used for simplified design and runtime optimization. The same behavior can be achieved via tabless tabpanel, but form component has optimized display because all elements are part of the same form, taking away the overhead of tabpanel and loading of another form.

{% hint style="warning" %}
A **Form Component** form can't have its own logic (.js file), it is also not available at runtime under `forms.xxx` because there is no instance of such a form. Only the template and its properties are used, events like `onclick` of a button can be assigned but only to scopes or entity methods (if the datasource is specified). Also because it does not have its own instance at runtime also all the form component events and commands like `onLoad` are not available for it.
{% endhint %}

Such a **Form Component** form can be places on the form by using the following containers:

* [FormComponentContainer](/guides/develop/application-design/forms/form-containers/form-component#overview)
* [List FormComponent Container](/guides/develop/application-design/forms/form-containers/list-form-component#overview)

## Get Started

### Creating a Form Component

Here are the steps for creating a Form Component:

1. Open the active solution in [Solution Explorer](/reference/servoy-developer/solution-explorer/all-solutions/solution)
2. Find the **Form Components** node, right click on it and select 'Create new form component', then 'New Form Component' wizard will appear
3. In the wizard you need to set the `Form name` and select the `Type`, also `Datasource` and `Extends` if needed, then click the `Finish` button
4. The form editor will appear, where you can add the desired elements

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

### Editing a Form Component

<div align="center"><figure><img src="/files/7ghCfBU8CvjzHPe0vu5J" alt=""><figcaption><p>Form Component - properties</p></figcaption></figure></div>

**Form Component** has a list of several [properties](/reference/servoycore/object-model/solution/form-component#property-summary) that can be edited the same way as for a normal Form.


# UI Components


# Buttons and Text


# Badge

Guide for using badges in your applications

## Overview

This guide will show how to use badges in your applications. See how easy it is to drag and drop badges onto your forms and connect them to your business logic. Badges can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=badge).

The badge component can be used to easily highlight new or unread items in labels or buttons.

Label example:

<figure><img src="/files/NUUoqRJkMahPGALq6SWb" alt=""><figcaption><p>Label</p></figcaption></figure>

Button example:

<figure><img src="/files/0ss9zqQjzAuCExjpNsEX" alt=""><figcaption><p>Button</p></figcaption></figure>

## Get Started

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Badge component from the Pallet onto the form.

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Extra Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/object-editors/package-manager.md) and install it.
{% endhint %}

## Modifying a Badge at Design-Time

Badges, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the badge in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

{% hint style="info" %}
See the reference docs for [Badge](/reference/servoyextensions/ui-components/buttons-and-text/badge) for a complete list of its [properties](/reference/servoyextensions/ui-components/buttons-and-text/badge#properties).
{% endhint %}

### Setting the Text

The text displayed on the label or button can be modified by setting its [`text`](/reference/servoyextensions/ui-components/buttons-and-text/badge#text) property. Most often, this will just be plain text, such as "Messages" or "Inbox". In this case, just enter the value into the editor or directly on the component by double-clicking it. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the badgeText

The badge text shown on the label or button can be modified by setting its [badgeText ](/reference/servoyextensions/ui-components/buttons-and-text/badge#badgetext)property. Usually this will be dynamic, otherwise just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

{% hint style="info" %}
Remember that text can also be dynamic, data-driven[^1] or localized. For more options, you can open edit the text property in the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).
{% endhint %}

### Setting an Image / Font-Icon

Many times, a badge will be decorated with an image or font icon. To add an image to your badge, edit the [`imageStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/badge#imagestyleclass) property and choose the image style class of the font icon you wish to use. For example, enter a value of `fa-regular fa-envelope` to get a nice "Messages" icon.

<figure><img src="/files/WqoPHQEcEhf0D3jSdSXF" alt=""><figcaption></figcaption></figure>

For more information, please see the [Font Icon](/guides/develop/application-design/styling-and-themes/font-icons) section of the guide on [Styling and Themes](/guides/develop/application-design/styling-and-themes).

### Styling

Like all components, baqdges can be styled using themes and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

<img src="/files/WqoPHQEcEhf0D3jSdSXF" alt="" data-size="line"> For example, `styleClass="font-weight-bold h3 border-class"`

## Handling Events

Like most components, Badges have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a badge is the `onAction` event, which is triggered when the component is clicked or the user hits the `Enter` key while the badge has focus.

To Handle the event, double-click the value for the `onAction` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the badge's `onAction` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"A74C281C-00AA-46AA-BB38-500C937F2D1A"}
 */
function onAction(event) {
	// Enter custom code
}
```

{% hint style="info" %}
See the [Badge reference](/reference/servoyextensions/ui-components/buttons-and-text/badge) for comprehensive list of [all events](/reference/servoyextensions/ui-components/buttons-and-text/badge#events)
{% endhint %}

## Modifying a Badge at Runtime

Badges, like many components, can be modified at runtime through code. Below are a few examples of controlling a Badge from code.

### Enabling / Disabling a badge

You can easily change the `enabled` state of a Badge at runtime.

```javascript
function disableBadge(){
	elements.myBadge.enabled = false;
}
```

### Hiding/Showing a Badge

You can easily change the `visible` state of a Badge at runtime.

```javascript
function hideBadge(){
	elements.myBadge.visible = false;
}
```

## Calling Badge API Methods

Like most components, a Badge has API methods which can be called from code. Below is an example of common API calls.

### Add CSS Style Class

You can easily add a style class to a badge using the `addStyleClass` method.

```javascript
function AddStyleClassBadge(){
	elements.myBadge.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Badge Reference Docs](/reference/servoyextensions/ui-components/buttons-and-text/badge) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/buttons-and-text/badge#properties) and methods.
{% endhint %}

## Related Articles

The following articles are recommended for additional reading:

* [Badge Reference Documentation](/reference/servoyextensions/ui-components/buttons-and-text/badge)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)

1. Anywhere you show text, it can be translated and localized to the users language. For more information, read our guide on [Multi-Language Support](/guides/develop/multi-language-support)

[^1]: Anywhere text is displayed, it can be substituted and merged with the data in context. For more information read about the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).


# Button

Guide for using buttons in your applications

## Overview

This guide will show how to use buttons in your applications. See how easy it is to drag and drop buttons onto your forms and connect them to your business logic. Buttons can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=button).

## Get Started

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Button component from the Pallet onto the form

<figure><img src="/files/LHBuWsIrsK5k2vis3xVW" alt=""><figcaption><p>Add Button</p></figcaption></figure>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/object-editors/package-manager.md) and install it.
{% endhint %}

## Modifying a Button at Design-Time

Buttons, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the button in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

{% hint style="info" %}
See the reference docs for [Button](/reference/servoyextensions/ui-components/buttons-and-text/button) for a complete list of its [properties](/reference/servoyextensions/ui-components/buttons-and-text/button#properties-summary).
{% endhint %}

### Setting the Text

The text displayed on a button can be modified by setting its [`text`](/reference/servoyextensions/ui-components/buttons-and-text/button#text) property. Most often, this will just be plain text, such as "Submit" or "Cancel". In this case, just enter the value into the editor or directly on the component by double-clicking it. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting a Tooltip message

Buttons, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

{% hint style="info" %}
Remember that text can also be dynamic, data-driven or localized. For more options, you can open edit the text property in the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).
{% endhint %}

### Setting an Image / Font-Icon

Many times, a button will be decorated with an image or font icon. To add an image to your button, edit the [`imageStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/button#imagestyleclass) property and choose the image style class of the font icon you wish to use. For example, enter a value of `fa fa-user-plus` to get a nice "Save" icon.

For more information, please see the [Font Icon](/guides/develop/application-design/styling-and-themes/font-icons) section of the guide on [Styling and Themes](/guides/develop/application-design/styling-and-themes).

### Styling

Like all components, a Button has a button can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

For example, `styleClass="btn btn-default"`

#### Button Variants

If you are using Variants, then you can easily drag and drop variations of your button onto your form.

<figure><img src="/files/A2z0z4qoAAit0oFljQQb" alt=""><figcaption><p>Button Variant being dropped on a form</p></figcaption></figure>

## Handling Events

Like most components, Buttons have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a button is the `onAction` event, which is triggered when the button is clicked or the user hits the `Enter` key while the button has focus.

To Handle the event, double-click the value for the `onAction` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the button's `onAction` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<figure><img src="/files/sOuNMRY0fvgPrAi6g2WG" alt=""><figcaption><p>Create a method t handle the onAction event</p></figcaption></figure>

```javascript
/**
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"A74C281C-00AA-46AA-BB38-500C937F2D1A"}
 */
function onAction(event) {
	// Enter custom code
}
```

{% hint style="info" %}
See the [Button reference](/reference/servoyextensions/ui-components/buttons-and-text/button) for comprehensive list of [all events](/reference/servoyextensions/ui-components/buttons-and-text/button#events-summary)
{% endhint %}

## Modifying a Button at Runtime

Buttons, like many components, can be modified at runtime through code. Below are a few examples of controlling a Button from code.

### Enabling / Disabling a button

You can easily change the `enabled` state of a Button at runtime.

```javascript
function disableButton(){
	elements.myButton.enabled = false;
}
```

### Hiding/Showing a Button

You can easily change the `visible` state of a Button at runtime.

```javascript
function hideButton(){
	elements.myButton.visible = false;
}
```

## Calling Button API Methods

Like most components, a Button has API methods which can be called from code. Below is an example of common API calls.

### Give Keyboard Focus

You can easily give keyboard focus to a button using the [`requestFocus`](/reference/servoyextensions/ui-components/buttons-and-text/button#requestfocus) method.

```javascript
function focusButton(){
	elements.myButton.requestFocus();
}
```

### Add CSS Style Class

You can easily add a style class to a button using the [`addStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/button#addstyleclass) method.

```javascript
function AddStyleClassButton(){
	elements.myButton.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Button Reference Docs](/reference/servoyextensions/ui-components/buttons-and-text/button) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/buttons-and-text/button#properties-summary) and [methods](/reference/servoyextensions/ui-components/buttons-and-text/button#methods-summary).
{% endhint %}

## Related Articles

The following articles are recommended for additional reading:

* [Button Reference Documentation](/reference/servoyextensions/ui-components/buttons-and-text/button)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Data Label

Guide for using data labels in your applications

## Overview

Data Label is a label component based on a dataprovider value, that can show dynamic text and (optionally) an image.

The key differences between a Data Label and a Label and the main reasons for using Data Label instead of Label are the following:

* Data Label supports **format**, which is very useful when it comes to displaying dates, numbers for example
* The value displayed by the Data Label can be enhanced/transposed using a **valuelist**, which is used to get a display value for the actual columns real value like id -> name for example

To see a live sample of the component you can go [here](https://samples-prod.demo.servoy-cloud.eu/solution/components?a=dataLabel).

![Data Label](/files/hJ5sc022EPA32exCoo8c)

## Get Started

### Add a Data Label to a form

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Data Label component from the Pallet onto the form, then select a dataprovider.

<div align="left"><figure><img src="/files/xnyCGD50lhHiRySSgT8o" alt=""><figcaption><p>Create Data Label</p></figcaption></figure></div>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Data Label at Design-Time

Data Labels, like all components, have properties that can be modified at design time to set the appearance and behavior of the component. Select the label in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design time.

{% hint style="info" %}
See the reference docs for [Data Label](/reference/servoyextensions/ui-components/buttons-and-text/datalabel) for a complete list of its [properties](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#properties).
{% endhint %}

### Setting the data-provider

Data Label's dataprovider can be set after the component has been added to the form or by setting it in [dataprovider](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#dataproviderid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties).

### Setting a Tooltip message

Data Labels, like many components, can display tooltip messages when a user hovers their cursor, this can be done by modifying the [`tooltipText`](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#tooltiptext) property using the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

{% hint style="info" %}
The tooltip text can be dynamic, data-driven, or localized.
{% endhint %}

### Setting an Image / Font-Icon

Many times, a data label will be decorated with an image or font icon. To add an image before the text of the data label, edit the [`imageStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#imagestyleclass) property and choose the style class of the font icon you wish to use. For example, enter a value of `fa fa-user` to get a nice icon that represents a User.

Example:\
`imageStyleClass: fa fa-user`

<div align="left"><figure><img src="/files/Ui9ZHzeA5xHTVUS6rfpg" alt=""><figcaption></figcaption></figure></div>

In the same way, there is a [`trailingImageStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#trailingimagestyleclass) property to add an image or icon after the text of the data label.

Example:\
`trailingImageStyleClass: fa fa-user-lock`

<div align="left"><figure><img src="/files/uUbo3UxISwHItiGTmG4c" alt=""><figcaption></figcaption></figure></div>

For more information, please see the [Font Icon](/guides/develop/application-design/styling-and-themes/font-icons) section of the guide on [Styling and Themes](/guides/develop/application-design/styling-and-themes)

### Styling

Like all components, a Data Label can be styled using themes and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the [`styleClass`](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#styleclass) property.

For example, `styleClass="label-info"`

### Using a format

Data Label's Format can be set in [Format](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#format) property. Depending on the type of each dataprovider, this will be done via the format editors for [date](/reference/servoy-developer/object-editors/date-format-editor), [text](/reference/servoy-developer/object-editors/text-format-editor), [integer/number](/reference/servoy-developer/object-editors/number-format-editor).

Example:\
Let's consider a Data Label having `requireddate` set as dataprovider, with no Format set:

<div align="left"><figure><img src="/files/pTavbhtQuD0R4w9jes5k" alt=""><figcaption><p>`requireddate` with no Format</p></figcaption></figure></div>

We need the date to show the full name of the month, followed by day and full year, so we apply a Format, as shown below:

<div align="left"><figure><img src="/files/hyaDaR6HOd6BhyeEbQ4q" alt=""><figcaption><p>set `requireddate` Format</p></figcaption></figure></div>

Here is how it looks after the Format has been set:

<div align="left"><figure><img src="/files/g3KX3hehZqP0AFXmi8aI" alt=""><figcaption><p>`requireddate` with applied Format</p></figcaption></figure></div>

### Using a Value List

Data Label's [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) can be set it in [valuelist](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#valuelistid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties) and it should match the set [dataprovider](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#dataproviderid).

Example:

In order to get a drop down menu with orders' ship countries, the followings settings should be made:

1. set `shipcountry` as the Data Label [dataprovider](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#dataproviderid)
2. in case it doesn't exist, create a [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) using Table values and `shipcountry` column as dataprovider
3. set the countries list in [valuelist](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#valuelistid) property of the Data Label

## Handling Click Events

Like most components, Data Labels have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a data label is the `onAction` event, which is triggered when the data label is clicked or the user hits the `Enter` key while the data label has focus.

To Handle the event, double-click the value for the [onAction](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#onactionmethodid) property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option to select an existing Method or create a new Method. The method will be called when the data label's `onAction` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<figure><img src="/files/JBAvIilpXAKabRVYzJy5" alt=""><figcaption><p>Create method to handle the onAction event</p></figcaption></figure>

```javascript
/**
 *
 * @param {JSEvent} event
 * @param {String} dataTarget
 *
 * @properties={typeid:24,uuid:"4FA50A53-70A6-4D14-83B8-EA3E675EBAEB"}
 */
function onAction(event, dataTarget) {
	application.showForm('order_details');
}
```

{% hint style="info" %}
See the [Data Label reference](/reference/servoyextensions/ui-components/buttons-and-text/datalabel) for a comprehensive list of [all events](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#events)
{% endhint %}

## Modifying a Data Label at Runtime

Data Labels, like many components, can be modified at runtime through code. Below are a few examples of controlling a Data Label from code.

### Enabling / Disabling a label

You can easily change the `enabled` state of a Data Label at runtime.

Example:

```javascript
function disableDataLabel(){
	elements.myDataLabel.enabled = false;
}
```

### Hiding/Showing a Data Label

You can easily change the `visible` state of a Data Label at runtime.

Example:

```javascript
function hideDataLabel(){
	elements.myDataLabel.visible = false;
}
```

## Calling Data Label API Methods

Like most components, a Data Label has API methods which can be called from code. Below is an example of common API calls.

### Add CSS Style Class

You can easily add a style class to a Data Label using the [`addStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#api) method.

Example:

```javascript
function AddStyleClassDataLabel(){
	elements.myDataLabel.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Data Label reference](/reference/servoyextensions/ui-components/buttons-and-text/datalabel) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#properties) and [methods](/reference/servoyextensions/ui-components/buttons-and-text/datalabel#api).
{% endhint %}

## Related Articles

The following articles are recommended for additional reading:

* [Data Label Reference Documentation](/reference/servoyextensions/ui-components/buttons-and-text/datalabel)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Dropdown

Guide for using dropdown in your applications

## Overview

This guide will show how to use Dropdown in your applications. See how easy it is to drag and drop Dropdown onto your forms and connect them to your business logic. Dropdown can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=dropdown).

## Get Started

## Modifying a Dropdown at Design-Time

Dropdown, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the Dropdown in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

### Setting the text

The text displayed on a dropdown can be modified by setting its [`text`](/reference/servoyextensions/ui-components/buttons-and-text/drop-down#text) property. Most often, this will just be plain text, such as "Options" or "Choices". In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the tooltipText

Dropdown, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the enabled

Dropdown, like many components, can be enabled or not enabled in order to allow users to interact with it or not. It can also be changed on runtime.

### Setting the visible

Dropdown, like many components, can be set as visible or not visible when launching an application. It can also be changed on runtime.

### Styling

Like all components, a dropdown can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

## Handling Events

Like most components, dropdown has events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a dropdown is the `onMenuItemSelected` event, which is triggered when a menu item from the dropdown component is clicked.

To Handle the event, double-click the value for the `onMenuItemSelected` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the button's `onMenuItemSelected` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"A74C281C-00AA-46AA-BB38-500C937F2D1A"}
 */
function onMenuItemSelected(event, menuItem) {
	// Enter custom code
}
```

{% hint style="info" %}
See the [dropdown reference](/reference/servoyextensions/ui-components/buttons-and-text/drop-down) for comprehensive list of [all events](/reference/servoyextensions/ui-components/buttons-and-text/drop-down#events)
{% endhint %}

## Modifying a dropdown at Runtime

dropdown, like many components, can be modified at runtime through code. Below are a few examples of controlling a dropdown from code.

### Enabling / Disabling a dropdown

You can easily change the `enabled` state of a dropdown at runtime.

```javascript
function disableDropdown(){
	elements.myDropdown.enabled = false;
}
```

### Hiding/Showing a dropdown

You can easily change the `visible` state of a dropdown at runtime.

```javascript
function hideDropdown(){
	elements.myDropdown.visible = false;
}
```

## Calling dropdown API Methods

Like most components, a dropdown has API methods which can be called from code. Below is an example of common API calls.

### Add item in the dropdown menu

You can easily give keyboard focus to a dropdown using the [`addMenuItem`](/reference/servoyextensions/ui-components/buttons-and-text/drop-down#addmenuitem) method.

```javascript
function focusButton(){
	elements.myButton.addMenuItem();
}
```

### Add CSS Style Class (Change this to match your component: )

You can easily add a style class to a dropdown using the `addStyleClass` method.

```javascript
function AddStyleClassBadge(){
	elements.myDropdown.addStyleClass('mycssclass');
}
```

## Related Articles

The following articles are recommended for additional reading:

* [Dropdown Reference Documentation](/reference/servoyextensions/ui-components/buttons-and-text/drop-down)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Image

Guide for using Image component in your applications

## Overview

This guide will show how to use the image component in your applications. The image component can be used for a variety of purposes, such as displaying logos, icons, product images, and other graphics. It can also be used to display dynamically generated images, such as charts or graphs. Overall, the image component is a simple but essential component in Servoy for displaying visual content on forms.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=image).

## Get Started

## Modifying the image container at Design-Time

Image, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the image in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

### Setting the Tooltip message

Image, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the image

The image can be selected from the ones pre-loaded in the media folder of the application or related to a media field of a database Just select the desired field or image in the media field of the property editor of the image component.

Note: Make sure that the image file or the URL you specify is accessible and correctly formatted. Additionally, consider using relative paths or dynamically retrieving the image source from a database or other data source for more flexibility.

### Styling

Like all components, a Image can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

## Handling Events

Like most components, Image have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a Image is the `onAction` event, which is triggered when the Image is clicked or the user hits the `Enter` key while the Image has focus.

To Handle the event, double-click the value for the `onAction` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the button's `onAction` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"A74C281C-00AA-46AA-BB38-500C937F2D1A"}
 */
function onAction(event) {
	// Enter custom code
}
```

{% hint style="info" %}
See the [Image reference](/reference/servoyextensions/ui-components/buttons-and-text/image) for comprehensive list of [all events](/reference/servoyextensions/ui-components/buttons-and-text/image#events)
{% endhint %}

## Modifying Image at Runtime

Image, like many components, can be modified at runtime through code. Below are a few examples of controlling a image from code.

### Enabling / Disabling an image

You can easily change the `enabled` state of a image at runtime. Enabling the image component will allow to import or export an image during runtime. If the image component is enabled buttons for import and export images will be shown

```javascript
function disableButton(){
	elements.myImage.enabled = false;
}
```

### Hiding/Showing an image

You can easily change the `visible` state of the image component at runtime.

```javascript
function hideButton(){
	elements.myImage.visible = false;
}
```

## Calling Image API Methods

Like most components, a Image has API methods which can be called from code. Below is an example of common API calls.

### Give Keyboard Focus

You can easily give keyboard focus to a image using the `requestFocus` method.

```javascript
function focusButton(){
	elements.myImage.requestFocus();
}
```

### Add CSS Style Class

You can easily add a style class to a image using the `addStyleClass` method.

```javascript
function AddStyleClassBadge(){
	elements.myImage.addStyleClass('mycssclass');
}
```

## Related Articles

The following articles are recommended for additional reading:

* [Image Reference Documentation](/reference/servoyextensions/ui-components/buttons-and-text/image)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Label

Guide for using labels in your applications

This guide will show how to use labels in your applications. See how easy it is to drag and drop labels onto your forms to show different types of information. Labels can be modified, styled, and even changed at runtime.

To see a live sample of the Label component you can go [here](https://samples-prod.demo.servoy-cloud.eu/solution/components?a=label).

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Get Started

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Label component from the Pallet onto the form

<figure><img src="/files/AU3KLdpBxQDELhDqpQls" alt=""><figcaption><p>Add Label</p></figcaption></figure>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Label at Design-Time

Labels, like all components, have properties that can be modified at design time to set the appearance and behavior of the component. Select the label in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design time.

{% hint style="info" %}
See the reference docs for [Label](/reference/servoyextensions/ui-components/buttons-and-text/label) for a complete list of its [properties](/reference/servoyextensions/ui-components/buttons-and-text/label#properties).
{% endhint %}

### Setting the Text

The text displayed on a label can be modified by setting its [`text`](/reference/servoyextensions/ui-components/buttons-and-text/label#text) property, it can be entered directly on the component by double-clicking it or using the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

The label text can be plain text, a locale-translated value when using [i18n](/reference/servoy-developer/solution-explorer/resources/i18n), HTML markup, or dynamic content when tags are used to display values from dataproviders like [Table Columns](/guides/develop/application-design/data-modeling/databases/tables/columns), [Calculations](/guides/develop/application-design/data-modeling/databases/tables/calculations), [Aggregations](/guides/develop/application-design/data-modeling/databases/tables/aggregations), [Form Variables](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/buttons-and-text/broken-reference/README.md), or standard tags (i.e. %%selectedIndex%% as used in the screenshot above).

The text can also be a combination of all the options above and Servoy will simply calculate the final result before rendering the label.

### Setting a Tooltip message

Labels, like many components, can display tooltip messages when a user hovers their cursor, this can be done by modifying the [`tooltipText`](/reference/servoyextensions/ui-components/buttons-and-text/label#tooltiptext) property using the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

{% hint style="info" %}
The tooltip text, like the label text, can also be dynamic, data-driven, or localized.
{% endhint %}

### Setting an Image / Font-Icon

Many times, a label will be decorated with an image or font icon. To add an image before the text of the label, edit the [`imageStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/label#imagestyleclass) property and choose the style class of the font icon you wish to use. For example, enter a value of `fa fa-user` to get a nice icon that represents a User.

In the same way, there is a [`trailingImageStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/label#trailingimagestyleclass) property to add an image or icon after the text of the label.

For more information, please see the [Font Icon](/guides/develop/application-design/styling-and-themes/font-icons) section of the guide on [Styling and Themes](/guides/develop/application-design/styling-and-themes).

### Styling

Like all components, a Label can be styled using themes, variants, and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the [`styleClass`](/reference/servoyextensions/ui-components/buttons-and-text/label#styleclass) property.

For example, `styleClass="label-info"`

#### Label Variants

If you are using Variants, then you can easily drag and drop variations of your label onto your form.

<figure><img src="/files/9KSdOx4Baf8oa89Jq6id" alt=""><figcaption><p>Add Label Variants to Form</p></figcaption></figure>

## Handling Events

Like most components, Labels have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a label is the `onAction` event, which is triggered when the label is clicked or the user hits the `Enter` key while the label has focus.

To Handle the event, double-click the value for the `onAction` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option to select an existing Method or create a new Method. The method will be called when the label's `onAction` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<figure><img src="/files/MtAIvAGcEksY7J1OZRZV" alt=""><figcaption><p>Create method to handle the onAction event</p></figcaption></figure>

```javascript
/**
 * Click event. 
 * dataTarget parameter is used to identify inner html elements 
 * (by their data-target attribute).
 *
 * @param {JSEvent} event
 * @param {String} dataTarget
 *
 * @properties={typeid:24,uuid:"4FA50A53-70A6-4D14-83B8-EA3E675EBAEB"}
 */
function onAction(event, dataTarget) {
	// TODO Auto-generated method stub
}
```

{% hint style="info" %}
See the [Label reference](/reference/servoyextensions/ui-components/buttons-and-text/label) for a comprehensive list of [all events](/reference/servoyextensions/ui-components/buttons-and-text/label#events)
{% endhint %}

## Modifying a Label at Runtime

Labels, like many components, can be modified at runtime through code. Below are a few examples of controlling a Label from code.

### Enabling / Disabling a label

You can easily change the `enabled` state of a Label at runtime.

```javascript
function disableLabel(){
	elements.myLabel.enabled = false;
}
```

### Hiding/Showing a Label

You can easily change the `visible` state of a Label at runtime.

```javascript
function hideLabel(){
	elements.myLabel.visible = false;
}
```

## Calling Label API Methods

Like most components, a Label has API methods which can be called from code. Below is an example of common API calls.

### Add CSS Style Class

You can easily add a style class to a Label using the [`addStyleClass`](/reference/servoyextensions/ui-components/buttons-and-text/label#api) method.

```javascript
function AddStyleClassLabel(){
	elements.myLabel.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Label reference](/reference/servoyextensions/ui-components/buttons-and-text/label) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/buttons-and-text/label#properties) and [methods](/reference/servoyextensions/ui-components/buttons-and-text/label#api).
{% endhint %}

## Related Articles

The following articles are recommended for additional reading

* [Label Reference Documentation](/reference/servoyextensions/ui-components/buttons-and-text/label)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Grids


# Data Grid

## Overview

Data Grid is a table providing advanced functionalities such as row grouping for the given foundset.

To see a live sample of the component you can go [here](https://samples-prod.demo.servoy-cloud.eu/solution/components?a=datagrid).

This table component is designed to work with large data, potentially infinite, since data is loaded lazily into the table even when grouped; group nodes are loaded lazily with incremental scrolling and children of groups are loaded only when the nodes are expanded; also children of groups are loaded incrementally with scrolling.

{% hint style="warning" %}
**IMPORTANT !**\
Grouping is not yet supported for foundset having multiple primary key columns. To use grouping feature of this component the foundset **MUST** have a single primary key.
{% endhint %}

{% hint style="info" %}
Since all data is loaded lazily on demand, the table doesn't provide any built in aggregation functionality such as count, sum, max, min etc.
{% endhint %}

## Get Started

<div align="left"><figure><img src="/files/grYJ3VyA3kqorylLKhoC" alt=""><figcaption><p>Data Grid</p></figcaption></figure></div>

### Creating a Data Grid

<div align="left"><figure><img src="/files/2MzVGnRm3BQtL6TK64VY" alt=""><figcaption><p>Create a Data Grid</p></figcaption></figure></div>

Here are the steps for creating a Data Grid:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Data Grid**
2. Find **Data Grid** in *Grids* section in the components' pallet
3. Drag and drop the **Data Grid** component in the desired place of the form
4. Set the columns; this can be done via [wizard](#setting-the-columns-via-the-wizard) or in the [properties panel](#setting-the-columns-in-the-properties-panel)
5. Edit other [**Data Grid** properties](/reference/servoyextensions/ui-components/grids/data-grid#properties) and [**Data Grid column** properties](/reference/servoyextensions/ui-components/grids/data-grid#column)

### Setting the Data Source

The Data Source of a Data Grid is set in the [myFoundset](/reference/servoyextensions/ui-components/grids/data-grid#myfoundset) property of the component.

#### Form Foundset

By default, when creating a Data Grid, its foundset is considered to be the form's datasource. In this case, a column's dataprovider can be chosen from the foundset table (table column, calculations, aggregates), form variables, scope variables, as well as tables related to the foundset's one.

#### Related or other foundset

<figure><img src="/files/20vB44DGGtnLwB1wk12y" alt=""><figcaption><p>setting Data Grid foundset</p></figcaption></figure>

Data Grid's foundset can be changed to a Related Foundset, Separate foundset or Named foundsets. In case of a Related Foundset a column's dataprovider can be chosen from the related table (table column, calculations, aggregates), form variables, scope variables.

### Setting the columns (in the properties panel)

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

After dragging the component on the form, the `Property configurator for columns` wizard appears. Close the editor without setting anything here, find the **Data Grid** in the form editor, click it and proceed with the following steps:

1. Add a column. There are 2 ways of adding a column:
   1. Select the [`columns`](/reference/servoyextensions/ui-components/grids/data-grid#columns) property and click the `+` button in order to add a column. Next columns can be added the same way or by clicking the `+` button (`insert a new array item below`) of another column. You can change the columns' order by dragging them into the desired placed inside the **Data Grid** (in the form editor).
   2. Drag and drop `column` component (of an **Data Grid** in *Grids* section in the components' pallet) into the **Data Grid** component (in the form editor)
2. Expand the [`columns`](/reference/servoyextensions/ui-components/grids/data-grid#columns) property to see the list of columns. They are also shown in the **Data Grid** component (in the form editor)
3. In order to edit each column, expand it or click the column name in the **Data Grid** component (in the form editor) and set its [properties](/reference/servoyextensions/ui-components/grids/data-grid#column)

{% hint style="info" %}
**Data Grid column**\
It is necessary to set an unique `id` in the Data Grid **column** properties.\
Example: `orderid`.
{% endhint %}

#### Setting the column data provider

A column's data provider is set in the [dataprovider](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the Data Grid Column.

<figure><img src="/files/SoMvdurMqKZkV4px9N5X" alt=""><figcaption><p>Column dataprovider with Form foundset, Separate foundset or Named foundsets</p></figcaption></figure>

In case the Data Grid foundset is set as Form foundset, Separate foundset or Named foundsets, a column's dataprovider can be selected from the foundset table (table column, calculations, aggregates), form variables, scope variables, as well as tables related to the foundset's one.

<figure><img src="/files/82q81hbJdqYS82z3UaKr" alt=""><figcaption><p>Column dataprovider with Related Foundset</p></figcaption></figure>

In case of a Related Foundset, a column's dataprovider can be selected only from the related table (table column, calculations, aggregates), form variables, scope variables.

#### Setting Column Header

Column Header is set in the [headerTitle](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the Column. It can be edited by entering a value in the property field or by entering the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor). 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#i18n) is also supported.

Examples:

<figure><img src="/files/t2zTXMMjemhOzKnuNGN8" alt=""><figcaption><p>Column headerTitle - plain text</p></figcaption></figure>

<figure><img src="/files/MTqC3mgEBgr0uFul0Rzq" alt=""><figcaption><p>Column headerTitle - i18n</p></figcaption></figure>

### Setting the columns via the wizard

<figure><img src="/files/P0Cet5keoNkli4ZA5Xa1" alt=""><figcaption><p>Property configurator for columns wizard</p></figcaption></figure>

After dragging the component on the form, the [Property configurator for columns](/reference/servoy-developer/object-editors/columns-property-configurator) wizard appears. In order to set the columns using the wizard, you need to do the following steps:

1. Find in the left side of the wizard the column you need: it can be part of a related or unrelated datasource, calculations, form and scope variables, aggregates
2. Click on the column name
3. The selected column will appear on the right side of the wizard, showing some of the column properties:
   1. `COLUMNS` : the column's `dataprovider` or `styleClassDataprovider`
   2. `DATAPROVIDER` : selected if the column id value represents the column's dataprovider
   3. `STYLECLASSDATAPROVIDER`: selected if the column id value represents the column's styleClass dataprovider
   4. `STYLECLASS`: the name of the style class that should be applied to this component.
   5. `HEADERTITLE`: the column's title text ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n#i18n) supported)
   6. `delete` icon : you can remove a tab by clicking the icon
4. Click `OK` button after all columns have been added

When using the wizard, column [id](/reference/servoyextensions/ui-components/grids/data-grid#column) property is automatically set:

* the same as `dataprovider` - in case the `COLUMN` was set as `DATAPROVIDER` at creating stage; example: `orderid`.
* `idX`, where `X` starts from 0 and increments according to the number of columns that are set as `STYLECLASSDATAPROVIDER` at creating stage; example: `id0`, `id1`, `id2`, etc.\
  Column ids can be manually changed by the user in the [column properties](/reference/servoyextensions/ui-components/grids/data-grid#column) panel.

## Grid Height in Responsive Form

It can be used both in responsive forms and absolute forms. If used in responsive mode, its [responsiveHeight](/reference/servoyextensions/ui-components/grids/data-grid#responsiveheight) property must be set in *Properties View* (which is the fixed height it will occupy).

Adding a table in a flex-content layout and setting the table [responsiveHeight](/reference/servoyextensions/ui-components/grids/data-grid#responsiveheight) property to `0`, let the table grow up to 100% height of parent element (see more on flex-layout [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/layout/b12grid/flexbox-layout.md#flexbox-layout)). Used with other containers than flex-content layout in order to grow the table to 100% height, the parent element must have a known height.

## Working with Grid Columns

### Click-Sorting by Column

<figure><img src="/files/vtWploVcvxnshwTT8T7m" alt=""><figcaption><p>Enable Columns sorting</p></figcaption></figure>

In order to have sortable columns by clicking on the column's header, the [enableSorting](/reference/servoyextensions/ui-components/grids/data-grid#enablesorting) property of the Data Grid must be set to `true`, as well as [enableSort](/reference/servoyextensions/ui-components/grids/data-grid#column) property of each desired column.

{% hint style="warning" %}
If [enableSorting](/reference/servoyextensions/ui-components/grids/data-grid#enablesorting) property of the Data Grid is set to `false`, then none of the columns will be sortable, even if their [enableSort](/reference/servoyextensions/ui-components/grids/data-grid#column) property is set to `true`.
{% endhint %}

### Reordering Columns

In order to enable moving of columns, the [enableColumnMove](/reference/servoyextensions/ui-components/grids/data-grid#enablecolumnmove) property of the Data Grid must be set to `true`.

### Column width and Resizing

#### width

Column's width is set in pixels in the [width](/reference/servoyextensions/ui-components/grids/data-grid#column) property of each column. This property is applied when [columnsAutoSizing](/reference/servoyextensions/ui-components/grids/data-grid#columnsautosizing) property of the Data Grid must be set to `NONE`.

#### enableColumnResize

<figure><img src="/files/ztchfg4zGieDXa9tNZ0s" alt=""><figcaption><p>Enable Columns resizing</p></figcaption></figure>

In order to allow the user to resize columns, the [enableColumnResize](/reference/servoyextensions/ui-components/grids/data-grid#enablecolumnresize) property of the Data Grid must be set to `true`, as well as [enableResize](/reference/servoyextensions/ui-components/grids/data-grid#column) property of each desired column.

{% hint style="warning" %}
If [enableColumnResize](/reference/servoyextensions/ui-components/grids/data-grid#enablecolumnresize) property of the Data Grid is set to `false`, then none of the columns will be sortable, even if their [enableResize](/reference/servoyextensions/ui-components/grids/data-grid#column) property is set to `true`.
{% endhint %}

#### min-width

In order to set the minimum width that a column can have, the value must be specified in `min-width` property of each desired column.

{% hint style="warning" %}
The `min-width` property of a column will be taken into consideration if [enableColumnResize](/reference/servoyextensions/ui-components/grids/data-grid#enablecolumnresize) property of the Data Grid is set to `true` and the column's [enableResize](/reference/servoyextensions/ui-components/grids/data-grid#column) property is set to `true`, as well.
{% endhint %}

#### max-width

In order to set the minimum width that a column can have, the value must be specified in [max-width](/reference/servoyextensions/ui-components/grids/data-grid#column) property of each desired column.

{% hint style="warning" %}
The [max-width](/reference/servoyextensions/ui-components/grids/data-grid#column) property of a column will be taken into consideration if [enableColumnResize](/reference/servoyextensions/ui-components/grids/data-grid#enablecolumnresize) property of the Data Grid is set to `true` and the column's [enableResize](/reference/servoyextensions/ui-components/grids/data-grid#column) property is set to `true`, as well.
{% endhint %}

#### columnsAutoSizing

Auto sizing for columns can be set in [columnsAutoSizing](/reference/servoyextensions/ui-components/grids/data-grid#columnsautosizing) property of the Data Grid and has the following options:

* `SIZE_COLUMNS_TO_FIT`: makes the currently visible columns fit the screen
* `AUTO_SIZE`: the grid will work out the best width to fit the contents of the 'visible' cells in the column
* `NONE`:\` no auto sizing action performed

#### continuousColumnsAutoSizing

Apply 'columnsAutoSizing' whenever columns width are changed, [continuousColumnsAutoSizing](/reference/servoyextensions/ui-components/grids/data-grid#continuouscolumnsautosizing) property of the Data Grid set to `true`.

#### Setting column Format

Columns' Format can be set in [Format](/reference/servoyextensions/ui-components/grids/data-grid#column) property of each column. Depending on the type of each dataprovider, this will be done via the format editors for [date](/reference/servoy-developer/object-editors/date-format-editor), [text](/reference/servoy-developer/object-editors/text-format-editor), [integer/number](/reference/servoy-developer/object-editors/number-format-editor).

Example:

Focusing on the `country` column of the following Data Grid, without having any Format:

<figure><img src="/files/vgFNyOn7izf8f58p12MH" alt=""><figcaption><p>`country` column with no Format</p></figcaption></figure>

If the countries' names need to be all upper case, then we apply a Format to the `country` column of the Data Grid:

<figure><img src="/files/MqyP92VMcmqmlAZ8mX77" alt=""><figcaption><p>set `country` column Format</p></figcaption></figure>

Here is how it looks after the Format has been set:

<figure><img src="/files/2JtErkSF3dcHF6I5t1Yb" alt=""><figcaption><p>`country` column with applied Format</p></figcaption></figure>

## Editing in the Data Grid

<figure><img src="/files/KKmpulZRKxtWXEGyxjJR" alt=""><figcaption><p>Column `editType`</p></figcaption></figure>

Editing in the Data Grid is enabled by selecting an option in the [editType](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the desired column:

* `NONE`: disables column editing
* `TEXTFIELD`: shows a text field where the user can edit the value of the column by typing
* `DATEPICKER`: allows users to enter a date either through text input, or by choosing a date from the calendar
* `COMBOBOX`: shows a popup that enables users to choose a value for the input from a collection
* `TYPEAHEAD`: shows a text field that offers values from a provided value list, filtering the list as the user starts typing
* `FORM`: shows a form
* `CHECKBOX`: shows a checkbox which the user can select / unselect

{% hint style="warning" %} The [readOnly](/reference/servoyextensions/ui-components/grids/data-grid#readonly) property of the Data Grid must be set to `false` in order to have editable columns / cells. {% endhint %}

Example:

* \`

COMBOBOX`\ Select the` COMBOBOX\` option in the [editType](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the desired column and set the [valuelist](/reference/servoyextensions/ui-components/grids/data-grid#column) property:

<figure><img src="/files/sAKVUClxXlDlWTPRiSc2" alt=""><figcaption><p>`COMBOBOX` Column `editType` and Column `valuelist`</p></figcaption></figure>

Here is the result:

<figure><img src="/files/PnFd5j7LxORBosWORAjO" alt=""><figcaption><p>Editable `Discount` column using `COMBOBOX` option</p></figcaption></figure>

### Advanced

#### isEditableDataProvider

Use a Servoy calculation as [isEditableDataprovider](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the desired column to set edit state conditionally to the table cell.

Example: Let's consider the case when `Discount` column need to be editable only for values smaller than `0.20`. In order to get that, [isEditableDataprovider](/reference/servoyextensions/ui-components/grids/data-grid#column) property of `Discount` column has to be set with the calculation name (`increase_discount`):

```javascript
/**
 * @properties={type:-4,typeid:36,uuid:"37BEFEFE-F7BC-4998-8ABE-326AE5391BBF"}
 */
function increase_discount()
{
	if (discount.toFixed(2) < 0.20)
    {return true;}
	else {return false;}
}
```

{% hint style="warning" %}
If the calculation returns `true/false`, then its Returned Type needs to be set as `MEDIA`.\
If the calculation returns `1/0`, then its Returned Type needs to be set as `INTEGER`.
{% endhint %}

#### Custom editors

It is possible to use a form as a custom editor, by setting the [editType](#editing-in-the-data-grid) of a column to `FORM` and `editForm` to the desired form. When a cell will enter edit mode, the form will be shown in a popup and the [onColumnFormEditStarted](/reference/servoyextensions/ui-components/grids/data-grid#oncolumnformeditstarted) handler will be called; this is where you can setup the values displayed in the form. To update the edited cell value with the result of the form editor, the [setFormEditorValue](/reference/servoyextensions/ui-components/grids/data-grid#setformeditorvalue) api function should be used (ex. if you have a save/ok button in the editor, this is the function that you need to call to set the result of the editing). In order to stop the editing and close the form editor popup, the [stopCellEditing](/reference/servoyextensions/ui-components/grids/data-grid#stopcellediting) api should be used.

## Filtering Data

<figure><img src="/files/pbnur0SbHruJG0i1Eemj" alt=""><figcaption><p>Column `filterType`</p></figcaption></figure>

Filtering Columns in the Data Grid is enabled by selecting an option in the [filterType](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the desired column:

* `NONE`: disables column filter
* `TEXT`: displays text related filter options
* `NUMBER`: displays number related filter options
* `DATE`: displays date related filter options
* `VALUELIST`: displays a text field filter option, with the specified valuelist items as suggestions
* `RADIO`: displays filter options with the specified valuelist items as a single choice

Example:

* `TEXT`\
  Select the `TEXT` option in the [filterType](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the desired column.\
  Here is the result:

<div align="left"><figure><img src="/files/AnPwVBB2rgzW2OWJ66rz" alt=""><figcaption><p>Filter `Ship country` column using `TEXT` option</p></figcaption></figure></div>

* `RADIO`\
  Select the `RADIO` option in the [filterType](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the desired column and set the [valuelist](/reference/servoyextensions/ui-components/grids/data-grid#column) property.\
  Here is the result:

<figure><img src="/files/bNFbNMbmwKXR3CW8rud0" alt=""><figcaption><p>Filter `Discount` column using `RADIO` option</p></figcaption></figure>

## Grouping Data

In order to enable grouping data, the [enableRowGroup](/reference/servoyextensions/ui-components/grids/data-grid#column) property of the desired column must be set to `true`.

{% hint style="danger" %}
**IMPORTANT !**\
Grouping is not yet supported for foundset having multiple primary key columns. To use grouping feature of this component the foundset **MUST** have a single primary key.
{% endhint %}

{% hint style="danger" %}
**IMPORTANT !**\
Calculations, Aggregations or form variables SHOULD not be used in group mode and `enableRowGroup` MUST be set to `false`.
{% endhint %}

### Grouping at runtime by the user

The user can change grouping criteria at runtime for the columns that have enabled grouping data.

Example:\
Having enabled grouping data in Servoy developer for `Ship country`, `Ship city`, `Customer ID` and `Order date` columns, here is the behavior at runtime:

<div align="left"><figure><img src="/files/CZqURdkGNb61c196wkYe" alt=""><figcaption><p>Grouping columns at runtime</p></figcaption></figure></div>

### Advanced: Grouping at design time

The table can be grouped on any foundset's dataprovider or related dataprovider by setting the [rowGroupIndex](/reference/servoyextensions/ui-components/grids/data-grid#column) in the column's properties. The grouped columns can be configured at design time and the user can change grouping criteria at runtime if [enableRowGroup](/reference/servoyextensions/ui-components/grids/data-grid#column) column property is `true`.

Example:\
Let's consider the case when columns need to be grouped first by `Ship country` and then by `Ship city`. In order to get that, the following settings need to be done:

* `Ship country` column:
  * [enableRowGroup](/reference/servoyextensions/ui-components/grids/data-grid#column) column property set to `true`
  * [rowGroupIndex](/reference/servoyextensions/ui-components/grids/data-grid#column) column property set to `0`
* `Ship city` column:
  * [enableRowGroup](/reference/servoyextensions/ui-components/grids/data-grid#column) column property set to `true`
  * [rowGroupIndex](/reference/servoyextensions/ui-components/grids/data-grid#column) column property set to `1`

Here is the result at runtime:

<div align="left"><figure><img src="/files/puRmWYk0DCbY5RqBcfoL" alt=""><figcaption><p>Grouping columns at design time</p></figcaption></figure></div>

## Scripting a Data Grid

### Main events

You can find a list of Data Grid **events** [here](/reference/servoyextensions/ui-components/grids/data-grid#events).\
You can find a list of Data Grid **API methods** [here](/reference/servoyextensions/ui-components/grids/data-grid#api).

#### Record selection

When the table is showing plain rows without grouped columns it highlights the selected record in foundset; if the selected record in foundset is changed serverside the table will change the selection to the new record however it won't scroll to the selected record but will remain to it's position.

When the table is grouping one ore more columns instead the record selection is disabled. If you would like to use change the selected record in foundset you can use the [onCellClickEvent](/reference/servoyextensions/ui-components/grids/data-grid#oncellclick) to change record selection on the foundset. Please note that the foundsetIndex param of the [onCellClickEvent](/reference/servoyextensions/ui-components/grids/data-grid#oncellclick) will always be `-1` when there are grouped columns; use the pks of the record object to select the clicked record.

#### onCellClick

This event is called when the mouse is clicked on a row/cell (foundset and column indexes are given). The foundsetindex is always -1 when there are grouped rows.\
Here is an example of how to use the [onCellClick](/reference/servoyextensions/ui-components/grids/data-grid#oncellclick) event of Data Grid in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):\
Let's consider a Data Grid showing `employees` table columns. When clicking on a table cell, the application will show a form containing details of that specific employee record.

```javascript
/**
 * @param {Number} foundsetindex
 * @param {Number} [columnindex]
 * @param {JSRecord} [record]
 * @param {JSEvent} [event]
 *
 * @private
 *
 * @properties={typeid:24,uuid:"9520356E-2893-41D8-97EA-3EC1BD96635B"}
 */
function onCellClick(foundsetindex, columnindex, record, event) {
    forms.employee_details.controller.loadRecords(record.foundset);
    application.showForm('employee_details');
}
```

#### onCellRightClick

This event is called when the right mouse button is clicked on a row/cell (foundset and column indexes are given). The foundsetindex is always -1 when there are grouped rows.\
Here is an example of how to use the [onCellRightClick](/reference/servoyextensions/ui-components/grids/data-grid#oncellrightclick) event of Data Grid in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):\
Let's consider a Data Grid showing `employees` table columns. When right clicking on a table cell, the application will show a pop up form containing an employees card menu of that specific employee record.

```javascript
/**
 * @param {Number} foundsetindex
 * @param {Number} [columnindex]
 * @param {JSRecord} [record]
 * @param {JSEvent} [event]
 *
 * @private
 *
 * @properties={typeid:24,uuid:"620BB9D4-7585-4B4D-A5E5-4E84BE4FC7E6"}
 */
function onCellRightClick(foundsetindex, columnindex, record, event) {
	var elementX = event.getX() - 210;
	var elementY = event.getY() + 20;
	plugins.window.showFormPopup(null, forms.employeeCardMenu, foundset.getSelectedRecord(), null, 222, 184, elementX, elementY);
}
```

### Add a column

Here is an example of how to programmatically add a column in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [newColumn](/reference/servoyextensions/ui-components/grids/data-grid#newcolumn) API:

```javascript
/**
 * @param {Boolean} firstShow form is shown first time after load
 * @param {JSEvent} event the event that triggered the action
 *
 * @properties={typeid:24,uuid:"B6E9D07A-8C72-452A-B282-F394DD6B3D5F"}
 */
function onShow(firstShow, event) {
	var column = elements.datagrid_orders.newColumn('shipaddress');
	column.headerTitle = "Ship address";
}
```

### Remove a column

Here is an example of how to programmatically remove a column in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [removeColumn](/reference/servoyextensions/ui-components/grids/data-grid#removecolumn) API:

```javascript
/**
 * @param {Boolean} firstShow form is shown first time after load
 * @param {JSEvent} event the event that triggered the action
 *
 * @properties={typeid:24,uuid:"B6E9D07A-8C72-452A-B282-F394DD6B3D5F"}
 */
function onShow(firstShow, event) {
	var index = elements.datagrid_orders.getColumnIndex("requireddate");
	elements.datagrid_orders.removeColumn(index);
}
```

## Advanced

### Data changes and Data broadcast

When the table is showing plain rows without grouped columns it updates spontaneously its rows at any data change which affect the rows visible in the table viewport; as common tables in Servoy the table component receive foundset updates which may be originated from a foundset update within the client itself or from a data broadcast update; it always presents the latest data to the user when the columns are not grouped.

This is not the case when the table is grouping one ore more columns; a data update may affect how the groups are displayed; a new group node or sub-node may be created or even removed after a data update. Adding and removing groups on the fly will result on a bad user experience therefore the table component doesn't react proactively to data updates.

The table allows the user to ask for latest data with a "Refresh Data" action; the refresh button will show up to the top-right corner of the table when there are grouped columns.

When the table receives any data change (either a record insert, a record delete or a record update for any of the columns in table) which affect the records in it's viewport, the table will notify the user highlighting the "Refresh Data" action; by default the refresh button is colored as orange to notify the user of a pending data change. You can style in CSS the refresh button when highlighted with the `.ag-table-info-notify` style Class.

Notice that, for obvious perfomance reasons, the table components won't listen for data changes on the whole foundset's table (and related foundset table) but only for the data in table's viewport; the implication of this is that if a table record, which is not in viewport, is being updated (for instance the client receives a data broadcast from another client) the table component won't be notified even if the update may result in a new group node within the table viewport.

If you would like to notify the table component of ANY data change, you can use the notifyDataChange api of the component. The [notifyDataChange](/reference/servoyextensions/ui-components/grids/data-grid#notifydatachange) api is best use in conjunction with the onDataBroadcast event of Servoy to notify the table of any data change from other clients and with the onAfterRecordInsert, onAfterRecordUpdate, onAfterRecordDelete events to notify the table of any data changes within the client; the client doesn't receive a data broadcast notification for it's own changes, therefore if the foundset's record (or the related foundset's record if related dataproviders are used in columns), which are not in the viewport, are changed in background you can rely on the onAfterRecordInsert/Update/Delete, or proactively notify the table component in your business logic. Please note that it's not necessary to notify the table component is the component is not visible; the component will always present the latest data when rendered again.


# Power Grid

## Overview

Power Grid is a feature-rich table component that offers advanced functionalities such as row grouping, pivoting, and dynamic row rendering. It allows users to load data from a dataset, customize the appearance of rows and cells, and use custom cell editors.

Unlike Data Grid, which load its data from foundsets, the Power Grid load its data from a dataset. The key difference is between dataset and foundset is that the former is cached in-memory and the latter is loaded dynamically from a backend datasource.

{% hint style="info" %}
The main reason of using Power Grid instead of Data Grid is that the Power Grid can show aggregates and do pivot mode.
{% endhint %}

## Get Started

<div align="left"><figure><img src="/files/MOaZAFT4vcSFzNPQ7y8I" alt=""><figcaption><p>Power Grid</p></figcaption></figure></div>

### Creating a Power Grid

<div align="left"><figure><img src="/files/0X4VV0buaC7e23I54LR9" alt=""><figcaption><p>Create a Power Grid</p></figcaption></figure></div>

Here are the steps for creating a Power Grid:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Power Grid**
2. Find **Power Grid** in *Grids* section in the components' pallet
3. Drag and drop the **Power Grid** component in the desired place of the form
4. [Set the columns](#setting-the-columns)
5. Edit other [**Power Grid** properties](/reference/servoyextensions/ui-components/grids/power-grid#properties) and [**Power Grid column** properties](/reference/servoyextensions/ui-components/grids/power-grid#column)

{% hint style="danger" %}
**IMPORTANT!**\
In order to fill data to the table, [renderData](/reference/servoyextensions/ui-components/grids/power-grid#renderdata-dataset-pks) API menthod **must** be called, with a dataset, that should have columns defined. The name of the columns from the dataset will be used to match the defined columns on the table, based on the column's dataprovider.

```javascript
function onShow(firstShow, event) {
	var ds = databaseManager.convertToDataSet(foundset, ['orderid', 'shipcountry', 'orderdate']);
	elements.powergrid_orders.renderData(ds);
}
```

{% endhint %}

### Setting the Data Source

By default, when creating a Power Grid, its foundset is considered to be the form's datasource.

### Setting the columns

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

After dragging the component on the form, find the **Power Grid** in the form editor, click it and proceed with the following steps:

1. Add a column. There are 2 ways of adding a column:
   1. Select the [`columns`](/reference/servoyextensions/ui-components/grids/power-grid#columns) property and click the `+` button in order to add a column. Next columns can be added the same way or by clicking the `+` button (`insert a new array item below`) of another column. You can change the columns' order by dragging them into the desired placed inside the **Power Grid** (in the form editor).
   2. Drag and drop `column` component (of an **Power Grid** in *Grids* section in the components' pallet) into the **Power Grid** component (in the form editor)
2. Expand the [`columns`](/reference/servoyextensions/ui-components/grids/power-grid#columns) property to see the list of columns. They are also shown in the **Power Grid** component (in the form editor)
3. In order to edit each column, expand it or click the column name in the **Power Grid** component (in the form editor) and set its [properties](/reference/servoyextensions/ui-components/grids/power-grid#column)

{% hint style="info" %}
**Power Grid column**\
It is necessary to set an unique `id` in the Power Grid **column** properties.\
Example: `orderid`
{% endhint %}

#### Setting the column data provider

A column's data provider is set in the [dataprovider](/reference/servoyextensions/ui-components/grids/power-grid#column) property of the Power Grid Column.

A column's dataprovider can be one of the foundset's column from the dataset used in [renderData](/reference/servoyextensions/ui-components/grids/power-grid#renderdata-dataset-pks) API method of the component.

#### Setting Column Header

Column Header is set in the [headerTitle](/reference/servoyextensions/ui-components/grids/power-grid#column) property of the Column. It can be edited by entering a value in the property field or by entering the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor). 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#i18n) is also supported.

Examples:

<figure><img src="/files/t2zTXMMjemhOzKnuNGN8" alt=""><figcaption><p>Column headerTitle - plain text</p></figcaption></figure>

<figure><img src="/files/MTqC3mgEBgr0uFul0Rzq" alt=""><figcaption><p>Column headerTitle - i18n</p></figcaption></figure>

## Grid Height in Responsive Form

It can be used both in responsive forms and absolute forms. If used in responsive mode, its [responsiveHeight](/reference/servoyextensions/ui-components/grids/power-grid#responsiveheight) property must be set in *Properties View* (which is the fixed height it will occupy).

Adding a table in a flex-content layout and setting the table [responsiveHeight](/reference/servoyextensions/ui-components/grids/power-grid#responsiveheight) property to `0`, let the table grow up to 100% height of parent element (see more on flex-layout [here](/guides/develop/application-design/forms/layout-management/home/flexbox#flexbox-layout)). Used with other containers than flex-content layout in order to grow the table to 100% height, the parent element must have a known height.

## Working with Grid Columns

### Click-Sorting by Column

<figure><img src="/files/40cbzX8RGr4QRK1cP3YU" alt=""><figcaption><p>Enable Columns sorting</p></figcaption></figure>

In order to have sortable columns by clicking on the column's header, the [enableSorting](/reference/servoyextensions/ui-components/grids/power-grid#enablesorting) property of the Power Grid must be set to `true`, as well as [enableSort](/reference/servoyextensions/ui-components/grids/power-grid#column) property of each desired column.

{% hint style="warning" %}
If [enableSorting](/reference/servoyextensions/ui-components/grids/power-grid#enablesorting) property of the Power Grid is set to `false`, then none of the columns will be sortable, even if their [enableSort](/reference/servoyextensions/ui-components/grids/power-grid#column) property is set to `true`.
{% endhint %}

### Column width and Resizing

#### width

Column's width is set in the [width](/reference/servoyextensions/ui-components/grids/power-grid#column) property of each column. This property is applied when [columnsAutoSizing](/reference/servoyextensions/ui-components/grids/power-grid#columnsautosizing) property of the Power Grid must be set to `NONE`.

#### enableColumnResize

<figure><img src="/files/QNjCujLbTjHagXqnFJnB" alt=""><figcaption><p>Enable Columns resizing</p></figcaption></figure>

In order to allow the user to resize columns, the [enableColumnResize](/reference/servoyextensions/ui-components/grids/power-grid#enablecolumnresize) property of the Power Grid must be set to `true`, as well as [enableResize](/reference/servoyextensions/ui-components/grids/power-grid#column) property of each desired column.

{% hint style="warning" %}
If [enableColumnResize](/reference/servoyextensions/ui-components/grids/power-grid#enablecolumnresize) property of the Power Grid is set to `false`, then none of the columns will be sortable, even if their [enableResize](/reference/servoyextensions/ui-components/grids/power-grid#column) property is set to `true`.
{% endhint %}

#### minWidth

In order to set the minimum width that a column can have, the value must be specified in `minWidth` property of each desired column.

{% hint style="warning" %}
The `minWidth` property of a column will be taken into consideration if [enableColumnResize](/reference/servoyextensions/ui-components/grids/power-grid#enablecolumnresize) property of the Power Grid is set to `true` and the column's [enableResize](/reference/servoyextensions/ui-components/grids/power-grid#column) property is set to `true`, as well.
{% endhint %}

#### maxWidth

In order to set the minimum width that a column can have, the value must be specified in [maxWidth](/reference/servoyextensions/ui-components/grids/power-grid#column) property of each desired column.

{% hint style="warning" %}
The [maxWidth](/reference/servoyextensions/ui-components/grids/power-grid#column) property of a column will be taken into consideration if [enableColumnResize](/reference/servoyextensions/ui-components/grids/power-grid#enablecolumnresize) property of the Power Grid is set to `true` and the column's [enableResize](/reference/servoyextensions/ui-components/grids/power-grid#column) property is set to `true`, as well.
{% endhint %}

#### columnsAutoSizing

Auto sizing for columns can be set in [columnsAutoSizing](/reference/servoyextensions/ui-components/grids/power-grid#columnsautosizing) property of the Power Grid and has the following options:

* `SIZE_COLUMNS_TO_FIT`: makes the currently visible columns fit the screen
* `AUTO_SIZE`: the grid will work out the best width to fit the contents of the 'visible' cells in the column
* `NONE`:\` no auto sizing action performed

#### continuousColumnsAutoSizing

Apply 'columnsAutoSizing' whenever columns width are changed, [continuousColumnsAutoSizing](/reference/servoyextensions/ui-components/grids/power-grid#continuouscolumnsautosizing) property of the Power Grid set to `true`.

#### Setting column Format

Columns' Format can be set in [Format](/reference/servoyextensions/ui-components/grids/power-grid#column) property of each column.\
The [formatType](/reference/servoyextensions/ui-components/grids/power-grid#column) column property must be set before defining the column Format.\
Depending on the option selected for [formatType](/reference/servoyextensions/ui-components/grids/power-grid#column), the column Format will be set via the format editors for [DATETIME](/reference/servoy-developer/object-editors/date-format-editor), [TEXT](/reference/servoy-developer/object-editors/text-format-editor), [NUMBER](/reference/servoy-developer/object-editors/number-format-editor).

## Editing in the Power Grid

<figure><img src="/files/KKmpulZRKxtWXEGyxjJR" alt=""><figcaption><p>Column `editType`</p></figcaption></figure>

Editing in the Power Grid is enabled by selecting an option in the [editType](/reference/servoyextensions/ui-components/grids/power-grid#column) property of the desired column:

* `NONE`: disables column editing
* `TEXTFIELD`: shows a text field where the user can edit the value of the column by typing
* `DATEPICKER`: allows users to enter a date either through text input, or by choosing a date from the calendar
* `COMBOBOX`: shows a popup that enables users to choose a value for the input from a collection
* `TYPEAHEAD`: shows a text field that offers values from a provided value list, filtering the list as the user starts typing
* `FORM`: shows a form
* `CHECKBOX`: shows a checkbox which the user can select / unselect

{% hint style="warning" %} The [readOnly](/reference/servoyextensions/ui-components/grids/power-grid#readonly) property of the Power Grid must be set to `false` in order to have editable columns / cells. {% endhint %}

### Advanced

#### Custom editors

It is possible to use a form as a custom editor, by setting the [editType](#editing-in-the-power-grid) of a column to `FORM` and `editForm` to the desired form. When a cell will enter edit mode, the form will be shown in a popup and the [onColumnFormEditStarted](/reference/servoyextensions/ui-components/grids/power-grid#oncolumnformeditstarted) handler will be called; this is where you can setup the values displayed in the form. To update the edited cell value with the result of the form editor, the [setFormEditorValue](/reference/servoyextensions/ui-components/grids/power-grid#setformeditorvalue) api function should be used (ex. if you have a save/ok button in the editor, this is the function that you need to call to set the result of the editing). In order to stop the editing and close the form editor popup, the [stopCellEditing](/reference/servoyextensions/ui-components/grids/power-grid#stopcellediting) API should be used.

## Filtering Data

<figure><img src="/files/pbnur0SbHruJG0i1Eemj" alt=""><figcaption><p>Column `filterType`</p></figcaption></figure>

Filtering Columns in the Power Grid is enabled by selecting an option in the [filterType](/reference/servoyextensions/ui-components/grids/power-grid#column) property of the desired column:

* `NONE`: disables column filter
* `TEXT`: displays text related filter options
* `NUMBER`: displays number related filter options
* `DATE`: displays date related filter options
* `VALUELIST`: displays a text field filter option, with the specified valuelist items as suggestions
* `RADIO`: displays filter options with the specified valuelist items as a single choice

## Grouping Data

In order to enable grouping data, the [enableRowGroup](/reference/servoyextensions/ui-components/grids/power-grid#column) property of the desired column must be set to `true`.

### Grouping at runtime by the user

The user can change grouping criteria at runtime for the columns that have enabled grouping data.

### Advanced: Grouping at design time

The table can be grouped on any column by setting the [rowGroupIndex](/reference/servoyextensions/ui-components/grids/power-grid#column) in the column's properties. The grouped columns can be configured at design time and the user can change grouping criteria at runtime if [enableRowGroup](/reference/servoyextensions/ui-components/grids/power-grid#column) column property is `true`.

Example:\
Let's consider the case when columns need to be grouped first by `column A` and then by `column B`. In order to get that, the following settings need to be done:

* `column A` column:
  * [enableRowGroup](/reference/servoyextensions/ui-components/grids/power-grid#column) column property set to `true`
  * [rowGroupIndex](/reference/servoyextensions/ui-components/grids/power-grid#column) column property set to `0`
* `column B` column:
  * [enableRowGroup](/reference/servoyextensions/ui-components/grids/power-grid#column) column property set to `true`
  * [rowGroupIndex](/reference/servoyextensions/ui-components/grids/power-grid#column) column property set to `1`

## Pivoting Data

Pivoting lets you convert column values into separate columns.

Pivoting allows you to transform the values of a column into separate columns. For instance, you can pivot on "Country" column to create columns for "Ireland," "United Kingdom," "USA," and so forth.

However, pivoting only becomes meaningful when combined with **aggregation**. If you pivot a column, you must have at least one active aggregation (value) for the configuration to make sense. For example, when pivoting by country, you must provide a measurement, such as "gold medals per country."

Activating pivot mode is necessary for pivoting to take effect. When the grid is in pivot mode, the following occurs:

* only columns with Group, Pivot, or Value activated will be included in the grid.
* only aggregated rows will be displayed; the lowest level rowData will not appear.

If pivot mode is deactivated, adding or removing pivot columns will have no impact.

In order to enable pivoting data, the following steps need to be made:

<div align="left"><figure><img src="/files/hp5uRQLDQwS8YRrq1ssu" alt=""><figcaption><p>Power Grid - column setting for pivot mode</p></figcaption></figure></div>

1. [enablePivot](/reference/servoyextensions/ui-components/grids/power-grid#column) column property must be set to `true`
2. set the aggregation in [aggFunc](/reference/servoyextensions/ui-components/grids/power-grid#column) column property. Select an option from the menu:
   * sum: adds up the values of a specific field in a dataset
   * min: the smallest value in a dataset
   * max: the largest value in a dataset
   * count: counts the number of records or occurrences in a dataset
   * avg: calculates the mean value of a field in a dataset
   * first: the first occurrence of a value in a dataset
   * last: the last occurrence of a value in a dataset
3. the Power Grid must have at least one other column to be grouped by; in order to do that, set [enableRowGroup](/reference/servoyextensions/ui-components/grids/power-grid#column) column property to `true` and set that column's [rowGroupIndex](/reference/servoyextensions/ui-components/grids/power-grid#column) property to `0`.

You can find more information about **pivoting** [here](https://www.ag-grid.com/javascript-data-grid/pivoting/).

Example:\
Below is a straightforward pivot example performed on the "Sport" column, utilizing the "Gold," "Silver," and "Bronze" columns as values.\
The "Date" and "Year" columns, despite being defined as such, are not visible in the grid. This is because they lack any grouping, pivoting, or value association.

<div align="left"><figure><img src="/files/HNZkmWUL5s2zcB2vNgPh" alt=""><figcaption><p>Power Grid pivot example</p></figcaption></figure></div>

## Scripting a Power Grid

### Main events

You can find a list of Power Grid **events** [here](/reference/servoyextensions/ui-components/grids/power-grid#events).\
You can find a list of Power Grid **API methods** [here](/reference/servoyextensions/ui-components/grids/power-grid#api).

#### onCellClick

This event is called when the mouse is clicked on a row/cell. Here is an example of how to use the [onCellClick](/reference/servoyextensions/ui-components/grids/power-grid#oncellclick) event of Power Grid in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):\
Let's consider a Power Grid showing `employees` table columns. When clicking on a table cell, the application will show a form containing details of that specific employee record.

```javascript
/**
 * @param rowData
 * @param {String} [columnId]
 * @param [cellData]
 * @param {JSEvent} [event]
 *
 * @private
 *
 * @properties={typeid:24,uuid:"9520356E-2893-41D8-97EA-3EC1BD96635B"}
 */
function onCellClick(rowData, columnId, cellData, event) {
    forms.employee_details.controller.loadRecords(record.foundset);
    application.showForm('employee_details');
}
```

#### onCellRightClick

This event is called when the right mouse button is clicked on a row/cell.\
Here is an example of how to use the [onCellRightClick](/reference/servoyextensions/ui-components/grids/power-grid#oncellrightclick) event of Power Grid in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):\
Let's consider a Power Grid showing `employees` table columns. When right clicking on a table cell, the application will show a pop up form containing an employees card menu of that specific employee record.

```javascript
/**
 * @param rowData
 * @param {String} [columnId]
 * @param [cellData]
 * @param {JSEvent} [event]
 *
 * @private
 *
 * @properties={typeid:24,uuid:"620BB9D4-7585-4B4D-A5E5-4E84BE4FC7E6"}
 */
function onCellRightClick(rowData, columnId, cellData, event) {
	var elementX = event.getX() - 210;
	var elementY = event.getY() + 20;
	plugins.window.showFormPopup(null, forms.employeeCardMenu, foundset.getSelectedRecord(), null, 222, 184, elementX, elementY);
}
```

### Add a column

Here is an example of how to programmatically add a column in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [newColumn](/reference/servoyextensions/ui-components/grids/power-grid#newcolumn) API:

```javascript
/**
 * @param {Boolean} firstShow form is shown first time after load
 * @param {JSEvent} event the event that triggered the action
 *
 * @properties={typeid:24,uuid:"B6E9D07A-8C72-452A-B282-F394DD6B3D5F"}
 */
function onShow(firstShow, event) {
	var column = elements.powergrid_orders.newColumn('shipaddress');
	column.headerTitle = "Ship address";
}
```

### Remove a column

Here is an example of how to programmatically remove a column in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [deleteColumn](/reference/servoyextensions/ui-components/grids/power-grid#deletecolumn) API:

```javascript
/**
 * @param {Boolean} firstShow form is shown first time after load
 * @param {JSEvent} event the event that triggered the action
 *
 * @properties={typeid:24,uuid:"B6E9D07A-8C72-452A-B282-F394DD6B3D5F"}
 */
function onShow(firstShow, event) {
	elements.powergrid_orders.deleteColumn('shipaddress');
}
```

### Dynamic row rendering

Is it possible to dynamically render and style the rows depending on their content using the Power Grid `*Func` properties such as ['rowStyleClassFunc'](/reference/servoyextensions/ui-components/grids/power-grid#rowstyleclassfunc), [groupRowRendererFunc](/reference/servoyextensions/ui-components/grids/power-grid#grouprowrendererfunc) table properties and the column's properties [cellRendererFunc](/reference/servoyextensions/ui-components/grids/power-grid#column), [cellStyleClassFunc](/reference/servoyextensions/ui-components/grids/power-grid#column).\
A common use case is to color a cell or a whole row differently depending of the row data.

The `*Func` in Power Grid are functions defined as `String` and evaluated client-side (in the Browser itself) by the Power Grid allowing to customize rows dinamically.

Example for the column's [cellStyleClassFunc](/reference/servoyextensions/ui-components/grids/power-grid#column); a different styleClass is returned depending on the columnData.

```javascript
(function cellStyleClassFuncStatusColor(rowIndex, rowData, field, columnData, event) {
   if (!columnData) {
      return "";
   }
   if (columnData) {
      switch (columnData) {
      case "New Order":
         return "label-tag text-info";
         break;
      case "Completed":
         return "label-tag text-success";
         break;
      case "Planned":
         return "label-tag text-info";
         break;
      default:
         break;
      }
   }
   return "label-tag text-info";
})
```


# Table

## Overview

Servoy Extra Table is a **lightweight read-only** table. It can be used both in responsive forms and absolute forms. If used in responsive mode, its 'responsiveHeight' property must be set in *Properties View* (which is the fixed height it will occupy).

It has typical table features, (fixed) table header, formats, styling, paging, column resize, column sort, valuelist support (for translating a real value to a display value). The model and API can be seen in Servoy Developer.

The purpose of this table component is to be able to **show large numbers of rows with acceptable or fast response times**.

The table is highly configurable from *Properties View* - in Developer. It can be configured to do paging and/or incremental scrolling.

## Get Started

<div align="left"><figure><img src="/files/I67KsyS4TYe20qmLZenN" alt=""><figcaption><p>Table</p></figcaption></figure></div>

### Creating a Table

Here are the steps for creating a Table:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Table**
2. Find **Table** in *Grids* section in the components' pallet
3. Drag and drop the **Table** component in the desired place of the form
4. Set the columns; this can be done via [wizard](#setting-the-columns-via-the-wizard) or in the [properties panel](#setting-the-columns-in-the-properties-panel)
5. Edit other [**Table** properties](/reference/servoyextensions/ui-components/grids/table#properties) and [**Table column** properties](/reference/servoyextensions/ui-components/grids/table#column)

## Setting the Data Source

The Data Source of a Table is set in the [foundset](/reference/servoyextensions/ui-components/grids/table#foundset) property of the component.

### Form Foundset

By default, when creating a Table, its foundset is considered to be the form's datasource. In this case, a column's dataprovider can be chosen from the foundset table (table column, calculations, aggregates), form variables, scope variables, as well as tables related to the foundset's one.

### Related or other foundset

<figure><img src="/files/20vB44DGGtnLwB1wk12y" alt=""><figcaption><p>setting Table foundset</p></figcaption></figure>

Table's foundset can be changed to a Related Foundset, Separate foundset or Named foundsets. In case of a Related Foundset a column's dataprovider can be chosen from the related table (table column, calculations, aggregates), form variables, scope variables.

### Setting the columns (in the properties panel)

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

After dragging the component on the form, the `Property configurator for columns` wizard appears. Close the editor without setting anything here, find the **Table** in the form editor, click it and proceed with the following steps:

1. Add a column. There are 2 ways of adding a column:
   1. Select the [`columns`](/reference/servoyextensions/ui-components/grids/table#columns) property and click the `+` button in order to add a column. Next columns can be added the same way or by clicking the `+` button (`insert a new array item below`) of another column. You can change the columns' order by dragging them into the desired placed inside the **Table** (in the form editor).
   2. Drag and drop `column` component (of an **Table** in *Grids* section in the components' pallet) into the **Table** component (in the form editor)
2. Expand the [`columns`](/reference/servoyextensions/ui-components/grids/table#columns) property to see the list of columns. They are also shown in the **Table** component (in the form editor)
3. In order to edit each column, expand it or click the column name in the **Table** component (in the form editor) and set its [properties](/reference/servoyextensions/ui-components/grids/table#column)

{% hint style="info" %}
**Table column**\
It is necessary to set an unique `id` in the Table **column** properties.\
Example: `orderid`.
{% endhint %}

#### Setting the column data provider

A column's data provider is set in the [dataprovider](/reference/servoyextensions/ui-components/grids/table#column) property of the Table Column.

<figure><img src="/files/SoMvdurMqKZkV4px9N5X" alt=""><figcaption><p>Column dataprovider with Form foundset, Separate foundset or Named foundsets</p></figcaption></figure>

In case the Table foundset is set as Form foundset, Separate foundset or Named foundsets, a column's dataprovider can be selected from the foundset table (table column, calculations, aggregates), form variables, scope variables, as well as tables related to the foundset's one.

<figure><img src="/files/82q81hbJdqYS82z3UaKr" alt=""><figcaption><p>Column dataprovider with Related Foundset</p></figcaption></figure>

In case of a Related Foundset, a column's dataprovider can be selected only from the related table (table column, calculations, aggregates), form variables, scope variables.

#### Setting Column Header

Column Header is set in the [headerText](/reference/servoyextensions/ui-components/grids/table#column) property of the Column. It can be edited by entering a value in the property field or by entering the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor). 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#i18n) is also supported.

Examples:

<figure><img src="/files/t2zTXMMjemhOzKnuNGN8" alt=""><figcaption><p>Column headerText - plain text</p></figcaption></figure>

<figure><img src="/files/MTqC3mgEBgr0uFul0Rzq" alt=""><figcaption><p>Column headerText - i18n</p></figcaption></figure>

### Setting the columns via the wizard

<figure><img src="/files/P0Cet5keoNkli4ZA5Xa1" alt=""><figcaption><p>Property configurator for columns wizard</p></figcaption></figure>

After dragging the component on the form, the [Property configurator for columns](/reference/servoy-developer/object-editors/columns-property-configurator) wizard appears. In order to set the columns using the wizard, you need to do the following steps:

1. Find in the left side of the wizard the column you need: it can be part of a related or unrelated datasource, calculations, form and scope variables, aggregates
2. Click on the column name
3. The selected column will appear on the right side of the wizard, showing some of the column properties:
   1. `COLUMNS` : the column's `dataprovider` or `styleClassDataprovider`
   2. `DATAPROVIDER` : selected if the column id value represents the column's dataprovider
   3. `STYLECLASSDATAPROVIDER`: selected if the column id value represents the column's styleClass dataprovider
   4. `STYLECLASS`: the name of the style class that should be applied to this component.
   5. `HEADERTITLE`: the column's title text ([i18n](/reference/servoy-developer/solution-explorer/resources/i18n#i18n) supported)
   6. `delete` icon : you can remove a tab by clicking the icon
4. Click `OK` button after all columns have been added

When using the wizard, column [id](/reference/servoyextensions/ui-components/grids/table#column) property is automatically set:

* the same as `dataprovider` - in case the `COLUMN` was set as `DATAPROVIDER` at creating stage; example: `orderid`.
* `idX`, where `X` starts from 0 and increments according to the number of columns that are set as `STYLECLASSDATAPROVIDER` at creating stage; example: `id0`, `id1`, `id2`, etc.\
  Column ids can be manually changed by the user in the [column properties](/reference/servoyextensions/ui-components/grids/table#column) panel.

## Paging

You can set [pageSize](/reference/servoyextensions/ui-components/grids/table#pagesize) `> 0` for **fixed page sizes**, or [pageSize](/reference/servoyextensions/ui-components/grids/table#pagesize) `0` to **disable paging**; we intend to add pageSize -1 for auto-determining page size based on available height but that is not implemented yet.

## Incremental scrolling

This can work together with paging as well, so you can have a large page size and incremental scrolling would still work.

Incremental scrolling means that if many rows are available (hundreds/thousands) only then rows surrounding the ones that need to be shown will be loaded from server and only a part of those will initially be rendered (added to the browser's DOM).

When the user scrolls, more rows will be loaded from server if needed and more rows will be rendered as needed.

The purpose of all this is that, for example, if you have 1000 rows and selected row is 823, we don't send to the browser the data for all 1000 rows and render thousands of cells in browser. Just some rows around the visible area (which initially will show selected row 823) will be loaded and some of them rendered. This can drop initial show time from tens of seconds or minutes (depending also on the data in each column, connection speed, hardware, ...) to less then one second.

Incremental scrolling can be controlled/customized or virtually disabled by modifying the following properties in properties view:

```javascript
performanceSettings : {
	minBatchSizeForRenderingMoreRows: 10,
	minBatchSizeForLoadingMoreRows: 20,
	maxRenderedRows: 450,
	maxLoadedRows: 1000,
	fastScrollRenderThresholdFactor : 3.0,
	fastScrollLoadThresholdFactor : 2.3
}
```

The values above are the **default values that should be fine** for most situations. If you want to tweak them, here is what they mean:

* **performanceSettings.minBatchSizeForRenderingMoreRows**: influences **the minimum of**:
  * how many rows around the initial visible area will be rendered initially;
  * (when scrolling) how many more rows get rendered each time in the direction of the scroll - in advance. This is done so that when the user scrolls, content is prepared for being shown. The **default value is 10**.

    The real value of initial rendered rows and of additional batch sizes for rendering is actually calculated from the visible height that the table has to work with in the browser, but it cannot go lower then what this setting requires.

    If you want to disable incremental rendering, just set a very high value for this setting and then all available (loaded from server) rows will be rendered right away (this makes sense when combined with paging - acceptable page size).
* **performanceSettings.minBatchSizeForLoadingMoreRows**: influences **the minimum of**:
  * how many rows around the initial visible area will be loaded from server initially;
  * (when scrolling) how many more rows get loaded from server each time in the direction of the scroll - in advance. When the user scrolls, row data is received from server ahead of the scroll so that more rows can be rendered. The **default value is 20**.

    The real value of initial loaded rows and of additional batch sizes for loading rows from server is actually calculated based on the visible height that the table has to work with in the browser, but it cannot go lower then what this setting requires.

    If you want to disable incremental loading of row data, just set a very high value in there and then all needed rows will be loaded from server (this makes sense when combined with paging - acceptable page size).
* **performanceSettings.maxRenderedRows**: in order to not slow down browser UI due to a huge number of DOM elements being created, this limits the number of rows that the table will render.

  If the user scrolls a lot and this results in more then 'maxRenderedRows' being rendered - the table will discard a part of the rendered rows and start fresh - as if it was rendering initially around the visible area.

  If you set a high value, many rows can get rendered in the browser and then you will have a more natural feel when scrolling fast back to already rendered rows. But if the value is too high and the browser slows down too much it is better to start fresh with less rendered rows more often (so have this set to a lower value).

  **Default value is 450** (although some browser & hardware can handle nicely even more rendered rows, depending also on content).
* **performanceSettings.maxLoadedRows**: in order to not use too much memory in the browser due to a huge number of rows (row data) being loaded, this limits the number of rows that the table will keep loaded.

  If the user scrolls a lot and this results in more then 'maxLoadedRows' being loaded - the table will discard a part of the loaded rows.

  If you set a high value, many rows can get loaded in the browser and then you will have a more natural feel when scrolling fast back to already loaded rows. But if the value is too high the browser memory usage might grow too much and it is better to discard part of the loaded rows (from the opposite side then user is scrolling to).

  **Default value is 1000** (although some hardware can handle nicely even more loaded rows, depending also on content).
* **performanceSettings.fastScrollRenderThresholdFactor**: **Default value: 3.0 (float)**; if for example you have a table with 1000 rows and initially the selected row is shown at index 700 - rendered rows and loaded rows will be around the visible area. Then if the user grabs the scroll knob with the mouse and drags fast upwards to the beginning we have to discard what we have rendered and render the first set of rows instead.

  We cannot just render batches of rows one by one upwards until we reach the first row because that will take a very long time. This setting determines when the table component considers a scroll operation to be a "**fast-scroll**" that needs a discard of currently rendered rows and a render of the new visible area.

  When the scroll position is more then 'fastScrollRenderThresholdFactor \* initiallyRenderedRows' apart from currently rendered rows, the scroll operation is considered to need a completely new set of rendered rows.
* **performanceSettings.fastScrollLoadThresholdFactor**: **Default value: 2.3 (float)**; if for example you have a table with 1000 rows and initially the selected row is shown at index 700 - rendered rows and loaded rows will be around the visible area. Then if the user grabs the scroll knob with the mouse and drags fast upwards to the beginning we have to discard what we have loaded and load the first set of rows instead.

  We cannot just load from server batches of rows one by one upwards until we reach the first row because that will take a very long time. This setting determines when the table component considers a scroll operation to be a "**fast-scroll**" that needs a discard of currently loaded rows and a load of rows from the new visible area.

  When the scroll position is more then 'fastScrollLoadThresholdFactor \* initiallyLoadedRows' apart from currently loaded rows, the scroll operation is considered to need a completely new set of loaded rows.

If you modify any of these performance settings, please make sure that:

```javascript
minBatchSizeForRenderingMoreRows < minBatchSizeForLoadingMoreRows
maxRenderedRows < maxLoadedRows
minBatchSizeForRenderingMoreRows  < maxRenderedRows (by a lot)
minBatchSizeForLoadingMoreRows < maxLoadedRows (by a lot)
```

## Table Height in Responsive Form

It can be used both in responsive forms and absolute forms. If used in responsive mode, its [responsiveHeight](/reference/servoyextensions/ui-components/grids/table#responsiveheight) property must be set in *Properties View* (which is the fixed height it will occupy).

Adding a table in a flex-content layout and setting the table [responsiveHeight](/reference/servoyextensions/ui-components/grids/table#responsiveheight) property to `0`, let the table grow up to 100% height of parent element (see more on flex-layout [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/layout/b12grid/flexbox-layout.md#flexbox-layout)). Used with other containers than flex-content layout in order to grow the table to 100% height, the parent element must have a known height.

## Working with Table Columns

### Click-Sorting by Column

In order to have sortable columns by clicking on the column's header, the [enableSort](/reference/servoyextensions/ui-components/grids/table#enablesort) property of the Table must be set to `true`. This will take effect on **all** columns.

### Column width and Resizing

#### width

Columns width can be set as pixel value (ex. `50px`), as a percentage of the table width (`25%`), or it can be left empty, and in this case it will have an automatic value calculated to fill the table width;

If the [autoResize](/reference/servoyextensions/ui-components/grids/table#column) flag of a column is set, the width of the column will increase/decrease when the width of the table is increasing/decreasing (ex. the table is anchored to right, and the window is resized), in order to fill/empty the extra width of the table;

#### enableColumnResize

In order to allow the user to resize columns, the [enableColumnResize](/reference/servoyextensions/ui-components/grids/table#enablecolumnresize) property of the Table must be set to `true`.

#### Setting column format

Columns' Format can be set in [format](/reference/servoyextensions/ui-components/grids/table#column) property of each column. Depending on the type of each dataprovider, this will be done via the format editors for [date](/reference/servoy-developer/object-editors/date-format-editor), [text](/reference/servoy-developer/object-editors/text-format-editor), [integer/number](/reference/servoy-developer/object-editors/number-format-editor).

Example:

Focusing on the `Ship country` column of the following Table, without having any format:

<figure><img src="/files/PjAb7dK6oN7QpQBXRTMZ" alt=""><figcaption><p>`Ship country` column with no format</p></figcaption></figure>

If the countries' names need to be all upper case, then we apply a Format to the `Ship country` column of the Table:

<figure><img src="/files/MqyP92VMcmqmlAZ8mX77" alt=""><figcaption><p>set `Ship country` column format</p></figcaption></figure>

Here is how it looks after the Format has been set:

<figure><img src="/files/bRc8d7Hn7gyT6tb1KEyR" alt=""><figcaption><p>`Ship country` column with applied format</p></figcaption></figure>

## Key Code Settings

On key press of any below keyboard codes we can activate different actions on the table.\
Also allows us to enable or disable this option per key.

Key Code Settings can be found [here](/reference/servoyextensions/ui-components/grids/table#keycodesettings-1).

* pageUp : Move down to last visible item in view
* pageDown : Move up to first visible item in view
* arrowUp : Move up one record in table
* arrowDown : Move down one record in table
* home : Move to the first record in the table
* end : Move to the last record in the table
* enter : Fire the onCellClick event

## Scripting a Table

### Main events

You can find a list of Table **events** [here](/reference/servoyextensions/ui-components/grids/table#events).\
You can find a list of Table **API methods** [here](/reference/servoyextensions/ui-components/grids/table#api).

#### onCellClick

This event is called when the mouse is clicked on a row/cell (foundset and column indexes are given). When the ENTER key is used then only the selected foundset index is given. It uses the record to exactly match where the user clicked on.

Here is an example of how to use the [onCellClick](/reference/servoyextensions/ui-components/grids/table#oncellclick) event of Table in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):\
Let's consider a Table showing `employees` table columns. When clicking on a table cell, the application will show a form containing details of that specific employee record.

```javascript
/**
 * @param {Number} foundsetindex
 * @param {Number} [columnindex]
 * @param {JSRecord} [record]
 * @param {JSEvent} [event]
 * @param {String} [columnid]
 *
 * @private
 *
 * @properties={typeid:24,uuid:"6F3FE901-6D40-4E82-B5C8-C506F201B30E"}
 */
function onCellClick(foundsetindex, columnindex, record, event, columnid) {
	forms.employee_details.controller.loadRecords(record.foundset);
    application.showForm('employee_details');

}
```

#### onCellRightClick

This event is called when the right mouse button is clicked on a row/cell (foundset and column indexes are given). When the ENTER key is used then only the selected foundset index is given. It uses the record to exactly match where the user clicked on.

Here is an example of how to use the [onCellRightClick](/reference/servoyextensions/ui-components/grids/table#oncellrightclick) event of Table in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):

Let's consider a Table showing `employees` table columns. When right clicking on a table cell, the application will show a pop up form containing an employees card menu of that specific employee record.

```javascript
/**
 * @param {Number} foundsetindex
 * @param {Number} [columnindex]
 * @param {JSRecord} [record]
 * @param {JSEvent} [event]
 * @param {String} [columnid]
 *
 * @private
 *
 * @properties={typeid:24,uuid:"8BEBEF8F-DEA8-4893-A2BC-23DC91605917"}
 */
function onCellRightClick(foundsetindex, columnindex, record, event, columnid) {
	var elementX = event.getX() - 210;
	var elementY = event.getY() + 20;
	plugins.window.showFormPopup(null, forms.employeeCardMenu, foundset.getSelectedRecord(), null, 222, 184, elementX, elementY);

}
```

### Add a column

Here is an example of how to programmatically add a column in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [newColumn](/reference/servoyextensions/ui-components/grids/table#newcolumn) API:

```javascript
/**
 * @param {Boolean} firstShow form is shown first time after load
 * @param {JSEvent} event the event that triggered the action
 *
 * @properties={typeid:24,uuid:"B6E9D07A-8C72-452A-B282-F394DD6B3D5F"}
 */
function onShow(firstShow, event) {
	var column = elements.table_orders.newColumn('shipaddress');
	column.id = "shipaddress";
	column.headerText= "Ship address";
}
```

### Remove a column

Here is an example of how to programmatically remove a column in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [removeColumn](/reference/servoyextensions/ui-components/grids/table#removecolumn) API:

```javascript
/**
 * @param {Boolean} firstShow form is shown first time after load
 * @param {JSEvent} event the event that triggered the action
 *
 * @properties={typeid:24,uuid:"B6E9D07A-8C72-452A-B282-F394DD6B3D5F"}
 */
function onShow(firstShow, event) {
	elements.table_orders.removeColumn(1);
}
```


# Input Controls


# Calendar

Guide for using the Calendar in your applications

## Overview

Calendar-Inline is an input control component. It allows a user us a date-picker to choose Date values for a bound data-provider. Similar to the Calendar component, the Calendar-Inline provides a date-picker interface to choose a date. The key difference is that the Calendar component is an input field that the shows the date-picker in a popup only when clicked; whereas the Calendar shows the date-picker directly on the form Common use cases include selecting a value for a filter or search parameter.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=calendar).

## Get Started

## Modifying Calendar at Design-Time

Calendar, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the componentName in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

### Setting the tooltipText

Calendar, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the placeholderText

The text displayed inside the calendar textbox can be modified by setting its [`placeholderText`](/reference/servoyextensions/ui-components/input-control/calendar#placeholdertext) property. This will just be plain text which will be shown as an instruction on what you can do within the calendar's textbox. When you insert a value in the calendar textbox the placeholderText will disappear and your inserted text will take it's place. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the property3name (or delete if needed)

### Styling

Like all components, Calendar can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

## Handling Events

Like most components, Calendar has events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a Calendar is the `onDataChange` event, which is triggered when a date item is clicked.

To Handle the event, double-click the value for the `onDataChange` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the button's `onAction` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript

  @param {JSEvent} event
 
  @properties={typeid24,uuidA74C281C-00AA-46AA-BB38-500C937F2D1A}
 
function onDataChange(oldValue, newValue, event) {
	 application.output(newValue); //print out the date selected
}
```

{% hint style="info" %}
See the [calendar reference](/reference/servoyextensions/ui-components/input-control/calendar) for comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/calendar#events)
{% endhint %}

## Modifying a Calendar at Runtime

Calendar, like many components, can be modified at runtime through code. Below are a few examples of controlling a Calendar from code.

#### Enabling or Disabling a Calendar

You can easily change the `enabled` state of a Calendar at runtime.

Change this to match your component

```javascript
function disableCalendar(){
	elements.myCalendar.enabled = false;
}
```

### HidingShowing a Calendar

You can easily change the `visible` state of a Calendar at runtime.

Change this to match your component

```javascript
function hideCalendar(){
	elements.myCalendar.visible = false;
}
```

## Calling Calendar API Methods

Like most components, a Calendar has API methods which can be called from code. Below is an example of common API calls.

#### disableDates

Disable some dates from selection in the calendar [`disableDates`](/reference/servoyextensions/ui-components/input-control/calendar#disabledates) method.

```javascript
function disableDates(){
	var dates = [];
	var d = new Date(); //create a new date object for today's date
	d.setDate(d.getDate() + 1); //set the date to the next day
	dates.push(d); // add that date object to an array
	elements.myCalendar.disableDates(dates); // send the array to the api which will then disable the day after today.
}
```

### Add CSS Style Class

You can easily add a style class to a Calendar using the `addStyleClass` method.

Change this to match your component

```javascript
function AddStyleClassBadge(){
	elements.myCalendar.addStyleClass('mycssclass');
}
```

### Related Articles

The following articles are recommended for additional reading

* [Calendar Reference Documentation](/reference/servoyextensions/ui-components/input-control/calendar)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Calendar Inline

## Overview

Calendar-Inline is an input control component. It allows a user us a date-picker to choose Date values for a bound data-provider. Similar to the Calendar component, the Calendar-Inline provides a date-picker interface to choose a date. The key difference is that the Calendar component is an input field that the shows the date-picker in a popup only when clicked; whereas the Calendar Inline shows the date-picker directly on the form. Common use cases include selecting a value for a filter or search parameter.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=calendarinline).

## Get Started

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Calendar-Inline component from the Pallet onto the form.

<figure><img src="/files/tQ39kK7AkHchcGxPdjiO" alt=""><figcaption><p>Add Calendar Inline</p></figcaption></figure>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying Calendar Inline at Design-Time

Calendar Inline, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the Calendar Inline in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

{% hint style="info" %}
See the reference docs for [Calendar Inline](/reference/servoyextensions/ui-components/input-control/calendar-inline) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/calendar-inline#properties).
{% endhint %}

### Setting the toolTipText

Calendar Inline, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

<figure><img src="/files/Vu6ySq2T8rkpLIqp4Bzz" alt=""><figcaption></figcaption></figure>

### Styling

Like all components, Calendar Inline can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

## Handling Events

Like most components, Calendar Inline has events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a Calendar Inline is the `onDataChange` event, which is triggered when a date item is clicked.

To handle the event, double-click the value for the `onDataChange` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the component's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<figure><img src="/files/PlBjxerluIZKQ3No2d8j" alt=""><figcaption><p>Create a method to handle the onDataChange event</p></figcaption></figure>

```javascript
/**
 * @param {JSEvent} event
 *
 * @properties={typeid24,uuidA74C281C-00AA-46AA-BB38-500C937F2D1A}
*/ 
function onDataChange(oldValue, newValue, event) {
	 application.output(newValue); //print out the date selected
}
```

{% hint style="info" %}
See the [Calendar Inline reference](/reference/servoyextensions/ui-components/input-control/calendar-inline) for comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/calendar-inline#events)
{% endhint %}

## Modifying a Calendar Inline at Runtime

Calendar Inline, like many components, can be modified at runtime through code. Below are a few examples of controlling a Calendar Inline from code.

### Enabling or Disabling a Calendar Inline

You can easily change the `enabled` state of a Calendar Inline at runtime.

```javascript
function disableCalendar(){
	elements.myCalendar.enabled = false;
}
```

### HidingShowing a Calendar Inline

You can easily change the `visible` state of a Calendar Inline at runtime.

```javascript
function hideCalendar(){
	elements.myCalendar.visible = false;
}
```

## Calling Calendar Inline API Methods

Like most components, a Calendar Inline has API methods which can be called from code. Below is an example of common API calls.

### disableDates

Disable some dates from selection in the calendar [`disableDates`](/reference/servoyextensions/ui-components/input-control/calendar-inline#disabledates) method.

```javascript
function disableDates(){
	var dates = [];
	var d = new Date(); //create a new date object for today's date
	d.setDate(d.getDate() + 1); //set the date to the next day
	dates.push(d); // add that date object to an array
	elements.myCalendar.disableDates(dates); // send the array to the api which will then disable the day after today.
}
```

### Add CSS Style Class

You can easily add a style class to a Calendar Inline using the `addStyleClass` method.

```javascript
function AddStyleClassCalendar(){
	elements.myCalendar.addStyleClass('mycssclass');
}
```

## Related Articles

The following articles are recommended for additional reading

* [Calendar Inline Reference Documentation](/reference/servoyextensions/ui-components/input-control/calendar-inline)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Checkbox

Guide for using checkboxes in your applications

## Overview

This guide will show how to use a checkbox in your applications. See how easy it is to drag and drop the checkboxes onto your forms and connect them to your business logic. Checkbox can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=checkbox).

## Get Started

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Checkbox component from the Pallet onto the form.

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Checkbox at Design-Time

The checkbox, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the checkbox in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

{% hint style="info" %}
See the reference docs for [Checkbox](/reference/servoyextensions/ui-components/input-control/checkbox) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/checkbox#properties).
{% endhint %}

### Setting the text

The text displayed on a checkbox can be modified by setting its [`text`](/reference/servoyextensions/ui-components/input-control/checkbox#text) property. Most often, this will just be plain text. In this case, just enter the value into the editor or directly on the component by double-clicking it. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the tooltipText

Checkboxes, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what value will be checked or unchecked. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

{% hint style="info" %}
Remember that text can also be dynamic, data-driven or localized. For more options, you can open edit the text property in the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).
{% endhint %}

### Styling

Like all components, a checkbox can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

For example, `styleClass="checkbox"`

If you are using Variants, then you can easily drag and drop variations of your checkbox onto your form.

## Handling Events

Like most components, checkbox have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a checkbox is the `onDataChange` event, which is triggered when the checkbox is clicked.

To Handle the event, double-click the value for the `onDataChange` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the component's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * Handle changed data, return false if the value should not be accepted.
 * JSEvent.data will contain extra information about dataproviderid, its scope and the scope id (record datasource or form/global variable scope)
 *
 * @param oldValue
 * @param newValue
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"4A599FE8-D13D-4E4E-88AE-9B40DF8434F5"}
 */
function onDataChange(oldValue, newValue, event) {
	// Enter custom code
	return true
}
```

{% hint style="info" %}
See the [Checkbox reference](/reference/servoyextensions/ui-components/input-control/checkbox) for comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/checkbox#events)
{% endhint %}

## Modifying a Checkbox at Runtime

Checkbox, like many components, can be modified at runtime through code. Below are a few examples of controlling a checkbox from code.

### Enabling / Disabling a Checkbox

You can easily change the `enabled` state of a checkbox at runtime.

```javascript
function  disableCheckbox(){
elements.myCheckbox.enabled = false;
}
```

## Calling Checkbox API Methods

Like most components, a checkbox has API methods which can be called from code. Below is an example of common API calls.

### Add CSS Style Class

You can easily add a style class to a checkbox using the `addStyleClass` method.

```javascript
function  AddStyleClassCheckbox(){
elements.myCheckbox.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Checkbox Reference Docs](/reference/servoyextensions/ui-components/input-control/checkbox) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/input-control/checkbox#properties) and [methods](/reference/servoyextensions/ui-components/input-control/checkbox#api).
{% endhint %}

## Related Articles

The following articles are recommended for additional reading:

* [Checkbox Reference Documentation](/reference/servoyextensions/ui-components/input-control/checkbox)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Choice Group

## Overview

![Choice group](/files/tBeISM1PRGMyWpmZoYIv)

A choice group offers values from a provided value list and returns the selected values as a carriage return-separated string to the dataprovider attached. When the value list offers display and return values, the return values are returned.

Note that if your value list does not have the "Allow empty value" check set, a user won't be able to remove the last selected value anymore.

The choice group component can be used in two modes: single select (either/or, aka radio button) or multi select. That mode can be controlled via the **inputType** property.

To see a live sample of the component you can go [here](https://samples-prod.demo.servoy-cloud.eu/solution/components?a=choicegroup).

## Get Started

<div align="left"><figure><img src="/files/FKEnBnQ0twQ8rrnOuulV" alt=""><figcaption><p>Choice group demo - single select</p></figcaption></figure></div>

### Add a Choice Group to a form

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Choice Group component from the Pallet onto the form, then select a dataprovider and a valuelist.

<div align="left"><figure><img src="/files/0IPfPp7ZUT3CNExcYskM" alt=""><figcaption><p>Create Choice Group</p></figcaption></figure></div>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Choice Group at Design-Time

Choice Groups, like all components, have properties that can be modified at design time to set the appearance and behavior of the component. Select the component in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design time.

{% hint style="info" %}
See the reference docs for [Choice Group](/reference/servoyextensions/ui-components/input-control/choice-group) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/choice-group#properties).
{% endhint %}

### Setting the data-provider

Choice Group's dataprovider can be set after the component has been added to the form or by setting it in [dataprovider](/reference/servoyextensions/ui-components/input-control/choice-group#dataproviderid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties).

### Setting the input type

Choice Group's input type can be set in [inputType](/reference/servoyextensions/ui-components/input-control/choice-group#inputtype) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). It can be single select (either/or, aka radio button) or multi select.

<div align="left"><figure><img src="/files/4JuN4BlVIETvIiK8s1DK" alt=""><figcaption><p>Choice group demo - multi select</p></figcaption></figure></div>

{% hint style="danger" %}
**IMPORTANT!**\
When the Choice Group [inputType](/reference/servoyextensions/ui-components/input-control/choice-group#inputtype) property is set to `checkbox`, then [dataprovider](/reference/servoyextensions/ui-components/input-control/choice-group#dataproviderid) property must be a variable that can contain multiples values, such as form or scope variable.\
Example:

```javascript
/**
 * @type {String}
 *
 * @properties={typeid:35,uuid:"FA8EF7B3-5A1C-43E6-A5A3-36E99197E38F"}
 */
var choice;
```

`dataprovider` is set as `choice`
{% endhint %}

### Setting the valuelist

Choice Group's [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) can be set it in [valuelist](/reference/servoyextensions/ui-components/input-control/choice-group#valuelistid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties) and it should match the set [dataprovider](/reference/servoyextensions/ui-components/input-control/choice-group#dataproviderid).

Example:

In order to get a drop down menu with orders' ship countries, the followings settings should be made:

1. set the Choice Group [dataprovider](/reference/servoyextensions/ui-components/input-control/choice-group#dataproviderid):
   * if [inputType](/reference/servoyextensions/ui-components/input-control/choice-group#inputtype) is `radio`, then [dataprovider](/reference/servoyextensions/ui-components/input-control/choice-group#dataproviderid) can be either a table column (`shipcountry`) or another type of dataprovider
   * if [inputType](/reference/servoyextensions/ui-components/input-control/choice-group#inputtype) is `checkbox`, then [dataprovider](/reference/servoyextensions/ui-components/input-control/choice-group#dataproviderid) must be a variable that can contain multiples values, such as form or scope variable
2. in case it doesn't exist, create a [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) using Table values and `shipcountry` column as dataprovider
3. set the countries list in [valuelist](/reference/servoyextensions/ui-components/input-control/choice-group#valuelistid) property of the Choice Group

## Handling Click Events

Like most components, Choice Groups have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a Choice Group is the `onDataChange` event, which is triggered when the component is clicked and the value is changed.

To Handle the event, double-click the value for the [onDataChange](/reference/servoyextensions/ui-components/input-control/choice-group#ondatachangemethodid) property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option to select an existing Method or create a new Method. The method will be called when the Choice Group's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<div align="left"><figure><img src="/files/jwhp8DR7Mid69pnHVPjE" alt=""><figcaption><p>Create method to handle the onDataChange event</p></figcaption></figure></div>

```javascript
/**
 *
 * @param oldValue
 * @param newValue
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"D2499C52-AC5E-4C9E-9B51-1415F0E83D04"}
 */
function onDataChange(oldValue, newValue, event) {
    //show and hide another page element according to the selected value(s)
	if(newValue.includes('USA')){
	    elements.info_usa.visible = true;
	}else {elements.info_usa.visible = false;}
	return true;
}
```

{% hint style="info" %}
See the [Choice Group reference](/reference/servoyextensions/ui-components/input-control/choice-group) for a comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/choice-group#events)
{% endhint %}

## Modifying a Choice Group at Runtime

Choice Groups, like many components, can be modified at runtime through code. Below are a few examples of controlling a Choice Group from code.

### Enabling / Disabling a Choice Group

You can easily change the `enabled` state of a Choice Group at runtime.

Example:

```javascript
function disableChoiceGroup(){
	elements.myChoiceGroup.enabled = false;
}
```

### Hiding/Showing a Choice Group

You can easily change the `visible` state of a Choice Group at runtime.

Example:

```javascript
function hideChoiceGroup(){
	elements.myChoiceGroup.visible = false;
}
```

## Calling Choice Group API Methods

Like most components, a Choice Group has API methods which can be called from code. Below is an example of common API calls.

### Add CSS Style Class

You can easily add a style class to a Choice Group using the [`addStyleClass`](/reference/servoyextensions/ui-components/input-control/choice-group#api) method.

Example:

```javascript
function AddStyleClassChoiceGroup(){
	elements.myChoiceGroup.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Choice Group reference](/reference/servoyextensions/ui-components/input-control/choice-group) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/input-control/choice-group#properties) and [methods](/reference/servoyextensions/ui-components/input-control/choice-group#api).
{% endhint %}

## Related Articles

The following articles are recommended for additional reading

* [Choice group Reference Documentation](/reference/servoyextensions/ui-components/input-control/choice-group)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Combobox

## Overview

Combobox is a standard input component that allows the user to pick one of the options in it's drop-down list.

To see a live sample of the component you can go [here](https://samples-prod.demo.servoy-cloud.eu/solution/components?a=combobox).

## Get Started

<div align="left"><figure><img src="/files/QOdkqGWbsGqIaKYNYUla" alt=""><figcaption><p>Combobox</p></figcaption></figure></div>

### Add a Combobox to a form

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Combobox component from the Pallet onto the form, then select a dataprovider and a valuelist.

<div align="left"><figure><img src="/files/gQoA0KYfkZRQOgvWJrko" alt=""><figcaption><p>Create Combobox</p></figcaption></figure></div>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Combobox at Design-Time

Comboboxes, like all components, have properties that can be modified at design time to set the appearance and behavior of the component. Select the label in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design time.

{% hint style="info" %}
See the reference docs for [Combobox](/reference/servoyextensions/ui-components/input-control/combobox) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/combobox#properties).
{% endhint %}

### Setting the data-provider

Combobox's dataprovider can be set after the component has been added to the form or by setting it in [dataprovider](/reference/servoyextensions/ui-components/input-control/combobox#dataproviderid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties).

### Setting the valuelist

Combobox's [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) can be set it in [valuelist](/reference/servoyextensions/ui-components/input-control/combobox#valuelistid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties) and it should match the set [dataprovider](/reference/servoyextensions/ui-components/input-control/combobox#dataproviderid).

Example:

In order to get a drop down menu with orders' ship countries, the followings settings should be made:

1. set `shipcountry` as the Combobox [dataprovider](/reference/servoyextensions/ui-components/input-control/combobox#dataproviderid)
2. in case it doesn't exist, create a [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) using Table values and `shipcountry` column as dataprovider
3. set the countries list in [valuelist](/reference/servoyextensions/ui-components/input-control/combobox#valuelistid) property of the Combobox

## Handling Click Events

Like most components, Comboboxes have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a combobox is the `onDataChange` event, which is triggered when the combobox is clicked and the value is changed.

To Handle the event, double-click the value for the [onDataChange](/reference/servoyextensions/ui-components/input-control/combobox#ondatachangemethodid) property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option to select an existing Method or create a new Method. The method will be called when the Combobox's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<figure><img src="/files/6qAJQMYTkkHzlt99dHHz" alt=""><figcaption><p>Create method to handle the onDataChange event</p></figcaption></figure>

```javascript
/**
 *
 * @param oldValue
 * @param newValue
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"D2499C52-AC5E-4C9E-9B51-1415F0E83D04"}
 */
function onDataChange(oldValue, newValue, event) {
    //enable and disable another page element according to the selected value
    if (newValue == 'Yes')
    {
        elements.buttonDetails.enabled = true;
    } else {elements.buttonDetails.enabled = false;}
	return true;
}
```

{% hint style="info" %}
See the [Combobox reference](/reference/servoyextensions/ui-components/input-control/combobox) for a comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/combobox#events)
{% endhint %}

## Modifying a Combobox at Runtime

Comboboxes, like many components, can be modified at runtime through code. Below are a few examples of controlling a Combobox from code.

### Enabling / Disabling a Combobox

You can easily change the `enabled` state of a Combobox at runtime.

Example:

```javascript
function disableCombobox(){
	elements.myCombobox.enabled = false;
}
```

### Hiding/Showing a Combobox

You can easily change the `visible` state of a Combobox at runtime.

Example:

```javascript
function hideCombobox(){
	elements.myCombobox.visible = false;
}
```

## Calling Combobox API Methods

Like most components, a Combobox has API methods which can be called from code. Below is an example of common API calls.

### Add CSS Style Class

You can easily add a style class to a Combobox using the [`addStyleClass`](/reference/servoyextensions/ui-components/input-control/combobox#api) method.

Example:

```javascript
function AddStyleClassCombobox(){
	elements.myCombobox.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Combobox reference](/reference/servoyextensions/ui-components/input-control/combobox) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/input-control/combobox#properties) and [methods](/reference/servoyextensions/ui-components/input-control/combobox#api).
{% endhint %}

## Related Articles

The following articles are recommended for additional reading

* [Combobox Reference Documentation](/reference/servoyextensions/ui-components/input-control/combobox)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Group Buttons

The Group Buttons component allows grouping a series of buttons on a single line.

To see a live sample of the component you can go [here](https://samples-prod.demo.servoy-cloud.eu/solution/components?a=groupButtons).

## Get Started

<div align="left"><figure><img src="/files/MXzUvWXo12pj9n2ezaVl" alt=""><figcaption><p>Group Buttons demo - single select</p></figcaption></figure></div>

### Add a Group Buttons to a form

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Group Buttons component from the Pallet onto the form, then select a dataprovider and a valuelist.

<div align="left"><figure><img src="/files/eCNqFdHZSpac1zakL9r5" alt=""><figcaption><p>Create Group Buttons</p></figcaption></figure></div>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Extra Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Group Buttons at Design-Time

Group Buttons, like all components, have properties that can be modified at design time to set the appearance and behavior of the component. Select the component in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design time.

{% hint style="info" %}
See the reference docs for [Group Buttons](/reference/servoyextensions/ui-components/input-control/group-buttons) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/group-buttons#properties).
{% endhint %}

### Setting the data-provider

Group Buttons dataprovider can be set after the component has been added to the form or by setting it in [dataprovider](/reference/servoyextensions/ui-components/input-control/group-buttons#dataproviderid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties).

### Setting the input type

Group Buttons input type can be set in [inputType](/reference/servoyextensions/ui-components/input-control/group-buttons#inputtype) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). It can be single select (`RADIO`) or multi select (`CHECKBOX`).

{% hint style="danger" %}
**IMPORTANT!**\
When the Group Buttons [inputType](/reference/servoyextensions/ui-components/input-control/group-buttons#inputtype) property is set to `CHECKBOX`, then [dataprovider](/reference/servoyextensions/ui-components/input-control/group-buttons#dataproviderid) property must be a variable that can contain multiples values, such as form or scope variable.\
Example:

```javascript
/**
 * @type {String}
 *
 * @properties={typeid:35,uuid:"FA8EF7B3-5A1C-43E6-A5A3-36E99197E38F"}
 */
var choice;
```

`dataprovider` is set as `choice`
{% endhint %}

### Setting the valuelist

Group Buttons [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) can be set it in [valuelist](/reference/servoyextensions/ui-components/input-control/group-buttons#valuelistid) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties) and it should match the set [dataprovider](/reference/servoyextensions/ui-components/input-control/group-buttons#dataproviderid).

Example:

In order to get a group buttons with orders' ship countries, the followings settings should be made:

1. set the Group Buttons [dataprovider](/reference/servoyextensions/ui-components/input-control/group-buttons#dataproviderid):
   * if [inputType](/reference/servoyextensions/ui-components/input-control/group-buttons#inputtype) is `RADIO`, then [dataprovider](/reference/servoyextensions/ui-components/input-control/group-buttons#dataproviderid) can be either a table column (`shipcountry`) or another type of dataprovider
   * if [inputType](/reference/servoyextensions/ui-components/input-control/group-buttons#inputtype) is `CHECKBOX`, then [dataprovider](/reference/servoyextensions/ui-components/input-control/group-buttons#dataproviderid) must be a variable that can contain multiples values, such as form or scope variable
2. in case it doesn't exist, create a [valuelist](/guides/develop/application-design/data-modeling/value-lists#overview) using Table values and `shipcountry` column as dataprovider
3. set the countries list in [valuelist](/reference/servoyextensions/ui-components/input-control/group-buttons#valuelistid) property of the Group Buttons

## Handling Click Events

Like most components, Group Buttons have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a Group Buttons is the `onDataChange` event, which is triggered when the component is clicked and the value is changed.

To Handle the event, double-click the value for the [onDataChange](/reference/servoyextensions/ui-components/input-control/group-buttons#ondatachangemethodid) property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option to select an existing Method or create a new Method. The method will be called when the Group Buttons's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<div align="left"><figure><img src="/files/1REPGdnOnofFmnNyHZf2" alt=""><figcaption><p>Create method to handle the onDataChange event</p></figcaption></figure></div>

```javascript
/**
 *
 * @param oldValue
 * @param newValue
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"D2499C52-AC5E-4C9E-9B51-1415F0E83D04"}
 */
function onDataChange(oldValue, newValue, event) {
    //show and hide other page elements according to the selected value
    showOptions(newValue);
	return true;
}
```

{% hint style="info" %}
See the [Group Buttons reference](/reference/servoyextensions/ui-components/input-control/group-buttons) for a comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/group-buttons#events)
{% endhint %}

## Modifying a Group Buttons at Runtime

Group Buttons, like many components, can be modified at runtime through code. Below are a few examples of controlling a Group Buttons from code.

### Enabling / Disabling a Group Buttons

You can easily change the `enabled` state of a Group Buttons at runtime.

Example:

```javascript
function disableGroupButtons(){
	elements.myGroupButtons.enabled = false;
}
```

### Hiding/Showing a Group Buttons

You can easily change the `visible` state of a Group Buttons at runtime.

Example:

```javascript
function hideGroupButtons(){
	elements.myGroupButtons.visible = false;
}
```

### Changing the valuelist

You can easily change the `valuelist` of a Group Buttons at runtime.

Example:

```javascript
function changeValuelist(){
	elements.myGroupButtons.valuelist = "myOtherValuelist";
}
```

## Calling Group Buttons API Methods

Like most components, a Group Buttons has API methods which can be called from code. Below is an example of common API calls.

### Add CSS Style Class

You can easily add a style class to a Group Buttons using the [`addStyleClass`](/reference/servoyextensions/ui-components/input-control/group-buttons#api) method.

Example:

```javascript
function AddStyleClassGroupButtons(){
	elements.myGroupButtons.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Group Buttons reference](/reference/servoyextensions/ui-components/input-control/group-buttons) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/input-control/group-buttons#properties) and [methods](/reference/servoyextensions/ui-components/input-control/group-buttons#api).
{% endhint %}

## Related Articles

The following articles are recommended for additional reading

* [Button group Reference Documentation](/reference/servoyextensions/ui-components/input-control/group-buttons)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Html Area

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=htmlArea).

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

Table of contents

* [Html Area properties](#html-area-properties)
* [Html Area events](#html-area-events)
* [Html Area API](#html-area-api)

## Html Area properties

Html Area properties can be found [here](/reference/servoyextensions/ui-components/input-control/html-area#properties).

## Html Area events

Html Area events can be found [here](/reference/servoyextensions/ui-components/input-control/html-area#events).

## Html Area API

Html Area API methods can be found [here](/reference/servoyextensions/ui-components/input-control/html-area#api).

## Related Articles

The following articles are recommended for additional reading

* [Html Area Reference Documentation](/reference/servoyextensions/ui-components/input-control/html-area)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Input Group

## Overview

An Input Group is a component that consists of input fields with text or button add-ons grouped into one element. It allows for a more structured and visually appealing way to display input fields along with additional elements like buttons or text add-ons.

## Get Started

<div align="left"><figure><img src="/files/yUsHDMSY3nHFmae8Cy7O" alt=""><figcaption><p>Input Group demo</p></figcaption></figure></div>

### Add an Input Group to a form

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Input Group component from the Pallet onto the form, then select a dataprovider.

<div align="left"><figure><img src="/files/xYLVgaVBoijF2J6aR5u1" alt=""><figcaption><p>Create Input Group</p></figcaption></figure></div>

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Extra Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying an Input Group at Design-Time

Input Groups, like all components, have properties that can be modified at design time to set the appearance and behavior of the component. Select the component in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design time.

{% hint style="info" %}
See the reference docs for [Input Group](/reference/servoyextensions/ui-components/input-control/input-group) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/input-group#properties).
{% endhint %}

### Setting the data-provider

Input Group's dataprovider can be set after the component has been added to the form or by setting it in [dataprovider](/reference/servoyextensions/ui-components/input-control/input-group#dataprovider) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties).

### AddOn

<div align="left"><figure><img src="/files/gpni4kU0E9faqsBh3Xk4" alt=""><figcaption><p>Input Group - addOn</p></figcaption></figure></div>

AddOns are text add-ons that can be added either to the left or right of a text field within an inputgroup.\
AddOn properties can be found [here](/reference/servoyextensions/ui-components/input-control/input-group#addon).

Here are the steps to add an addOn to an Input Group:

1. Select the component in the [Form Editor](/reference/servoy-developer/object-editors/form-editor)
2. Select the [`addOns`](/reference/servoyextensions/ui-components/input-control/input-group#addons) property and click the `+` button in order to add one
3. Expand the [`addOns`](/reference/servoyextensions/ui-components/input-control/input-group#addons) property to see the list of addOns.
4. In order to edit each addOn, expand it set its [properties](/reference/servoyextensions/ui-components/input-control/input-group#addon)

### AddOnButton

<div align="left"><figure><img src="/files/h9RlqCLwyLFfC7Bwko2r" alt=""><figcaption><p>Input Group - addOnButton</p></figcaption></figure></div>

AddOnButtons are buttons that can be added either to the left or right of a text field within an inputgroup.

AddOnButton properties can be found [here](/reference/servoyextensions/ui-components/input-control/input-group#addonbutton).

Here are the steps to add an addOnButton to an Input Group:

1. Select the component in the [Form Editor](/reference/servoy-developer/object-editors/form-editor)
2. Select the [`addOnButtons`](/reference/servoyextensions/ui-components/input-control/input-group#addonbuttons) property and click the `+` button in order to add one
3. Expand the [`addOnButtons`](/reference/servoyextensions/ui-components/input-control/input-group#addonbuttons) property to see the list of addOnButtons.
4. In order to edit each addOnButton, expand it set its [properties](/reference/servoyextensions/ui-components/input-control/input-group#addonbutton)

### Using a format

Input Group's Format can be set in [Format](/reference/servoyextensions/ui-components/input-control/input-group#format) property. Depending on the type of each dataprovider, this will be done via the format editors for [date](/reference/servoy-developer/object-editors/date-format-editor), [text](/reference/servoy-developer/object-editors/text-format-editor), [integer/number](/reference/servoy-developer/object-editors/number-format-editor).

### Setting the input type

Input Group's input type can be set in [inputType](/reference/servoyextensions/ui-components/input-control/input-group#inputtype) property, found in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). It can be `text`, `password` or `number`.

## Handling Click Events

Like most components, Input Groups have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a Input Group is the `onDataChange` event, which is triggered when the component is clicked and the value is changed.

To Handle the event, double-click the value for the [onDataChange](/reference/servoyextensions/ui-components/input-control/input-group#ondatachangemethodid) property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option to select an existing Method or create a new Method. The method will be called when the Input Group's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

<div align="left"><figure><img src="/files/WN9Zu1AvAVr2iklRaxIA" alt=""><figcaption><p>Create method to handle the onDataChange event</p></figcaption></figure></div>

```javascript
/**
 *
 * @param oldValue
 * @param newValue
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"28F84381-D7B4-44B3-8A5E-771C82C1A1D6"}
 */
function onDataChange(oldValue, newValue, event) {
	if(newValue.includes('USA')){
	    elements.info_usa.visible = true;
	}else {elements.info_usa.visible = false;}
	return true;
}
```

{% hint style="info" %}
See the [Input Group reference](/reference/servoyextensions/ui-components/input-control/input-group) for a comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/input-group#events)
{% endhint %}

## Modifying an Input Group at Runtime

Input Groups, like many components, can be modified at runtime through code. Below are a few examples of controlling a Input Group from code.

### Enabling / Disabling an Input Group

You can easily change the `enabled` state of an Input Group at runtime.

Example:

```javascript
function disableInputGroup(){
	elements.myInputGroup.enabled = false;
}
```

### Hiding/Showing an Input Group

You can easily change the `visible` state of a Input Group at runtime.

Example:

```javascript
function hideInputGroup(){
	elements.myInputGroup.visible = false;
}
```

## Calling Input Group API Methods

Like most components, an Input Group has API methods which can be called from code. Below is an example of common API calls.

### Add an AddOn

You can easily add an AddOn to an Input Group using the [`addAddOn`](/reference/servoyextensions/ui-components/input-control/input-group#addaddon) method.

Example:

```javascript
function AddAddOnInputGroup(){
	elements.myInputGroup.addAddOn({text:"new addOn", position:'LEFT'});
}
```

### Add an AddOnButton

You can easily add an AddOnButton to an Input Group using the [`addAddOnButton`](/reference/servoyextensions/ui-components/input-control/input-group#addaddon) method.

Example:

```javascript
function AddAddOnButtonInputGroup(){
	elements.myInputGroup.addAddOnButton({text:'new btn', position:'RIGHT', onAction:onAction});
}
```

### Remove AddOns

You can easily remove all AddOns of an Input Group using the [`clearAddOns`](/reference/servoyextensions/ui-components/input-control/input-group#clearaddons) method.

Example:

```javascript
function removeAllAddOns(){
	elements.myInputGroup.clearAddOns();
}
```

### Remove AddOnButtons

You can easily remove all AddOnButtons of an Input Group using the [`clearAddOnButtons`](/reference/servoyextensions/ui-components/input-control/input-group#clearaddonbuttons) method.

Example:

```javascript
function removeAllAddOnButtons(){
	elements.myInputGroup.clearAddOnButtons();
}
```

### Add CSS Style Class

You can easily add a style class to an Input Group using the [`addStyleClass`](/reference/servoyextensions/ui-components/input-control/input-group#api) method.

Example:

```javascript
function AddStyleClassInputGroup(){
	elements.myInputGroup.addStyleClass('mycssclass');
}
```

{% hint style="info" %}
See the [Input Group reference](/reference/servoyextensions/ui-components/input-control/input-group) for a complete list of programmable [properties](/reference/servoyextensions/ui-components/input-control/input-group#properties) and [methods](/reference/servoyextensions/ui-components/input-control/input-group#api).
{% endhint %}

### Related Articles

The following articles are recommended for additional reading

* [Inputgroup Reference Documentation](/reference/servoyextensions/ui-components/input-control/input-group)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Rating

The rating component is a simple component to capture a value in a certain range by selecting a star or other icon from a number of icons shown.

Star example:

![Rating stars](/files/jndzrm08MCPyyqaASGvV)

Hearts example:

![Rating hearts](/files/I2jt9mmKbfDdLlsMFiIz)

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Rating properties](#rating-properties)
* [Rating events](#rating-events)

## Rating properties

Rating properties can be found [here](/reference/servoyextensions/ui-components/input-control/rating#properties).

## Rating events

Rating events can be found [here](/reference/servoyextensions/ui-components/input-control/rating#events).

### Related Articles

The following articles are recommended for additional reading

* [Rating Reference Documentation](/reference/servoyextensions/ui-components/input-control/rating)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Slider

The Slider component offers simple or range sliders. It is based on the [angularjs-slider](https://github.com/angular-slider/angularjs-slider) project.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Slider examples](#slider-examples)
* [Slider properties](#slider-properties)
  * [Function properties](#function-properties)
* [Custom types](#custom-types)
  * [Gradient type](#gradient-type)
* [Slider events](#slider-events)
* [Slider API](#slider-api)
* [Custom styling](#custom-styling)

## Slider examples

Here is a screenshot of a form with a few sliders in action:

![Slider screenshot](/files/ddLNKFisqUy9qn5VhDez)

## Slider properties

Slider properties can be found [here](/reference/servoyextensions/ui-components/input-control/slider#properties).

### Function properties

Some properties above are named "Function" that take a string with the full function definition. Please not that a function reference to a Servoy function will not work (something like forms.abc.myMethod).

These functions are sent to the client as such and will execute client side. This reduces the roundtrips to the server.

Here is an example of the `formattingFunction` that will divide each value by 1000 and display values with 1 decimal and a 'k' at the end, while tick values show without decimals:

```javascript
function formatValue(value, type) { 	
	value = value / 1000;
	if (type === 'value' || type === 'high') {
		return numberFormat(value, '#,###.0') + 'k'; 
	} else {
		return numberFormat(value, '#,###') + 'k'; 
	}
}
```

**Note:** the example method above calls a method `numberFormat` which formats a number with the given Servoy format. This method is always present client side and can be called by any function provided to the component.

This function has been entered in designer as a string as shown below:

![Developer function](/files/vl1hYRag1xbrCk9rbqlB)

## Custom types

### Gradient type

Gradient properties can be found [here](/reference/servoyextensions/ui-components/input-control/slider#gradient).

## Slider events

Slider events can be found [here](/reference/servoyextensions/ui-components/input-control/slider#events).

## Slider API

Slider API methods can be found [here](/reference/servoyextensions/ui-components/input-control/slider#api).

## Custom styling

The Slider component consists of one `<div>` containing the slider element. The outer div has the `svy-slider-container` class attached, while the slider itself can be addressed using the `svy-slider` class and/or the ones that were set via the styleClass property.

To address single items of the slider, these classes can be used:

| element selector        | summary        |
| ----------------------- | -------------- |
| .svy-slider .rz-bar     | the slider bar |
| .svy-slider .rz-pointer | the pointer    |
| .svy-slider .rz-tick    | a tick         |
| .svy-slider .rz-bubble  | a label bubble |

## Related Articles

The following articles are recommended for additional reading

* [Slider Reference Documentation](/reference/servoyextensions/ui-components/input-control/slider)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Switch

Guide for using Switch in your applications

## Overview

This guide will show how to use Switch in your applications. See how easy it is to drag and drop switches onto your forms and connect them to your business logic. Switch can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=switchButton).

## Get Started

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Switch component from the Pallet onto the form.

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Bootstrap Extra Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Switch at Design-Time

Switch, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the Switch in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

{% hint style="info" %}
See the reference docs for [Switch](/reference/servoyextensions/ui-components/input-control/switch) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/switch#properties).
{% endhint %}

### Setting the animate

The animate property can be set on true or false. To apply this property on the webpage you need to check or uncheck the box depends on your preferences.

### Setting the componentSize

In case you want to change the size of the switch button you have 4 types of size that you can change in js file dinamically or hardcode in the property.

### Setting the dataProvider

The column or variable to provide the data for this label.

### Setting the onText/OffText

The text displayed on the sides of the button can be modified by setting its [`onText`](/reference/servoyextensions/ui-components/input-control/switch#ontext) property and [`offText`](/reference/servoyextensions/ui-components/input-control/switch#offtext) property. Most often, this will just be plain text for example on the left side "On" and on the right side "Off". In this case, just enter the value into the editor or directly on the component by double-clicking it.

### Setting the label

The text displayed on the middle of the button can be modified by setting its [`label`](/reference/servoyextensions/ui-components/input-control/switch#label) property.

### Setting the labelWidth

You can adjust the width of the middle container of the switch button.

### Styling

Like all components, a Switch can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

### Setting the offColor/onColor

You can change the color of the off button or on button by selecting from properties from the dropdown a class that is predifined by servoy. Also, you can change the color from JS file hardcoded or dinamically but keep in mind that you need to assign those classes using **lowercase** not uppercase!

### Setting the onColor

You can adjust the width of the middle container of the switch button

## Handling Events

Like most components, switches have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a Switch is the `onDataChange` event, which is triggered when dataprovider is updated.

To handle the event, double-click the value for the `onDataChange` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the button's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * Handle changed data, return false if the value should not be accepted.
 * JSEvent.data will contain extra information about dataproviderid, its scope and the scope id (record datasource or form/global variable scope)
 *
 * @param oldValue
 * @param newValue
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"4A599FE8-D13D-4E4E-88AE-9B40DF8434F5"}
 */
function onDataChange(oldValue, newValue, event) {
	// Enter custom code
}
```

{% hint style="info" %}
See the [Switch reference](/reference/servoyextensions/ui-components/input-control/switch) for comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/switch#events)
{% endhint %}

## Modifying a Switch at Runtime

Switch, like many components, can be modified at runtime through code. Below are a few examples of controlling a Switch from code.

### Enabling / Disabling a Switch

You can easily change the `enabled` state of a Switch at runtime.

```javascript
function disableSwitch(){
	elements.mySwitch.enabled = false;
}
```

### Hiding/Showing a Switch

You can easily change the `visible` state of a Switch at runtime.

```javascript
function hideSwitch(){
	elements.mySwitch.visible = false;
}
```

## Calling Switch API Methods

Like most components, a Switch has API methods which can be called from code. Below is an example of common API calls.

### Give Keyboard Focus

Change this to match your component:

You can easily give keyboard focus to a Switch using the [`requestFocus`](/reference/servoyextensions/ui-components/input-control/switch#requestfocus) method.

```javascript
function focusSwitch(){
	elements.mySwitch.requestFocus();
}
```

### Add CSS Style Class

You can easily add a style class to a Switch using the `addStyleClass` method.

```javascript
function AddStyleClassSwitch(){
	elements.mySwitch.addStyleClass('mycssclass');
}
```

## Related Articles

The following articles are recommended for additional reading:

* [Switch Reference Documentation](/reference/servoyextensions/ui-components/input-control/switch)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Spinner

Guide for using Spinner in your applications

## Overview

This guide will show how to use a Spinner in your applications. A spinner can be used to select a value from a predefined set of values, which are usually presented in a valuelist. See how easy it is to drag and drop spinners onto your forms and connect them to your business logic. Spinner can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=spinner).

## Get Started

In the [Form Editor](/reference/servoy-developer/object-editors/form-editor), drag the Spinner component from the Pallet onto the form.

{% hint style="info" %}
If the component does not appear in the pallet, it means you do not have the Servot Extra Components package installed. Click "Get more components" at the top of the pallet to open the [Servoy Package Manager](/reference/servoy-developer/package-manager) and install it.
{% endhint %}

## Modifying a Spinner at Design-Time

Spinners, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the spinner in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

{% hint style="info" %}
See the reference docs for [Spinner](/reference/servoyextensions/ui-components/input-control/spinner) for a complete list of its [properties](/reference/servoyextensions/ui-components/input-control/spinner#properties).
{% endhint %}

### Selecting the Valuelist associated with the Spinner

The possible values of the spinner are the ones in the valuelist that is related to the component To select the valuelist just enter the name of the desired valuelist on the valuelist property of the spinner. More information about valuelists can be found [here](/guides/develop/application-design/data-modeling/value-lists).

### Setting the Tooltip message

Spinner, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

{% hint style="info" %}
Remember that text can also be dynamic, data-driven or localized. For more options, you can open edit the text property in the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).
{% endhint %}

### Styling

Like all components, a spinner can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

## Handling Events

Like most components, spinners have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a spinners is the `onDataChange` event, which is triggered when the value is changed.

To Handle the event, double-click the value for the `onDataChange` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the button's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * Handle changed data, return false if the value should not be accepted.
 * JSEvent.data will contain extra information about dataproviderid, its scope and the scope id (record datasource or form/global variable scope)
 *
 * @param oldValue
 * @param newValue
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"4A599FE8-D13D-4E4E-88AE-9B40DF8434F5"}
 */
function onDataChange(oldValue, newValue, event) {
	// Enter custom code
	return true
}
```

{% hint style="info" %}
See the [Spinner reference](/reference/servoyextensions/ui-components/input-control/spinner) for comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/spinner#events)
{% endhint %}

## Modifying a Spinner at Runtime

Spinner, like many components, can be modified at runtime through code. Below are a few examples of controlling a spinner from code.

### Enabling / Disabling a Spinner

You can easily change the `enabled` state of a spinner at runtime.

```javascript
function disableSpinner(){
	elements.mySpinner.enabled = false;
}
```

### Hiding/Showing a Spinner

You can easily change the `visible` state of a spinner at runtime.

```javascript
function hideSpinner(){
	elements.mySpinner.visible = false;
}
```

## Calling Spinner API Methods

Like most components, a spinner has API methods which can be called from code. Below is an example of common API calls.

### Give Keyboard Focus

You can easily give keyboard focus to a spinner using the [`requestFocus`](/reference/servoyextensions/ui-components/input-control/spinner#requestfocus) method.

```javascript
function focusSpinner(){
	elements.mySpinner.requestFocus();
}
```

### Add CSS Style Class

You can easily add a style class to a spinner using the `addStyleClass` method.

```javascript
function AddStyleClassSpinner(){
	elements.mySpinner.addStyleClass('mycssclass');
}
```

## Related Articles

The following articles are recommended for additional reading:

* [Spinner Reference Documentation](/reference/servoyextensions/ui-components/input-control/spinner)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# TextArea

Shows a dataprovider in a multiline editable text box.

![Text area](/files/gD5SzW0Ea8nJ2OUb48X0)

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=textarea).

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Text area properties](#text-area-properties)
* [Text area events](#text-area-events)
* [Text area API](#text-area-api)

## Text area properties

Text area properties can be found [here](/reference/servoyextensions/ui-components/input-control/textarea#properties).

## Text area events

Text area events can be found [here](/reference/servoyextensions/ui-components/input-control/textarea#events).

## Text area API

Text area API methods can be found [here](/reference/servoyextensions/ui-components/input-control/textarea#api).

## Related Articles

The following articles are recommended for additional reading

* [Text area Reference Documentation](/reference/servoyextensions/ui-components/input-control/textarea)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Textbox

Guide for using textbox in your applications

## Overview

This guide will show how to use textbox in your applications. See how easy it is to drag and drop textbox onto your forms and connect them to your business logic. textbox can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=textbox).

## Get Started

## Modifying a textbox at Design-Time

Textbox, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the textbox in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

### Setting the placeholderText

The text displayed inside the textbox can be modified by setting its [`placeholderText`](/reference/servoyextensions/ui-components/input-control/textbox#placeholdertext) property. This will just be plain text which will be shown as an instruction on what you can do within the textbox. When you insert a value in the textbox the placeholderText will disappear and your inserted text will take it's place. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the tooltipText

TextBox, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Styling

Like all components, a textbox can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

## Handling Events

Like most components, textbox have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a textbox is the `onDataChange` event, which is triggered when the textbox is clicked or the user hits the `Enter` key while the textbox has focus.

To Handle the event, double-click the value for the `onDataChange` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the TextBox's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"A74C281C-00AA-46AA-BB38-500C937F2D1A"}
 */
function onDataChange(event) {
	// Enter custom code
}
```

{% hint style="info" %}
See the [textbox reference](/reference/servoyextensions/ui-components/input-control/textbox) for comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/textbox#events)
{% endhint %}

## Modifying a textbox at Runtime

textbox, like many components, can be modified at runtime through code. Below are a few examples of controlling a textbox from code.

### Enabling / Disabling a textbox (delete/change if not the case)

You can easily change the `enabled` state of a textbox at runtime.

```javascript
function disableTextBox(){
	elements.myTextBox.enabled = false;
}
```

### Hiding/Showing a textbox (delete/change if not the case)

You can easily change the `visible` state of a textbox at runtime.

```javascript
function hideTextBox(){
	elements.myTextBox.visible = false;
}
```

## Calling textbox API Methods

Like most components, a textbox has API methods which can be called from code. Below is an example of common API calls.

### Give Keyboard Focus ()

You can easily give keyboard focus to a textbox using the [`requestFocus`](/reference/servoyextensions/ui-components/input-control/textbox#requestfocus) method.

```javascript
function focusTextBox(){
	elements.myTextBox.requestFocus();
}
```

### Add CSS Style Class ()

You can easily add a style class to a textbox using the `addStyleClass` method.

```javascript
function AddStyleClassTextBox(){
	elements.myTextBox.addStyleClass('mycssclass');
}
```

## Related Articles

The following articles are recommended for additional reading:

* [textbox Reference Documentation](/reference/servoyextensions/ui-components/input-control/textbox)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes/font-icons)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# TextBoxGroup

Guide for using textboxGroup in your applications

## Overview

This guide will show how to use textboxGroup in your applications. See how easy it is to drag and drop textboxGroup onto your forms and connect them to your business logic. textboxGroup can be modified, styled and even changed at runtime.

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=textBoxGroup).

## Get Started

## Modifying a textboxGroup at Design-Time

textboxGroup, like all components, have properties which can be modified at design-time to set the appearance and behavior of the component. Select the textboxGroup in the [Form Editor](/reference/servoy-developer/object-editors/form-editor) to see a list of properties in the [Component Properties Editor](/reference/servoy-developer/views/properties#properties). Below are some common properties and how to set them at design-time.

### Setting the placeholderText

The text displayed inside the textboxGroup can be modified by setting its [`placeholderText`](/reference/servoyextensions/ui-components/input-control/textbox-group#placeholdertext) property. This will just be plain text which will be shown as an instruction on what you can do within the textbox. When you insert a value in the textboxGroup the placeholderText will disappear and your inserted text will take it's place. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the faclass

The icon attached on the textbox can be changed from [`faclass`](/reference/servoyextensions/ui-components/input-control/textbox-group#faclass) property. You can use different icons from fontawosome. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the inputType

The inputType of the textbox and be changed from [`inputType`](/reference/servoyextensions/ui-components/input-control/textbox-group#inputtype) property. Here we have two types, text and password. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Setting the tooltipText

TextBoxGroup, like many components, can display tooltip messages when a user hovers their cursor. Most often, this will just be plain text that describes what will happen on-click. In this case, just enter the value into the editor. For more options open the [Text Property Editor](/reference/servoy-developer/object-editors/text-property-editor).

### Styling

Like all components, a textboxGroup can be styled using themes, variants and raw CSS. To apply any available style class, simply enter one or more space-delimited values for the `styleClass` property.

## Handling Events

Change this to match your component - if the case:

Like most components, textboxGroup have events, which allow you to execute some logic when something happens in the UI. Of course, the most common event for a textboxGroup is the `onDataChange` event, which is triggered when the textboxGroup is clicked or the user hits the `Enter` key while the textboxGroup has focus.

To Handle the event, double-click the value for the `onDataChange` property in the [Properties Editor](https://github.com/Servoy/gitbook/blob/master/reference/servoy-developer/views/component-properties-editor.md). You will see the [Method Selection Wizard](/reference/servoy-developer/object-editors/method-selection-wizard). You'll have the option select an existing Method or create a new Method. The method will be called when the TextBoxGroup's `onDataChange` event is fired and the [Event](/reference/servoycore/dev-api/application/jsevent) object will be passed to it.

```javascript
/**
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"A74C281C-00AA-46AA-BB38-500C937F2D1A"}
 */
function onDataChange(event) {
	// Enter custom code
}
```

{% hint style="info" %}
See the [textboxGroup reference](/reference/servoyextensions/ui-components/input-control/textbox-group) for comprehensive list of [all events](/reference/servoyextensions/ui-components/input-control/textbox-group#events)
{% endhint %}

## Modifying a textboxGroup at Runtime

textboxGroup, like many components, can be modified at runtime through code. Below are a few examples of controlling a textboxGroup from code.

### Enabling / Disabling a textboxGroup (delete/change if not the case)

You can easily change the `enabled` state of a textboxGroup at runtime.

```javascript
function disableTextBoxGroup(){
	elements.myTextBoxGroup.enabled = false;
}
```

### Hiding/Showing a textboxGroup (delete/change if not the case)

You can easily change the `visible` state of a textboxGroup at runtime.

```javascript
function hideTextBoxGroup(){
	elements.myTextBoxGroup.visible = false;
}
```

## Calling textboxGroup API Methods

Like most components, a textboxGroup has API methods which can be called from code. Below is an example of common API calls.

### Give Keyboard Focus ()

You can easily give keyboard focus to a textboxGroup using the [`requestFocus`](/reference/servoyextensions/ui-components/input-control/textbox-group#requestfocus) method.

```javascript
function focusTextBoxGroup(){
	elements.myTextBoxGroup.requestFocus();
}
```

### Add CSS Style Class ()

You can easily add a style class to a textboxGroup using the `addStyleClass` method.

```javascript
function AddStyleClassTextBoxGroup(){
	elements.myTextBoxGroup.addStyleClass('mycssclass');
}
```

## Related Articles

The following articles are recommended for additional reading:

* [textboxGroup Reference Documentation](/reference/servoyextensions/ui-components/input-control/textbox-group)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Type Ahead

A text field that offers values from a provided value list, filtering the list as the user starts typing.

![Type ahead](/files/F222Liqj3YlcwG7jAuPo)

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Type ahead properties](#type-ahead-properties)
* [Type ahead events](#type-ahead-events)
* [Type ahead API](#type-ahead-api)

## Type ahead properties

Type ahead properties can be found [here](/reference/servoyextensions/ui-components/input-control/type-ahead#properties).

## Type ahead events

Type ahead events can be found [here](/reference/servoyextensions/ui-components/input-control/type-ahead#events).

## Type ahead API

Type ahead API methods can be found [here](/reference/servoyextensions/ui-components/input-control/type-ahead#api).

## Related Articles

The following articles are recommended for additional reading

* [Type Ahead Reference Documentation](/reference/servoyextensions/ui-components/input-control/type-ahead)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# select2tokenizer

Since V1.1.0

Select2Tokenizer is a component which allow the user to select multiple values as 'tokens' from a search field. The component is implemented on top of the [Select2](https://select2.github.io/examples.html#tokenizer) library.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Styling Select2Tokenizer](#styling-select2tokenizer)
* [Select2Tokenizer Properties](#select2tokenizer-properties)
* [Select2Tokenizer Events](#select2tokenizer-events)
* [Select2Tokenizer API](#select2tokenizer-api)

## Styling Select2Tokenizer

The component has it's own CSS selector to be used for the restyle of the component. Note that fine-grained styling of the component is depending on the internal selectors of the select2 libary

| element selector                     | summary                                   |
| ------------------------------------ | ----------------------------------------- |
| .svy-select2-autotokenizer           | style the select2tokenizer                |
| .svy-select2-autotokenizer-container | style the select2tokenizer tags container |
| .svy-select2-autotokenizer-dropdown  | style the select2tokenizer dropdown       |

#### Sizing

To adjust the Select2Tokenizer size, apart from stylying the component with your own CSS, you can use one the control size classes; the Select2Tokenizer offers 4 control size classes. Please note that each size class requires a certain height of the component for nice stylying and to avoid vertical scrollbars. To use the size classes just add one of them into the component's styleClass property. Default size class is select2-sm.

| size class | min-height | font-size |
| ---------- | :--------: | --------- |
| select2-xs |    20px    | 12px      |
| select2-sm |    32px    | 14px      |
| select2-md |    36px    | 16px      |
| select2-lg |    44px    | 18px      |

## Select2Tokenizer Properties

Select2Tokenizer properties can be found [here](/reference/servoyextensions/ui-components/input-control/select2tokenizer#properties).

## Select2Tokenizer Events

Select2Tokenizer events can be found [here](/reference/servoyextensions/ui-components/input-control/select2tokenizer#events).

## Select2Tokenizer API

Select2Tokenizer API methods can be found [here](/reference/servoyextensions/ui-components/input-control/select2tokenizer#api).

## Related Articles

The following articles are recommended for additional reading

* [Select2Tokenizer Reference Documentation](/reference/servoyextensions/ui-components/input-control/select2tokenizer)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Media


# Carousel

The Carousel component offers a simple carousel to show several images in a slide show

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Carousel properties](#carousel-properties)
* [Slide type](#slide-type)
* [cssProperty type](#cssproperty-type)
* [Carousel events](#carousel-events)
* [Carousel API](#carousel-api)

## Carousel properties

Carousel properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

### Slide type

Slide properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

### cssProperty type

cssProperty properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Carousel events

Carousel events can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Carousel API

Carousel API methods can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Related Articles

The following articles are recommended for additional reading

* [Carousel Reference Documentation](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Embedded YouTube

This components allows you to easily embed YouTube videos both at design-time (properties view) and runtime (elements.my\_embed\_componen.embeddedVideoURL = "<https://www.youtube.com/embed/>...").

In designer it will not load/show the video; it just shows a logo and play button.

Some video options can be configured like autoplay, showControls, allowFullScreen ... More options (or even API/handler support) can be added in the future to the component - as needed.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Youtube video player properties

Youtube video player properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Related Articles

The following articles are recommended for additional reading

* [Embedded YouTube Reference Documentation](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# File upload

Single file upload component. File content will be saved in the dataprovider.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Getting uploaded file name and mime type](#getting-uploaded-file-name-and-mime-type)
* [File upload properties](#file-upload-properties)
* [File upload events](#file-upload-events)

## Getting uploaded file name and mime type

To get the name and mime type of the uploaded file, you need to create form variables, on the component's parent form, with the following names, 'dataprovider\_filename' and 'dataprovider\_mimetype', where 'dataprovider' is the dataprovider name of the component. These form variables will be filled with the right values after the file is uploaded. Ex.: you have a fileupload component, with dataprovider : 'picture', after the upload, if the form variables 'picture\_filename' and 'picture\_mimetype' exits, they will have the uploaded file name and mime type.

## File upload properties

File upload properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## File upload events

File upload events can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Related Articles

The following articles are recommended for additional reading

* [File upload Reference Documentation](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Image label

A basic component for displaying an image from media library in html img tag. This component also supports svg images but doesn't support text.

NOTE: For svg images, we are seeing some issues with files which start with xml tag instead of svg. As soon as xl tag is removed the images display fine.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Image label properties](#image-label-properties)
* [Image label events](#image-label-events)

## Image label properties

Image label properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Image label events

Image label events can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Related Articles

The following articles are recommended for additional reading

* [Image label Reference Documentation](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Lightbox Gallery

Since version v1.6.0

Lightbox Gallery shows a gallery of images and allows to overlay images on top of the current page. It works in all modern Browsers.

It can be used both in responsive and non responsive forms.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Lightbox Gallery properties](#lightbox-gallery-properties)
* [Lightbox Gallery events](#lightbox-gallery-events)
* [Lightbox Gallery API](#lightbox-gallery-api)

## Lightbox Gallery Properties

Lightbox Gallery properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Lightbox Gallery Events

Lightbox Gallery events can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Lightbox Gallery API

Lightbox Gallery API methods can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Related Articles

The following articles are recommended for additional reading

* [Lightbox Gallery Reference Documentation](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# MultiFile Upload

Added in version v2.0.0

The MultiFile Upload component is a slick and powerful file uploader. It allows users to drag and drop (or select) a number of files and review them before upload. The component supports several languages, meta fields that allow users to enter additional information for each file, file restrictions and an extensive API and events to interact with the component.

<figure><img src="/files/0wBuZKrT6wNlU0SqWxIT" alt=""><figcaption><p>MultiFile Upload demo</p></figcaption></figure>

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Getting started](#getting-started)
* [MultiFile Upload properties](#multifile-upload-properties)
* [Custom types](#custom-types)
  * [uploadRestriction type](#uploadrestriction-type)
  * [metaField type](#metafield-type)
  * [uploadFile type](#uploadfile-type)
  * [progress type](#progress-type)
* [MultiFile Upload events](#multifile-upload-events)
* [MultiFile Upload API](#multifile-upload-api)
* [MultiFile Localization](#multifile-localization)

## Getting started

To get started with the MultiFile Upload component, drag the component on a form and attach a method to the [onFileUploaded](#multifile-upload-events) event. Whenever a file is completely uploaded to the server, this method is fired and receives a [JSUpload](/reference/servoycore/dev-api/application/jsupload) object as argument. From that you can get the bytes of the file uploaded, its name, content type etc.

The component can either be shown as a "drop zone" on the form or as a modal dialog. This is controlled via the [inline property](#multifile-upload-properties). When `true`, the component will render a UI on the form, when `false`, nothing will be rendered on the form and the component needs to be opened as a modal via the [openModal()](#multifile-upload-api) API call.

## MultiFile Upload properties

MultiFile Upload properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## Custom types

Custom types can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

### uploadRestriction type

Optionally, provide rules and conditions to limit the type and/or number of files that can be selected and it is used on the restrictions property of the component.

uploadRestriction properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

maxNumberOfFiles also affects the number of files a user is able to select via the system file dialog in UI plugins like DragDrop, FileInput and Dashboard: when set to 1, they will only be able to select a single file. When null or another number is provided, they will be able to select multiple files.

### metaField type

Meta fields can be added to the component and will be shown when a user clicks the "edit" button on a specific file. Adding meta fields enables the "edit" button on file cards.

metaField properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

### uploadFile type

uploadFiles can be retrieved via the getFiles() or getFile(fileID) API calls or will be passed as parameter to some of the handlers of the component.

metaField properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

### progress type

An object detailing a file's transfer progress.

progress properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## MultiFile Upload events

MultiFile Upload events can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## MultiFile Upload API

MultiFile Upload API methods can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md).

## MultiFile Localization

To localize the component, use the `language` property to choose among any of the shipped languages. If you want to translate single strings differently or provide a full own translation, you can use the localeStrings property to provide those translations.

Below you find all keys and their English translation for reference. Please note that some keys are nested in a complex object, such as

```javascript
`filesUploadedOfTotal: {`
`'0': '%{complete} of %{smart_count} file uploaded',`
`'1': '%{complete} of %{smart_count} files uploaded',`
`'2': '%{complete} of %{smart_count} files uploaded'`
`}`
```

For this to work properly, you have to provide the property of the nested object directly with the key, separated with a dot as in

```javascript
`filesUploadedOfTotal.0 = '%{complete} of %{smart_count} file uploaded'`
`filesUploadedOfTotal.1 = '%{complete} of %{smart_count} files uploaded'`
`filesUploadedOfTotal.2 = '%{complete} of %{smart_count} files uploaded'`
```

### Localization keys

Here is a list of all keys and their English translation defaults:

**addMore** - *'Add more'*\
**addMoreFiles** - *'Add more files'*\
**addingMoreFiles** - *'Adding more files'*\
**allowAccessDescription** - *'In order to take pictures or record video with your camera, please allow camera access for this site.'*\
**allowAccessTitle** - *'Please allow access to your camera'*\
**authenticateWith** - *'Connect to %{pluginName}'*\
**authenticateWithTitle** - *'Please authenticate with %{pluginName} to select files'*\
**back** - *'Back'*\
**browse** - *'browse'*\
**cancel** - *'Cancel'*\
**cancelUpload** - *'Cancel upload'*\
**chooseFiles** - *'Choose files'*\
**closeModal** - *'Close Modal'*\
**companionAuthError** - *'Authorization required'*\
**companionError** - *'Connection with Companion failed'*\
**companionUnauthorizeHint** - *'To unauthorize to your %{provider} account, please go to %{url}'*\
**complete** - *'Complete'*\
**connectedToInternet** - *'Connected to the Internet'*\
**copyLink** - *'Copy link'*\
**copyLinkToClipboardFallback** - *'Copy the URL below'*\
**copyLinkToClipboardSuccess** - *'Link copied to clipboard'*\
**creatingAssembly** - *'Preparing upload...'*\
**creatingAssemblyFailed** - *'Transloadit'*\
**dashboardTitle** - *'File Uploader'*\
**dashboardWindowTitle** - *'File Uploader Window (Press escape to close)'*\
**dataUploadedOfTotal** - *'%{complete} of %{total}'*\
**done** - *'Done'*\
**dropHereOr** - *'Drop files here or %{browse}'*\
**dropHint** - *'Drop your files here'*\
**dropPaste** - *'Drop files here, paste or %{browse}'*\
**dropPasteImport** - *'Drop files here, paste, %{browse} or import from'*\
**edit** - *'Edit'*\
**editFile** - *'Edit file'*\
**editing** - *'Editing %{file}'*\
**emptyFolderAdded** - *'No files were added from empty folder'*\
**encoding** - *'Encoding...'*\
**enterCorrectUrl** - *'Incorrect URL'*\
**enterUrlToImport** - *'Enter URL to import a file'*\
**exceedsSize** - *'This file exceeds maximum allowed size of'*\
**failedToFetch** - *'Companion failed to fetch this URL, please make sure it's correct'*\
**failedToUpload** - *'Failed to upload %{file}'*\
**fileSource** - *'File source'*\
**filesUploadedOfTotal.0** - *'%{complete} of %{smart\_count} file uploaded'* **filesUploadedOfTotal.1** - *'%{complete} of %{smart\_count} files uploaded'*\
**filesUploadedOfTotal.2** - *'%{complete} of %{smart\_count} files uploaded'*\
**filter** - *'Filter'*\
**finishEditingFile** - *'Finish editing file'*\
**folderAdded.0** - *'Added %{smart\_count} file from %{folder}'*\
**folderAdded.1** - *'Added %{smart\_count} files from %{folder}'*\
**folderAdded.2** - *'Added %{smart\_count} files from %{folder}'*\
**generatingThumbnails** - *'Generating thumbnails...'*\
**import** - *'Import'*\
**importFrom** - *'Import from %{name}'*\
**link** - *'Link'*\
**loading** - *'Loading...'*\
**logOut** - *'Log out'*\
**myDevice** - *'My Device'*\
**noFilesFound** - *'You have no files or folders here'*\
**noInternetConnection** - *'No Internet connection'*\
**openFolderNamed** - *'Open folder %{name}'*\
**pause** - *'Pause'*\
**pauseUpload** - *'Pause upload'*\
**paused** - *'Paused'*\
**poweredBy** - *'Powered by'*\
**preparingUpload** - *'Preparing upload...'*\
**processingXFiles.0** - *'Processing %{smart\_count} file'*\
**processingXFiles.1** - *'Processing %{smart\_count} files'*\
**processingXFiles.2** - *'Processing %{smart\_count} files'*\
**removeFile** - *'Remove file'*\
**resetFilter** - *'Reset filter'*\
**resume** - *'Resume'*\
**resumeUpload** - *'Resume upload'*\
**retry** - *'Retry'*\
**retryUpload** - *'Retry upload'*\
**saveChanges** - *'Save changes'*\
**selectAllFilesFromFolderNamed** - *'Select all files from folder %{name}'*\
**selectFileNamed** - *'Select file %{name}'*\
**selectX.0** - *'Select %{smart\_count}'*\
**selectX.1** - *'Select %{smart\_count}'*\
**selectX.2** - *'Select %{smart\_count}'*\
**smile** - *'Smile!'*\
**startRecording** - *'Begin video recording'*\
**stopRecording** - *'Stop video recording'*\
**takePicture** - *'Take a picture'*\
**timedOut** - *'Upload stalled for %{seconds} seconds, aborting.'*\
**unselectAllFilesFromFolderNamed** - *'Unselect all files from folder %{name}'*\
**unselectFileNamed** - *'Unselect file %{name}'*\
**upload** - *'Upload'*\
**uploadComplete** - *'Upload complete'*\
**uploadFailed** - *'Upload failed'*\
**uploadPaused** - *'Upload paused'*\
**uploadXFiles.0** - *'Upload %{smart\_count} file'*\
**uploadXFiles.1** - *'Upload %{smart\_count} files'*\
**uploadXFiles.2** - *'Upload %{smart\_count} files'*\
**uploadXNewFiles.0** - *'Upload +%{smart\_count} file'*\
**uploadXNewFiles.1** - *'Upload +%{smart\_count} files'*\
**uploadXNewFiles.2** - *'Upload +%{smart\_count} files'*\
**uploading** - *'Uploading'*\
**uploadingXFiles.0** - *'Uploading %{smart\_count} file'*\
**uploadingXFiles.1** - *'Uploading %{smart\_count} files'*\
**uploadingXFiles.2** - *'Uploading %{smart\_count} files'*\
**xFilesSelected.0** - *'%{smart\_count} file selected'*\
**xFilesSelected.1** - *'%{smart\_count} files selected'*\
**xFilesSelected.2** - *'%{smart\_count} files selected'*\
**xMoreFilesAdded.0** - *'%{smart\_count} more file added'*\
**xMoreFilesAdded.1** - *'%{smart\_count} more files added'*\
**xMoreFilesAdded.2** - *'%{smart\_count} more files added'*\
**xTimeLeft** - *'%{time} left'*\
**youCanOnlyUploadFileTypes** - *'You can only upload'*\
**youCanOnlyUploadX.0** - *'You can only upload %{smart\_count} file'*\
**youCanOnlyUploadX.1** - *'You can only upload %{smart\_count} files'*\
**youCanOnlyUploadX.2** - *'You can only upload %{smart\_count} files'*\
**youHaveToAtLeastSelectX.0** - *'You have to select at least %{smart\_count} file'*\
**youHaveToAtLeastSelectX.1** - *'You have to select at least %{smart\_count} files'*\
**youHaveToAtLeastSelectX.2** - *'You have to select at least %{smart\_count} files'*

## Related Articles

The following articles are recommended for additional reading

* [MultiFile Upload Reference Documentation](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/media/broken-reference/README.md)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# PDF JS Viewer


# PDF Viewer


# Mobile


# Native Data List

Value list driven drop down using the html 'datalist' tag, useful for mobile apps to keep the native look and feel.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Native Data List properties](#native-data-list-properties)
* [Native Data List events](#native-data-list-events)
* [Native Data List API](#native-data-list-api)

## Native Data List properties

Native Data List properties can be found [here](/reference/servoyextensions/ui-components/mobile/native-data-list#properties).

## Native Data List events

Native Data List events can be found [here](/reference/servoyextensions/ui-components/mobile/native-data-list#events).

## Native Data List API

Native Data List API methods can be found [here](/reference/servoyextensions/ui-components/mobile/native-data-list#api).

## Related Articles

The following articles are recommended for additional reading

* [Native Data List Reference Documentation](/reference/servoyextensions/ui-components/mobile/native-data-list)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Native Select

![Native Select](/files/fOn6GQT7li7SmzwRZwdw)

The Native Select offers values from a provided value list in a dropdown list. When the value list offers display and return values, the return value is returned to the dataprovider. Note that if your value list does not have the "Allow empty value" check set, a user won't be able to empty the field anymore.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Table of contents

* [Native Select properties](#native-select-properties)
* [Native Select events](#native-select-events)
* [Native Select API](#native-select-api)

## Native Select properties

Native Select properties can be found [here](/reference/servoyextensions/ui-components/mobile/native-select#properties).

## Native Select events

Native Select events can be found [here](/reference/servoyextensions/ui-components/mobile/native-select#events).

## Native Select API

Native Select API methods can be found [here](/reference/servoyextensions/ui-components/mobile/native-select#api).

## Related Articles

The following articles are recommended for additional reading

* [Native Select Reference Documentation](/reference/servoyextensions/ui-components/mobile/native-select)
* [Styling and Themes](/guides/develop/application-design/styling-and-themes)
* [Scripting the UI](/guides/develop/programming-guide/scripting-the-ui)


# Navigation


# Breadcrumbs

## Overview

<div align="left"><figure><img src="/files/LvO6VMUT5J7fbSBQRWXj" alt=""><figcaption><p>Breadcrumbs demo</p></figcaption></figure></div>

**Breadcrumbs** in Servoy is a UI component used for navigation that provides a **trail of links representing the user's current location within the application**, usually in a hierarchical manner. This allows users to easily navigate back to previous forms or pages by clicking on the links in the breadcrumb trail.

The Breadcrumbs component wraps the standard [Bootstrap breadcrumbs](http://getbootstrap.com/components/#breadcrumbs) used to display navigational hierarchy.

Breadcrumbs are particularly useful in applications with a multi-level navigation structure or complex workflows, where users need to track where they are and how they reached the current page. They give users a quick way to backtrack to higher-level forms or sections of the application without using traditional back/forward buttons or re-navigating through the menus.

**Key Features of Breadcrumbs**:

* **Hierarchical Navigation**: Breadcrumbs display the user's navigation path in a hierarchical order. Each segment in the breadcrumb trail represents a form or a section, and users can click on any segment to go back to that point in the navigation history.
* **Improves User Experience**: Breadcrumbs make navigation more intuitive by providing users with a clear sense of their location within the application's hierarchy. This is especially helpful in applications with deep navigation layers or complex workflows.
* **Contextual Backtracking**: Unlike using a back button (which follows strict history order), breadcrumbs allow the user to jump back to any previous section in the hierarchy, making it easier to navigate to higher-level forms or modules. **Dynamic Generation**: Breadcrumbs are often generated dynamically based on the user's navigation history. Each time the user navigates to a new form, the breadcrumb trail updates to reflect the new location. **Customization**: Breadcrumb components in Servoy can be customized to fit the design and functionality of the application. You can choose the labels for each segment of the breadcrumb and control how they respond when clicked.

## Use Cases for Breadcrumbs

* **Hierarchical Applications**: In applications with a hierarchical structure, breadcrumbs help users understand their current location and navigate between different levels of the hierarchy. For example, in an e-commerce application, a breadcrumb might track the user's path from Home to Categories to a specific Product.
* **Multi-Step Processes**: Breadcrumbs can be used to guide users through a multi-step process, such as a wizard or checkout flow. The breadcrumbs visually represent each step, and users can click on previous steps to review or change information.
* **Drill-Down Navigation**: Breadcrumbs are useful when users are drilling down into data or categories. They allow users to easily retrace their steps back to higher-level categories or forms without having to use the back button or main navigation.

## Get Started

### Creating a Breadcrumbs component

<div align="left"><figure><img src="/files/WkldPULoI7gwkfeQmxgJ" alt=""><figcaption><p>Create a Breadcrumbs component</p></figcaption></figure></div>

Here are the steps for creating a Breadcrumbs component:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Breadcrumbs** component
2. Find **Breadcrumbs** in *Navigation* section in the components' pallet
3. Drag and drop the **Breadcrumbs** component in the desired place of the form
4. Set the crumbs; this can be done via [properties panel](#setting-the-crumbs-in-the-properties-panel)
5. Edit other [**Breadcrumbs** properties](/reference/servoyextensions/ui-components/navigation/breadcrumbs#properties) and [**Breadcrumbs crumb** properties](/reference/servoyextensions/ui-components/navigation/breadcrumbs#crumb)

### Setting the crumbs (in the properties panel)

<figure><img src="/files/alRLhpr90CbBetWZthpz" alt=""><figcaption><p>Adding and editing crumbs</p></figcaption></figure>

After dragging the component on the form, find the **Breadcrumbs** in the form editor, click it and proceed with the following steps:

1. Add a crumb. There are 2 ways of adding a crumb:
   1. Select the [`breadcrumbs`](/reference/servoyextensions/ui-components/navigation/breadcrumbs#breadcrumbs-1) property and click the `+` button in order to add a crumb. Next crumbs can be added the same way or by clicking the `+` button (`insert a new array item below`) of another crumb. You can change the crumbs' order by dragging them into the desired placed inside the **Breadcrumbs** (in the form editor).
   2. Drag and drop `crumb` component (of an **Breadcrumbs** in *Navigation* section in the components' pallet) into the **Breadcrumbs** component (in the form editor)
2. Expand the [`breadcrumbs`](/reference/servoyextensions/ui-components/navigation/breadcrumbs#breadcrumbs-1) property to see the list of crumbs. They are also shown in the **Breadcrumbs** component (in the form editor)
3. In order to edit each crumb, expand it or click the crumb name in the **Breadcrumbs** component (in the form editor) and set its [properties](/reference/servoyextensions/ui-components/navigation/breadcrumbs#crumb):
   1. Set an unique crumb id
   2. Set a display name corresponding to each id

{% hint style="info" %}
**Breadcrumbs crumb**\
It is necessary to set an unique id in the Breadcrumbs **crumb** [crumbID](/reference/servoyextensions/ui-components/navigation/breadcrumbs#crumb) property.\
Example: `home_page`.

If you do it in code:

```javascript
   /** @type {CustomType<bootstrapextracomponents-breadcrumbs.crumb>} */
   var newCrumb = {crumbId:'home_page', displayName:'Home'};
```

{% endhint %}

{% hint style="info" %}
**Building a Custom Trail**\
If your breadcrumb trail depends on **user choices or dynamic navigation**, you should **add crumbs one by one** using the [addCrumb()](#add-a-crumb) method. This ensures the trail accurately reflects the actual path taken through your application rather than a fixed, predefined structure.

```javascript
elements.breadcrumbs_steps.addCrumb({ crumbId: 'step1', displayName: 'Step 1' });
elements.breadcrumbs_steps.addCrumb({ crumbId: 'step2', displayName: 'Step 2' });
```

This approach is ideal for multi-step forms, wizard-style flows, or deep drill-down paths.
{% endhint %}

{% hint style="info" %}
**Predefined Crumbs Behavior**\
If you set the entire breadcrumb trail in one go in the properties panel or by using [setCrumbs()](#setting-the-crumbs), Servoy will **automatically highlight the last crumb as active**. This assumes the final item in the array represents the current page or view.

```javascript
elements.breadcrumbs_steps.setCrumbs([
  { crumbId: 'home', displayName: 'Home' },
  { crumbId: 'orders', displayName: 'Orders' },
  { crumbId: 'details', displayName: 'Details' } // this one will be shown as active
]);
```

To change this behavior dynamically, consider building the trail incrementally using [addCrumb()](#add-a-crumb) instead.
{% endhint %}

## Breadcrumbs Properties

You can find a list of Breadcrumbs **events** [here](/reference/servoyextensions/ui-components/navigation/breadcrumbs#properties).

### autoRemoveWhenClicked

When [autoRemoveWhenClicked](/reference/servoyextensions/ui-components/navigation/breadcrumbs#autoremovewhenclicked) property is selected, then any crumbs that come after it will be automatically removed from the breadcrumb trail.\
This behavior is useful in scenarios where the breadcrumb trail represents a linear progression, such as a step-by-step workflow or a history path that should reset when the user navigates back to a previous point. When set to true, it mimics the behavior of "going back and discarding forward history," ensuring the trail stays relevant and doesn't display steps that are no longer active.

## Scripting Breadcrumbs

### Main events

You can find a list of Breadcrumbs **events** [here](/reference/servoyextensions/ui-components/navigation/breadcrumbs#events).\
You can find a list of Breadcrumbs **API methods** [here](/reference/servoyextensions/ui-components/navigation/breadcrumbs#api).

### onCrumbClicked

This event is called when a breadcrumb item is clicked.\
Here is an example of how to use the [onCrumbClicked](/reference/servoyextensions/ui-components/navigation/breadcrumbs#oncrumbclicked) event of Breadcrumbs in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):

Let's consider the following setup:

* `main_form`: the form where the Breadcrumbs component is placed, together with a [form container](/guides/develop/application-design/forms/form-containers/form-container#overview) component, `fc_crumb_form`
  * Breadcrumbs component will get the following crumbs:
    * `crumb`:`customers`, `displayName`:`Customers page`
    * `crumb`:`orders`, `displayName`:`Orders page`
    * `crumb`:`order_details`, `displayName`:`Order details page`
* separate forms showed in `main_form` as a contained form in the form container component: `customers`, `orders`, `order_details`.

The following goes on `main_form` script file:

```javascript
/**
 * Called whenever a breadcrumb item is clicked with the JSEvent and the item clicked on.
 *
 * @param {JSEvent} event
 * @param {CustomType<bootstrapextracomponents-breadcrumbs.crumb>} crumb
 * @param {Number} index
 *
 * @private
 *
 * @properties={typeid:24,uuid:"5289032B-AF76-4E73-BB04-65061E0CAA6D"}
 */
function onCrumbClicked(event, crumb, index) {
elements.fc_crumb_form.containedForm = forms[crumb.crumbId]; // crumb is an object; crumb.crumbId gets the value of the clicked crumb ID
}
```

### Add a crumb

Here is an example of how to programmatically add a crumb in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [addCrumb](/reference/servoyextensions/ui-components/navigation/breadcrumbs#addcrumb) API:

```javascript
/**
 * 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:"62F000BF-9C8E-4E42-88D4-D4CFBAEB7AC5"}
 */
function onShow(firstShow, event) {
	elements.breadcrumbs_steps.addCrumb({crumbId:"products", displayName:"Products page"}); // adds a crumb at the end, having id = `products` and displayed text "Products page"
}
```

### Remove a crumb after a certain index

Here is an example of how to programmatically remove a crumb after a certain index in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [removeCrumbsAfter](/reference/servoyextensions/ui-components/navigation/breadcrumbs#removecrumbsafter) API:

```javascript
/**
 * 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:"62F000BF-9C8E-4E42-88D4-D4CFBAEB7AC5"}
 */
function onShow(firstShow, event) {
	elements.breadcrumbs_steps.removeCrumbsAfter(1); // index starts at 0, so in this case only the first 2 crumbs will be displayed
}
```

### Remove the last crumb

Here is an example of how to programmatically remove the last crumb in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [removeLastCrumb](/reference/servoyextensions/ui-components/navigation/breadcrumbs#removelastcrumb) API:

```javascript
/**
 * 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:"62F000BF-9C8E-4E42-88D4-D4CFBAEB7AC5"}
 */
function onShow(firstShow, event) {
	elements.breadcrumbs_steps.removeLastCrumb(); // removes the last crumb
}
```

### Setting the crumbs

Here is an example of how to programmatically set the crumbs in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [setCrumbs](/reference/servoyextensions/ui-components/navigation/breadcrumbs#setcrumbs) API:

```javascript
/**
 * 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:"62F000BF-9C8E-4E42-88D4-D4CFBAEB7AC5"}
 */
function onShow(firstShow, event) {
	elements.breadcrumbs_steps.setCrumbs([{crumbId:"customers", displayName:"Customers page"}, {crumbId:"orders", displayName:"Orders page}, {crumbId:"order_details", displayName:"Order details page"}, {crumbId:"products", displayName:"Products page"}]); 
}
```


# Navbar

## Overview

<div align="left"><figure><img src="/files/qKSTs79Yb4IykGrbluHa" alt=""><figcaption><p>Navbar demo</p></figcaption></figure></div>

A **Navbar** in Servoy is a **horizontal navigation bar** typically placed at the top of the application interface. It is used to provide users with quick access to major sections or features of the application. The navbar often contains links or buttons that allow users to navigate between different forms or pages in a consistent and intuitive manner.

Navbars are commonly used in applications to enhance user experience by offering easy access to global navigation options like `Home`, `Dashboard`, `Settings`, and more. They can also contain additional elements like dropdowns, search fields, and icons for notifications, user profiles, or other utility actions.

The Navbar component wraps a bootstrap navbar (see [here](https://getbootstrap.com/docs/5.3/components/navbar/) for details) into a component usable directly from within Servoy.

**Key Features of a Navbar**:

* **Horizontal Layout**: The navbar provides a horizontal layout for navigation items, usually placed at the top of the application. This layout ensures that major sections of the application are always visible and accessible.
* **Navigation Links**: The navbar contains buttons or links that allow users to navigate to different forms or sections of the application. These links can represent different views or modules, such as Dashboard, Reports, or Settings.
* **Dropdown Menus**: The navbar can include dropdown menus for nested or grouped navigation options. This is useful when you want to offer multiple related options under a single menu item, such as user settings or report types.
* **Search Field**: Navbars often include a search input field to allow users to quickly search through the application or specific data, providing a more comprehensive and functional navigation experience.
* **Utility Icons**: Navbars may also include icons for additional utilities such as notifications, messages, or profile settings. These icons typically have contextual dropdowns or links associated with them.
* **Responsive Design**: In responsive layouts, the navbar can adapt to different screen sizes, collapsing into a hamburger menu on smaller screens to save space while still providing easy access to the navigation items.

## Use Cases for Navbar

* **Global Application Navigation**: In applications with global sections (e.g., Dashboard, Reports, Settings), the navbar provides quick access to these areas while maintaining consistency across the interface.
* **Modular Systems**: For modular systems like admin dashboards or content management systems, the navbar allows users to easily switch between modules or sections.
* **User Profile and Utility Actions**: The navbar is ideal for placing user-related actions like profile management, notifications, settings, and logout. These can be accessed through icons or dropdowns.
* **Responsive Applications**: In responsive applications, the navbar can collapse into a hamburger menu for mobile or tablet users, making navigation accessible without taking up too much screen space.

## Get Started

### Creating a Navbar component

<div align="left"><figure><img src="/files/4jYaXauKUnItxmSzKoxn" alt=""><figcaption><p>Create a Navbar</p></figcaption></figure></div>

Here are the steps for creating a Navbar:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Navbar** component
2. Find **Navbar** in *Navigation* section in the components' pallet
3. Drag and drop the **Navbar** component in the desired place of the form
4. Set the menu items; this can be done via [properties panel](#setting-the-menu-items-in-the-properties-panel)
5. Edit other [**Navbar** properties](/reference/servoyextensions/ui-components/navigation/navbar#properties) and [**Navbar menu item** properties](/reference/servoyextensions/ui-components/navigation/navbar#menuitem)

***

{% hint style="info" %}
**Hint**

<img src="/files/S6MqqyOsivKu89p3o9ZH" alt="Create a Navbar through a Servoy Menu" data-size="original">

In case there is an existing [Servoy Menu](/guides/develop/application-design/data-modeling/menu#overview) that will be used as a Navbar menu, then here are the steps to be followed:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Navbar** component
2. Find the desired Servoy Menu name in the *Servoy Menu* section in the components' palette
3. Drag and drop the desired Servoy Menu name in the form. This will open the [JSMenu compatible component selector](/reference/servoy-developer/object-editors/jsmenu-compatible-component-selector#overview)
4. Select `Navbar[bootstrapextracomponents]` option, then click `OK`. This will add to the main form a Sidenav component having the desired Servoy Menu name set for [servoyMenu](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu) property of the component
5. Configure [**Navbar** properties](/reference/servoyextensions/ui-components/navigation/navbar#properties) in the component's properties panel. If needed, you can change or remove the assigned [servoyMenu](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu). In this case, you must manually configure the [**Navbar menu item** properties](/reference/servoyextensions/ui-components/navigation/navbar#menuitem).
   {% endhint %}

## Setting the Menu

The **Navbar** component supports two ways to configure its menu:

1. **Using** [**`servoyMenu`**](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu) **property**: Assign a predefined [servoyMenu](/guides/develop/application-design/data-modeling/menu#overview) for centralized menu management.
2. **Using** [**`menu`**](/reference/servoyextensions/ui-components/navigation/navbar#menuitems) **property**: Manually define menu items directly inside the component.

{% hint style="info" %}
**Using either a manually configured menu or servoyMenu will not change the appearance of the Navbar.**\
Both methods result in the **same** UI layout, styling, and interactions, including menu item rendering, nested structures, icons, and animations. The only difference is in how the menu items are configured and managed.
{% endhint %}

{% hint style="danger" %}
**IMPORTANT!**\
If **both methods** are used, the manually configured menu **will take precedence**, and the **servoyMenu will be ignored**.
{% endhint %}

### Assigning an existing servoyMenu

Instead of configuring the menu manually, you can assign a **predefined** [**servoyMenu**](/guides/develop/application-design/data-modeling/menu#overview) in Navbar [`servoyMenu`](/reference/servoyextensions/ui-components/navigation/navbar#servoymenu) property, which allows you to:

* Centrally manage menus across multiple components.
* Easily update menus without modifying individual Sidenav components.
* Use the same menu structure in different parts of the application.

To assign a `servoyMenu`:

1. In the Properties Panel of the **Navbar** component, locate the [`servoyMenu`](/reference/servoyextensions/ui-components/navigation/navbar#servoymenu) property and click on its value. This will open the [Servoy Menu Selection Wizard](/reference/servoy-developer/object-editors/menu-selection-wizard#overview)
2. Select an existing `servoyMenu` from the list.
3. When a `servoyMenu` is assigned, its menu items are automatically applied to the Navbar component.

### Setting the menu items in the properties panel

<figure><img src="/files/77Jdkmi5frlU0j2Pm8oM" alt=""><figcaption><p>Adding and editing menu items and sub menu items</p></figcaption></figure>

You can configure menu items directly in the **Navbar** [**`menuItems`**](/reference/servoyextensions/ui-components/navigation/navbar#menuitems) **property**. This allows fine-grained control over the menu structure, including:

* Adding menu items manually.
* Defining sub-menus (up to 4 levels deep).
* Setting icons, styles, and form associations.

After dragging the component on the form, find the **Navbar** in the form editor, click it and proceed with the following steps:

1. Add a menu item:
   * Select the [`menuItems`](/reference/servoyextensions/ui-components/navigation/navbar#menu) property and click the `+` button in order to add a menu item. Next menu item can be added the same way or by clicking the `+` button (`insert a new array item below`) of another menu item.
2. Expand the [`menuItems`](/reference/servoyextensions/ui-components/navigation/navbar#menu) property to see the list of menu items. They are also shown in the **Navbar** component (in the form editor)
3. In order to edit each menu item, expand it in the Properties Panel and set its [properties](/reference/servoyextensions/ui-components/navigation/navbar#menuitem)

{% hint style="info" %}
**Navbar menu items**\
It is necessary to set an unique id in the Navbar **menu item** [id](/reference/servoyextensions/ui-components/navigation/navbar#menuitem) property.\
Example: `home_page`.
{% endhint %}

## Working with Navbar

A Navbar is a simple navigation bar that offers:

* an optional branding logo on the left
* an optional branding text on the left
* two bars with any number of items
* plain texts
* single clickable menu entries
* dropdown menus showing a menu (one level)
* buttons
* text fields (optionally as type aheads)

One of the two bars is aligned to the left, the other to the right. Either one or both can be set.

Each item in the bar is a [MenuItem](#menuitem-type) javascript object with a `position` (`LEFT` or `RIGHT`) and a `displayType` (e.g. `BUTTON`) that controls how the single entry is displayed. Depending on the `displayType` a MenuItem's properties can have component specific meaning (for example the text property is used as placeholder text for an input field).

You can find a list of Navbar **properties** [here](/reference/servoyextensions/ui-components/navigation/navbar#properties).

### Setting the Brand

Navbar has a few properties that allow setting and customizing branding logo and text:

* [`brandLogo`](/reference/servoyextensions/ui-components/navigation/navbar#brandlogo): an optional media shown as branding logo in the upper left corner.
* [`brandLogoStyleClass`](/reference/servoyextensions/ui-components/navigation/navbar#brandlogostyleclass): optional style class(es) that can be added to the brandLogo media.
* [`brandLogoTabindex`](/reference/servoyextensions/ui-components/navigation/navbar#brandlogotabindex): sets the tab index for brand logo
* [`brandText`](/reference/servoyextensions/ui-components/navigation/navbar#brandtext): an optional branding text shown in the upper left corner (after the optional brandLogo)
* [`brandTextTabindex`](/reference/servoyextensions/ui-components/navigation/navbar#brandtexttabindex): sets the tab index for brand text

### Set the Navbar's position

Navbar's position can be set in [fixed](/reference/servoyextensions/ui-components/navigation/navbar#fixed) property. This property controls whether the toolbar is fixed to either top or bottom of the screen.

### Distinct Active Menu Item

Setting the [markClickedItemActive](/reference/servoyextensions/ui-components/navigation/navbar#markclickeditemactive) property to `true`, items of `displayType`: `MENU_ITEM` will be shown as "active" when clicked.

### Setting menu item's properties

A complete list of menu item's properties can be found [here](/reference/servoyextensions/ui-components/navigation/navbar#menuitem).

Properties to be set:

* `item`: Identifier of a menu item. This property is required to allow the component to figure out what item a user selected
* `text`: The text shown. Is used as placeholder text on INPUT or INPUT\_GROUP items
* `displayType`: Controls the appearance of the menu item:
  * `MENU_ITEM` (default)
  * `TEXT`
  * `BUTTON`
  * `INPUT`
  * `INPUT_GROUP`
* `subMenuItems`: An optional array of sub menus for a `MENU_ITEM` type. When set, the item will be shown as a dropdown
* `enabled`: enables the menu item
* `iconName`: An optional icon added to the menu item. Any glyhicon or font awesome icon can be used (e.g. "glyphicon glyphicon-search" or "fa fa-car"). When used with `INPUT` or `INPUT_GROUP` used as the button's icon.
* `inputButtonStyleClass`: Style class to control the optional button shown with `INPUT` or `INPUT_GROUP`. Typically one of bootstraps button classes ("btn-default", "btn-primary", "btn-success", "btn-info", "btn-warning", "btn-danger", "btn-link"). Default is "btn-default"
* `isActive`: When `true`, a `MENU_ITEM` item will be shown as `active`
* `position`: Controls whether an item is shown on the left or on the right of the navbar. Default is `LEFT`
* `styleClass`: Additional style class(es) of the component
* `tooltip`: An optional tooltip for the item
* `valuelist`: When set, an `INPUT` or `INPUT_GROUP` item will show a typeahead list.
* `onAction`: Function that will be called if the item is clicked on (`MENU_ITEM`, `BUTTON`), a submenu is selected (`MENU_ITEM` with `subMenuItems`) or the user hits enter, leaves the field or clicks the optional button (`INPUT`, `INPUT_GROUP`). If not set, the component will call the `onMenuItemClicked` method assigned to the component itself.

### Menu Item DisplayType

Menu item `displayType` property has the following options:

#### DisplayType: `MENU_ITEM` (default)

Simple clickable entry in the navbar.

Example with just the text:

<div align="left"><figure><img src="/files/9fzoKSSTQlJCCRFP8ISW" alt=""><figcaption><p>MenuItem Text</p></figcaption></figure></div>

Example with icon and submenus:

<div align="left"><figure><img src="/files/nQwix6UYpwly0kya5ABH" alt=""><figcaption><p>MenuItem Dropdown</p></figcaption></figure></div>

Example of an opened submenu:

<div align="left"><figure><img src="/files/fZ9mqlwjRaGiXn6quHqy" alt=""><figcaption><p>MenuItem Dropdown opened</p></figcaption></figure></div>

For an item of `displayType`:`MENU_ITEM` the `MenuItem` properties are used as:

<table data-full-width="false"><thead><tr><th width="230">Property</th><th>Usage</th></tr></thead><tbody><tr><td>dataProvider</td><td>not used</td></tr><tr><td>iconName</td><td>icon to the left of the entry's name</td></tr><tr><td>inputButtonStyleClass</td><td>not used</td></tr><tr><td>inputButtonText</td><td>not used</td></tr><tr><td>subMenuItems</td><td>When set, the item will be shown as a dropdown menu</td></tr><tr><td>valuelist</td><td>not used</td></tr><tr><td>onAction</td><td>Fired when the user clicks on the item or selects an item from the dropdown menu</td></tr></tbody></table>

***

#### DisplayType: `TEXT`

Plain text shown in the bar:

<div align="left"><figure><img src="/files/2xs1L7kA17asBbqHrrQ7" alt=""><figcaption><p>Text</p></figcaption></figure></div>

For an item of `displayType`:`TEXT` the `MenuItem` properties are used as:

<table><thead><tr><th width="230">Property</th><th>Usage</th></tr></thead><tbody><tr><td>dataProvider</td><td>not used</td></tr><tr><td>iconName</td><td>icon to the left of the entry's name</td></tr><tr><td>inputButtonStyleClass</td><td>not used</td></tr><tr><td>inputButtonText</td><td>not used</td></tr><tr><td>subMenuItems</td><td>not used</td></tr><tr><td>valuelist</td><td>not used</td></tr><tr><td>onAction</td><td>not fired</td></tr></tbody></table>

***

#### DisplayType: `BUTTON`

A normal button.

Example with text "Button 1", iconName "glyphicon glyphicon-camera" and styleClass "btn-primary":

<div align="left"><figure><img src="/files/dTVervAKhi2eYGiVaQTb" alt=""><figcaption><p>Button</p></figcaption></figure></div>

For an item of `displayType`:`BUTTON` the `MenuItem` properties are used as:

<table><thead><tr><th width="230">Property</th><th>Usage</th></tr></thead><tbody><tr><td>dataProvider</td><td>not used</td></tr><tr><td>iconName</td><td>icon to the left of the entry's name</td></tr><tr><td>inputButtonStyleClass</td><td>not used</td></tr><tr><td>inputButtonText</td><td>not used</td></tr><tr><td>subMenuItems</td><td>not used</td></tr><tr><td>valuelist</td><td>not used</td></tr><tr><td>onAction</td><td>fired when the user clicks on an item</td></tr><tr><td>styleClass</td><td>Button style class. Typically one of bootstraps button classes ("btn-default", "btn-primary", "btn-success", "btn-info", "btn-warning", "btn-danger", "btn-link"). Default is "btn-default".</td></tr></tbody></table>

***

#### DisplayType: `INPUT`

An item of type `INPUT` adds a text field to the navbar. The text field can have an optional button grouped next to it when the `inputButtonText` or `iconName` (or both) property is set.

Example with iconName and inputButtonText:

<div align="left"><figure><img src="/files/VXrZJG97liYYRPLg4N92" alt=""><figcaption><p>Input</p></figcaption></figure></div>

For an item of `displayType`:`INPUT` the `MenuItem` properties are used as:

<table><thead><tr><th width="230">Property</th><th>Usage</th></tr></thead><tbody><tr><td>dataProvider</td><td>used to assign the dataprovider of the field</td></tr><tr><td>iconName</td><td>When set a button with that icon is shown next to the input field. Any glyhicon or font awesome icon can be used (e.g. "glyphicon glyphicon-search" or "fa fa-car").</td></tr><tr><td>inputButtonStyleClass</td><td>Used for the optional button. Typically one of bootstraps button classes ("btn-default", "btn-primary", "btn-success", "btn-info", "btn-warning", "btn-danger", "btn-link"). Default is "btn-default".</td></tr><tr><td>inputButtonText</td><td>When set a button with the text is shown next to the input field.</td></tr><tr><td>subMenuItems</td><td>not used</td></tr><tr><td>valuelist</td><td>When set, the input will show a typeahead list.</td></tr><tr><td>onAction</td><td>fired when the user hits enter in the field, leaves the field or clicks on the optional button next to the field.</td></tr></tbody></table>

***

#### DisplayType: `INPUT_GROUP`

An item of type `INPUT_GROUP` behaves the same as `INPUT` except that the field is rendered along with optional button as an `inputgroup`. There is no spacing between the field and the button.

Example with `iconName` and `inputButtonText`:

<div align="left"><figure><img src="/files/vJHIgGbK8lOPEA1yN2VB" alt=""><figcaption><p>Inputgroup</p></figcaption></figure></div>

## Scripting Navbar

### Main events

You can find a list of Navbar **events** [here](/reference/servoyextensions/ui-components/navigation/navbar#events).\
You can find a list of Navbar **API methods** [here](/reference/servoyextensions/ui-components/navigation/navbar#api).

Let's consider the following setup:

* `main_form`: the form where the Navbar component is placed, together with a [form container](/guides/develop/application-design/forms/form-containers/form-container#overview) component, `fc_nav`
  * Navbar component has the following menu items:
    * `item`:`home`, `displayName`:`Home`
    * `item`:`menu_item1`, `displayName`:`Menu Item #1`
    * `item`:`menu_item2`, `displayName`:`Menu Item #2`
    * `item`:`menu_item3`, `displayName`:`Menu Item #3`
* separate forms showed in `main_form` as a contained form in the form container component: `home`, `menu_item1`, `menu_item2`, `menu_item3`.

### onBrandClicked

This event is called when the user clicks on the brand logo or text.\
Here is an example of how to use the [onBrandClicked](/reference/servoyextensions/ui-components/navigation/navbar#onbrandclicked) event of Navbar in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor).\
The following goes on `main_form` script file:

```javascript
/**
 * Called when the user clicks on the brand logo or text.
 *
 * @param {JSEvent} event
 *
 * @private
 *
 * @properties={typeid:24,uuid:"A122138E-AA11-4570-9A94-C1C7454C579D"}
 */
function onBrandClicked(event) {
  elements.fc_nav.containedForm = forms.home; // shows the `Home` form in the form container when clicking on brand logo or text
}
```

### onMenuItemClicked

This event is called when a menu item is clicked.\
Here is an example of how to use the [onMenuItemClicked](/reference/servoyextensions/ui-components/navigation/navbar#onmenuitemclicked) event of Navbar in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor). The following goes on `main_form` script file:

```javascript
/**
 * Called whenever a menu item is clicked or a submenu item is selected with the JSEvent and the menuItem object clicked on.
 *
 * @param {JSEvent} event
 * @param {CustomType<bootstrapextracomponents-navbar.menuItem>} menuItem
 *
 * @private
 *
 * @properties={typeid:24,uuid:"6F2D94B3-C80F-4086-976C-0DAFBF05E256"}
 */
function onMenuItemClicked(event, menuItem) {
	elements.fc_nav.containedForm = forms[menuItem.itemId] // menuItem.itemId gets the ID value of the clicked menu item
}
```

### Setting menu items for a manually configured component's menu

Sets all menu items of the navbar. The branding remains untouched.\
Here is an example of how to use the [setMenuItems](/reference/servoyextensions/ui-components/navigation/navbar#setmenuitems) event of Navbar in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):

```javascript
var menuItems = [];

menuItems.push({itemId: '1', text: 'Accounts', tooltip: 'Accounts'});
menuItems.push({itemId: '2', text: 'Invoices', tooltip: 'Invoices'});
menuItems.push({itemId: '3', text: 'Click me', displayType: 'BUTTON', tooltip: 'Button'});
menuItems.push({text: 'Payables', tooltip: 'Payables'});
menuItems.push({itemId: '5', text: 'Search account...', displayType: 'INPUT', iconName: 'glyphicon glyphicon-search', tooltip: 'Search'});
menuItems.push({itemId: '6', text: 'Menu', position: 'RIGHT', tooltip: 'A submenu', subMenuItems: [{itemId: '6.1', text: 'Action'}, {itemId: '6.2', text: 'More action'}, {isDivider: true}, {itemId: '6.3', text: 'Last action'}]});
menuItems.push({itemId: '7', text: 'Logged in as John Doe', tooltip: 'just text', displayType: 'TEXT', position: 'RIGHT'});

elements.navbar.brandText = 'Accounting';
elements.navbar.setMenuItems(menuItems);
```

### Add a menu item

Adds the given item to the navbar. Here is an example of how to use the [addMenuItem](/reference/servoyextensions/ui-components/navigation/navbar#addmenuitem) event of Navbar in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):

**For a manually configured Menu:**

```javascript
/** @type {bootstrapextracomponents-navbar.menuItem} */
var itemToAdd = {
	itemId: application.getUUID().toString(), 
	text: 'Item added'
}
elements.navbar.addMenuItem(itemToAdd);
```

***

**For an assigned servoyMenu:**

```javascript
// Get reference to servoyMenu
var menu = elements.navbar.servoyMenu;

// Create a new menu item
var newItem = menu.addMenuItem("item1");
newItem.menuText = "Sample Item #1";
```

### Remove menu Item

Removes the item with the given `itemId` from the bar.\
Here is an example of how to use the [removeMenuItem](/reference/servoyextensions/ui-components/navigation/navbar#removemenuitem) event of Navbar in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):

**For a manually configured Menu:**

```javascript
/**
 * Fired when the button is clicked.
 *
 * @param {JSEvent} event
 *
 * @private
 *
 * @properties={typeid:24,uuid:"01F79B4C-917A-44A6-8499-F99D4611FA5F"}
 */
function onAction$remove(event) {
	elements.navbar.removeMenuItem(`menu_item3`); // `menu_item3` is the id of the item we want to remove from the menu
}
```

***

**For an assigned servoyMenu:**

```javascript
// Get reference to servoyMenu
var menu = elements.navbar.servoyMenu;

// remove menu item 
menu.removeMenuItem("menu_item3") // `menu_item3` is the id of the item we want to remove from the menu
```

### Set selected menu item

Sets the item with the given ID as selected (sets the `isActive` property). Items of type `MENU_ITEM` will be rendered with a different background color when selected. Here is an example of how to use the [setMenuSelected](/reference/servoyextensions/ui-components/navigation/navbar#setmenuselected) event of Navbar in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):

**For a manually configured Menu:**

```javascript
/**
 * Fired when the button is clicked.
 *
 * @param {JSEvent} event
 *
 * @private
 *
 * @properties={typeid:24,uuid:"01F79B4C-917A-44A6-8499-F99D4611FA5F"}
 */
function onAction$setMenuSelected(event) {
	elements.navbar.setMenuSelected(`menu_item3`); // `menu_item3` is the id of the item we want to set as selected - active
}
```

***

**For an assigned servoyMenu:**

```javascript
// Get reference to servoyMenu
var menu = elements.navbar.servoyMenu;

// remove menu item 
menu.selectMenuItem("menu_item3") // `menu_item3` is the id of the item we want to set as selected - active
```

### Get the selected menu item

Returns the currently selected menu item.\
Here is an example of how to use the [getSelectedMenu](/reference/servoyextensions/ui-components/navigation/navbar#getselectedmenu) event of Navbar in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):

**For a manually configured Menu:**

```javascript
/**
 * Fired when the button is clicked.
 *
 * @param {JSEvent} event
 *
 * @return {CustomType<bootstrapextracomponents-navbar.menuItem>} selected
 * 
 * @private
 *
 * @properties={typeid:24,uuid:"01F79B4C-917A-44A6-8499-F99D4611FA5F"}
 */
function onAction$getSelectedMenu(event) {
	var selected = elements.navbar.getSelectedMenu(); // Returns the currently selected menu item
  return selected;
}
```

***

**For an assigned servoyMenu:**

```javascript
// Get reference to servoyMenu
var menu = elements.navbar.servoyMenu;

// remove menu item 
menu.getSelectedItem() // Returns the currently selected menu item
```


# sidenav

## Overview

<div align="left"><figure><img src="/files/RC3AJgvW08Bk7kXaYc4y" alt=""><figcaption><p>Sidenav demo</p></figcaption></figure></div>

A **Sidenav** (short for side navigation) in Servoy is a UI component that provides a **vertical navigation menu** typically placed on the left (or sometimes right) side of an application interface. Sidenav allows users to navigate quickly between different sections or forms within the application. This type of navigation is common in modern web and mobile applications, providing a consistent and intuitive structure, particularly when managing multiple sections or forms.

**Key Features of Sidenav**:

* **Multi-Level Navigation (Up to 4 Levels)**: The sidenav can manage nested items up to 4 levels deep. Each level can have selectable and collapsible items, where one item can be selected and expanded at a time.
* **Collapsible and Expandable Menu Items**: Menu items within the sidenav can be collapsed or expanded, giving users control over how much information is visible at any given time. When an item is selected, its child items (if any) are automatically expanded.
* **Programmatic Control**: The sidenav component can be controlled programmatically, allowing developers to modify its runtime properties and trigger actions through the component's API.
* **Form Container Integration**: The sidenav can serve as a form container that displays a form alongside the menu. This form animates together with the menu when it slides in or out, creating a seamless user experience.

## Use Cases for Sidenav

* **Multi-Section Applications**: In applications with multiple sections or areas (such as an admin panel, content management system, or e-commerce platform), a sidenav provides a clear, structured way to navigate between forms or modules.
* **Hierarchical Navigation**: For applications that require deep, hierarchical navigation (e.g., categories and subcategories in a product catalog), sidenav is ideal for letting users drill down into different levels of the hierarchy.
* **Responsive Design**: In mobile and responsive applications, the sidenav can be made collapsible or hidden on smaller screens, giving users access to navigation when needed while conserving screen space.

## Get Started

### Creating a Sidenav component

<div align="left"><figure><img src="/files/eGzSie2VLDvU0TTIUzKY" alt=""><figcaption><p>Create a Sidenav</p></figcaption></figure></div>

Here are the steps for creating a Sidenav:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Sidenav** component
2. Find **Sidenav** in the *Navigation* section in the components' palette
3. Drag and drop the **Sidenav** component in the desired place of the form
4. [Set the menu](#setting-the-menu)
5. Edit other [**Sidenav** properties](/reference/servoyextensions/ui-components/navigation/sidenav#properties) and [**Sidenav menu item** properties](/reference/servoyextensions/ui-components/navigation/sidenav#menuitem), if the case

***

{% hint style="info" %}
**Hint**

<img src="/files/WC2G1TbBRusvRMvMtQa5" alt="Create a Sidenav through a Servoy Menu" data-size="original">

In case there is an existing [Servoy Menu](/guides/develop/application-design/data-modeling/menu#overview) that will be used as a Sidenav menu, then here are the steps to be followed:

1. Open the [Form Editor](/reference/servoy-developer/object-editors/form-editor) of the form where you need to place a **Sidenav** component
2. Find the desired Servoy Menu name in the *Servoy Menu* section in the components' palette
3. Drag and drop the desired Servoy Menu name in the form. This will open the [JSMenu compatible component selector](/reference/servoy-developer/object-editors/jsmenu-compatible-component-selector#overview)
4. Select `sidenav[servoyextra]` option, then click `OK`. This will add to the main form a Sidenav component having the desired Servoy Menu name set for [servoyMenu](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu) property of the component
5. Configure [**Sidenav** properties](/reference/servoyextensions/ui-components/navigation/sidenav#properties) in the component's properties panel. If needed, you can change or remove the assigned [servoyMenu](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu). In this case, you must manually configure the [**Sidenav menu item** properties](/reference/servoyextensions/ui-components/navigation/sidenav#menuitem).
   {% endhint %}

## Setting the Menu

The **Sidenav** component supports two ways to configure its menu:

1. **Using** [**`servoyMenu`**](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu) **property**: Assign a predefined [servoyMenu](/guides/develop/application-design/data-modeling/menu#overview) for centralized menu management.
2. **Using** [**`menu`**](/reference/servoyextensions/ui-components/navigation/sidenav#menu) **property**: Manually define menu items directly inside the component.

{% hint style="info" %}
**Using either a manually configured menu or servoyMenu will not change the appearance of the Sidenav.**\
Both methods result in the **same** UI layout, styling, and interactions, including menu item rendering, nested structures, icons, and animations. The only difference is in how the menu items are configured and managed.
{% endhint %}

{% hint style="danger" %}
**IMPORTANT!**\
If **both methods** are used, the manually configured menu **will take precedence**, and the **servoyMenu will be ignored**.
{% endhint %}

### Assigning an existing servoyMenu

Instead of configuring the menu manually, you can assign a **predefined** [**servoyMenu**](/guides/develop/application-design/data-modeling/menu#overview) in Sidenav [`servoyMenu`](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu) property, which allows you to:

* Centrally manage menus across multiple components.
* Easily update menus without modifying individual Sidenav components.
* Use the same menu structure in different parts of the application.

To assign a `servoyMenu`:

1. In the Properties Panel of the **Sidenav** component, locate the [`servoyMenu`](/reference/servoyextensions/ui-components/navigation/sidenav#servoymenu) property and click on its value. This will open the [Servoy Menu Selection Wizard](/reference/servoy-developer/object-editors/menu-selection-wizard#overview)
2. Select an existing `servoyMenu` from the list.
3. When a `servoyMenu` is assigned, its menu items are automatically applied to the Sidenav component.

### Setting the menu items in the properties panel

<figure><img src="/files/Vgtp4sK7wyZITKP3YUBB" alt=""><figcaption><p>Adding and editing menu items and sub menu items</p></figcaption></figure>

You can configure menu items directly in the **Sidenav** [**`menu`**](/reference/servoyextensions/ui-components/navigation/sidenav#menu) **property**. This allows fine-grained control over the menu structure, including:

* Adding menu items manually.
* Defining sub-menus (up to 4 levels deep).
* Setting icons, styles, and form associations.

After dragging the component on the form, find the **Sidenav** in the form editor, click it and proceed with the following steps:

1. Add a menu item:
   * Select the [`menu`](/reference/servoyextensions/ui-components/navigation/sidenav#menu) property and click the `+` button in order to add a menu item. You can add the next menu item in the same way or by clicking the `+` button (`insert a new array item below`) of another menu item.
2. Expand the [`menu`](/reference/servoyextensions/ui-components/navigation/sidenav#menu) property to see the list of menu items. They are also shown in the **Sidenav** component (in the form editor)
3. In order to edit each menu item, expand it in the Properties Panel and set its [properties](/reference/servoyextensions/ui-components/navigation/sidenav#menuitem)
4. Submenu items can be added by clicking the `+` button of the parent menu item and following the same steps.

{% hint style="info" %}
**Sidenav menu items**\
It is necessary to set a unique id in the Sidenav **menu item** [id](/reference/servoyextensions/ui-components/navigation/sidenav#menuitem) property.\
Example: `home_page`.
{% endhint %}

## Working with Sidenav

You can find a list of Sidenav **properties** [here](/reference/servoyextensions/ui-components/navigation/sidenav#properties).

### Setting the contained form

The initial form to be displayed can be set by selecting a form name in the component's Properties Panel [containedForm](/reference/servoyextensions/ui-components/navigation/sidenav#containedform) property.

### Setting header and footer

Sidenav component can include forms acting like headers and footers. This is done by selecting a form name in the component's Properties Panel for the following properties:

* [headerForm](/reference/servoyextensions/ui-components/navigation/sidenav#headerform)
* [footerForm](/reference/servoyextensions/ui-components/navigation/sidenav#footerform)

### Setting component's menu item's properties

A complete list of component's menu item's properties can be found [here](/reference/servoyextensions/ui-components/navigation/sidenav#menuitem).

Important properties to be set:

* `id`: it represents the menu item ID, it is mandatory and must be unique for each menu item
* `text`: displayed text for the menu item
* `enabled`: enables the menu item
* `isDivider`: if this property is set to `true`, then the menu item will be displayed as a visually divider line
* `menuItems`: this property is set exactly as a menu item; here the user can set sub-items for a menu item; each sub-item has the same kind of properties as a main item
* `relationName`: here the user can set an existing relation in case the contained form needs to be loaded through a specific relation
* `formName`: the user can set here the contained form corresponding to each menu item

## Scripting Sidenav

### Main events

You can find a list of Sidenav **events** [here](/reference/servoyextensions/ui-components/navigation/sidenav#events).\
You can find a list of Sidenav **API methods** [here](/reference/servoyextensions/ui-components/navigation/sidenav#api).

### onMenuItemSelected

This event is called when a menu item is clicked.\
Here is an example of how to use the [onMenuItemSelected](/reference/servoyextensions/ui-components/navigation/sidenav#onmenuitemselected) event of Sidenav in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor):\
Let's consider the following setup:

* `main_form`: the form where the Sidenav component is placed:
  * Sidenav component has the following menu items:
    * `id`:`menu_item1`, `text`:`Menu Item #1`
    * `id`:`menu_item2`, `text`:`Menu Item #2`
    * `id`:`menu_item3`, `text`:`Menu Item #3`
* separate forms showed in `main_form` as a contained form in the Sidenav component: `menu_item1`, `menu_item2`, `menu_item3`.

The following goes on `main_form` script file:

```javascript
/**
 * @param menuItemId
 * @param {JSEvent} event
 *
 * @return {Boolean}
 *
 * @private
 *
 * @properties={typeid:24,uuid:"D1C19804-0E6A-44C2-B5D4-8934E5B5F5F5"}
 */
function onMenuItemSelected(menuItemId, event) {
	elements.sidenav.containedForm = forms[menuItemId]; // menuItemId gets the ID value of the clicked menu item
	return false;
}
```

### Setting menu items for a manually configured component's menu

Use the api [**setRootMenuItems**](/reference/servoyextensions/ui-components/navigation/sidenav#setrootmenuitems-menuitems) to populate the sidenav with [Menu Items](#menu-item). You can nest Menu Items up to 4 levels depth.

```javascript
var menu = [{
    id: 1,
    text: "Sample Item #1",
    styleClass : "sn-large",
    iconStyleClass:  "glyphicon glyphicon-search",
    data: { description: "This is sample information that can be added to a menuItem" },
    menuItems: [{
  	  id: 5,
  	  text: "Sub Item #1"
  	}, {
  	  id: 6,
  	  text: "Sub Item #2"}]
  }, {
    id: 2,
    text: "Sample Item #2"
  },{
    isDivider: true
  },{
    id: 3,
    text: "Sample Item #3",
    enabled: false
}];

  elements.sideNavigation.setRootMenuItems(menu);
```

The method [setRootMenuItems](/reference/servoyextensions/ui-components/navigation/sidenav#setrootmenuitems-menuitems) requires an Array of [Menu Item object](/reference/servoycore/dev-api/menus/jsmenuitem#overview).

### Menu Item

The menu item is a JSON object representing an item in the sidenav. A menu item may nest other menu items. A menu item may be also used as divider, which is nothing else then a line separating the menu item above and below, in this case all other properties of the menu item are ignored.

Component's Menu Item properties can be found [here](/reference/servoyextensions/ui-components/navigation/sidenav#menuitem).\
ServoyMenu's Menu Item properties for Sidenav component can be found [here](/guides/develop/application-design/data-modeling/menu#sidenav-properties).

This is a menu item with 2 sub menu items:

**For a manually configured Menu:**

```javascript
var menuItem = {
    id: 1,
    text: "Sample Item #1",
    styleClass : "sn-large",
    iconStyleClass:  "glyphicon glyphicon-search",
    data: { description: "This is sample information that can be added to a menuItem" },
    menuItems: [{
  	  id: 5,
  	  text: "Sub Item #1"
  	}, {
  	  id: 6,
  	  text: "Sub Item #2"}]
  };
```

This menu item is instead rendered as a divider:

```javascript
 var menuDivider = {
    isDivider: true
  };
```

***

**For an assigned servoyMenu:**

```javascript
// Get reference to servoyMenu
var menu = elements.sidenav.servoyMenu;

// Create a new menu item
var newItem = menu.addMenuItem("item1");
newItem.menuText = "Sample Item #1";
newItem.iconStyleClass = "glyphicon glyphicon-search";

// Add sub-menu items
var subItem1 = newItem.addMenuItem("sub_item1");
subItem1.menuText = "Sub Item #1";

var subItem2 = newItem.addMenuItem("sub_item2");
subItem2.menuText = "Sub Item #2";
```

### Add a Menu Item

Add a menu item. The menu is added as sub Menu Item if a `menuItemId` is provided, otherwise is added in root. If index is provided the menu is added at the specified index position, otherwise is added as last element. Return false if `menuItemId` cannot be found.\
Here is an example of how to programmatically add a menu item in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [addMenuItem](/reference/servoyextensions/ui-components/navigation/sidenav#addmenuitem):

**For a manually configured Menu:**

```javascript
 var menuItem = {
  id: 100,
  text: "Sample Item #1",
  styleClass : "nav-large nav-primary",
  iconStyleClass:  "glyphicon glyphicon-search",
  data: { description: "This is sample information that can be added to a menuItem" },
  menuItems: [{
  	id: 101,
  	text: "Sub Item #1"
  	}, {
  	id: 102,
  	text: "Sub Item #2"}]
  };
  elements.sideNavigation.addMenuItem(menuItem, 1, 0); // parameters are : menuItem, menuItemId, index
```

***

**For an assigned servoyMenu:**

```javascript
// Get reference to servoyMenu
var menu = elements.sidenav.servoyMenu;

// Create a new menu item
var newItem = menu.addMenuItem("item1");
newItem.menuText = "Sample Item #1";
newItem.iconStyleClass = "glyphicon glyphicon-search";
```

### Setting sub-menu items

Set the `menuItems` as sub-menu items of the menu item with id `menuItemId`. This function returns `false` if `menuItemId` cannot be found.\
Here is an example of how to programmatically set sub-menu items in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [setSubMenuItems](/reference/servoyextensions/ui-components/navigation/sidenav#setsubmenuitems):

**For a manually configured Menu:**

```javascript
var menuItems = [{
  id: 10,
  text: "Sample Item #1",
  styleClass : "sn-large",
  iconStyleClass:  "glyphicon glyphicon-search",
  data: { description: "This is sample information that can be added to a menuItem" },
  menuItems: [{
  	id: 12,
  	text: "Sub Item #1"
  	}
  }]
  }, {
  id: 11,
  text: "Sample Item #2"
  },{
  isDivider: true
  }];
  elements.sideNavigation.setSubMenuItems(menuItems);
```

***

**For an assigned servoyMenu:**

```javascript
// get reference to the desired menu item
var menuItem = elements.sidenav.servoyMenu.getMenuItem("item1");

// Add sub-menu items
var subItem1 = menuItem.addMenuItem("sub_item1");
subItem1.menuText = "Sub Item #1";

var subItem2 = menuItem.addMenuItem("sub_item2");
subItem2.menuText = "Sub Item #2";
```

### Update a Menu Item

To update a menu item you should get the menu item object using the component's API [getMenuItem](/reference/servoyextensions/ui-components/navigation/sidenav#getmenuitem), any change to the returned object will be reflected on the sidenav component.

Example\
**For a manually configured Menu:**

```javascript
var menuItem = elements.sidenav.getMenuItem(1);
menuItem.text = "Update the text of the menuItem";
menuItem.styleClass = "nav-large nav-bold";
menuItem.data = { "lastUpdate" : new Date(); }
```

Updating an old reference of the menuItem which has not been retrieved via API it won't be possible.

Don't do this:

```javascript
var menuItem = { id:1, text: "init text"};
elements.sidenav.addMenuItem(menuItem);
menuItem.text = "Update text of menu item 1 like this is not reflected on UI"
```

**Instead do**:

```javascript
var menuItem = { id:1, text: "init text"};
elements.sidenav.addMenuItem(menuItem);
// get the menuItem via API
menuItem = elements.sidenav.getMenuItem(1); 
menuItem.text = "Update text of menu item 1 like this is correct"
```

***

**For an assigned servoyMenu:**

```javascript
// get the menuItem via API
var menuItem = elements.sidenav.servoyMenu.getMenuItem("item1");

//update the menu item as needed
menuItem.menuText = "Update the text of the menuItem";
menuItem.styleClass = "nav-large nav-bold";
```

### Remove all menu items

If a depth value is specified, all menu items at that depth will be removed. If the depth is set to `1`, all root menu items will be removed. The default depth is `1`.\
Here is an example of how to programmatically remove all menu items in the [Scripting Editor](/reference/servoy-developer/object-editors/scripting-editor) of the main form, using the the [clearMenuItems](/reference/servoyextensions/ui-components/navigation/sidenav#clearmenuitems):

```javascript
 // clear the whole menu removing all nodes. 
 elements.sidenav.clearMenuItems();
  
 // clear menu at depth 2 removes the sub menu items of each root menu.
 elements.sidenav.clearMenuItems(2);
```


# Visualization


# DBTreeview

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

Servoy extra components contains two tree components. The difference between the two is the model, the dbtreeview is based on foundset(s) while treeview is based on dataset.

DbTreeview shows multiple tree levels based on relation. From top foundset (datasource), one can show related nodes specified by a relation. Note that each relation is a database query , so for performance should not abuse the tree expand (from javascript). The tree works lazy and initializes data as requested.

Usual tree features are included, show a node checkbox, node image, tooltip, click callback, expand node... More information about model/api can be seen in Servoy Developer.

This component is a porting to NG of Servoy's DBTreeView bean, you can find more details about the migration here: <https://wiki.servoy.com/display/DOCS/Upgrading+to+Servoy+8.x.x#UpgradingtoServoy8.x.x-DBTreeView>

Here is a sample code of the tree initialization:

```javascript
//set the relation to discover other nodes (when clicked open)
elements.dbtreeview.setNRelationName(controller.getDataSource(), 'book_nodes_to_book_nodes_parent_childs');
		
//set the name of dataprovider to use for text display on a node
elements.dbtreeview.setTextDataprovider(controller.getDataSource(), 'label_text');

//set the method to call and dataprovider value to pass when node clicked
elements.dbtreeview.setCallBackInfo(controller.getDataSource(), globals.node_selected,'node_id');

//search the root node(s)
controller.find();
parent_id = 0;
controller.search();

//set the root node(s) and set the name of dataprovider to use for text display on a node
elements.dbtreeview.addRoots(foundset);

var pathAr = new Array(1,2,3);
elements.dbtreeview.setSelectionPath(pathAr);
```

## Table of contents

* [DBTreeView properties](#dbtreeview-properties)
* [DBTreeView events](#dbtreeview-events)
* [DBTreeView API](#dbtreeview-api)
* [DBTreeView Types](#dbtreeview-types)

## DBTreeView properties

DBTreeView properties can be found [here](/reference/servoyextensions/ui-components/visualization/dbtreeview#properties)

The component has only one public property, component should be handled via API.

## DBTreeView Events

DBTreeView events can be found [here](/reference/servoyextensions/ui-components/visualization/dbtreeview#events)

## DBTreeView API

DBTreeView API methods can be found [here](/reference/servoyextensions/ui-components/visualization/dbtreeview#api)

## DBTreeView Types

DBTreeView types can be found [here](/reference/servoyextensions/ui-components/visualization/dbtreeview#types)


# Progress Bar

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

The Progress Bar component shows a progress bar that can be used to indicate the progress of lengthy processes.

Example:

![Progress Bar](/files/8fEcpoMfgWLXBFcC9Px8)

## Table of contents

* [Progress Bar properties](#progress-bar-properties)
* [Progress Bar API](#progress-bar-api)

## Progress Bar properties

Progress Bar properties can be found [here](/reference/servoyextensions/ui-components/visualization/progress-bar#properties)

## Progress Bar API

Progress Bar API methods can be found [here](/reference/servoyextensions/ui-components/visualization/progress-bar#api)

### [setProgress](/reference/servoyextensions/ui-components/visualization/progress-bar#setprogress)

Updates the progress, optionally setting the given value text

### [updateProgressBar](/reference/servoyextensions/ui-components/visualization/progress-bar#updateprogressbar)

To update the progress bar you should update the value of the progress bar.

`elements.myProgressBar.value = 60;`

Please note that runtime changes to element's properties are not pushed immediately to the UI. To reduce the number of the round-trip server to client, Servoy keep track of the runtime changes and push them to the client as soon the method thread is terminated or as soon an updateUI is forced. An updateUI can be explicitly invoked with application.updateUI().

The function below updates the progress bar only once the execution is terminated.

```javascript
function onAction(event) {
 // UI is updated only when the the loop is over; there is 1 round-trip server to client
 for (var index = 0; index <= 100; index++) {
   elements.bs_progressbar.value = index;
   application.sleep(50);
 }
}
```

This function behave differently then the function above, updating the progress bar at each iteration.

```javascript
function onAction(event) {
 // UI is updated at each iteration. There are 100 round-trip to server to client
 for (var index = 0; index <= 100; index++) {
   elements.bs_progressbar.value = index;
   application.updateUI();
   application.sleep(50);
 }
}
```


# Treeview

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

Servoy extra components contains two tree components. The difference between the two is the model, the dbtreeview is based on foundset(s) while treeview is based on dataset.

DbTreeview shows multiple tree levels based on relation. From top foundset (datasource), one can show related nodes specified by a relation. Note that each relation is a database query , so for performance should not abuse the tree expand (from javascript). The tree works lazy and initializes data as requested.

Usual tree features are included, show a node checkbox, node image, tooltip, click callback, expand node... More information about model/api can be seen in Servoy Developer.

## Table of contents

* [Tree properties](#tree-properties)
* [Tree example](#tree-example)
* [Tree events](#tree-events)
* [Tree API](#tree-api)

## Tree properties

Tree properties can be found [here](/reference/servoyextensions/ui-components/visualization/treeview#properties)

The component has one property, API should be used for everything else. Dataset that is the model of the tree. Each row in dataset represents a node in the tree. Dataset should have 4 columns: node id, parent node id (null in case of top nodes or another valid id), node text and icon media url.

Instead of 'icon' it is possible to use 'fa-icon', in this case the values in the column should be FontAwesome classes, ex: 'fa fa-users'.

## Tree example

```javascript
var treeviewDataSet = databaseManager.createEmptyDataSet( 0,  ['id', 'pid', 'treeColumn', 'icon']);
treeviewDataSet.addRow([1,		null,	'Main group',	'media:///group.png']);
treeviewDataSet.addRow([2,		null,	'Second group',	'media:///group.png']);
treeviewDataSet.addRow([3,		2,		'Subgroup',		'media:///group.png']);
treeviewDataSet.addRow([4,		3,		'Mark',			'media:///user.png']);
treeviewDataSet.addRow([5,		3,		'George',		'media:///user.png']);
elements.mytree.setDataSet(treeviewDataSet);
```

## Tree events

Tree events can be found [here](/reference/servoyextensions/ui-components/visualization/treeview#events)

## Tree API

Tree API methods can be found [here](/reference/servoyextensions/ui-components/visualization/treeview#api)


# ChartJS

Guide for using svyChartJS in your applications

## svyChartJS

To see a live sample of the component you can go [here](https://samples-dev.samples.servoy-cloud.eu/solution/components?a=chart).

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

This wiki provides comprehensive documentation for using the **svyChartJS** web-component, which allows you to display a chart utlizing the Chart.JS library within Servoy's NGClient.

## Getting Started

First import the component using one of the release [binaries](https://github.com/Servoy/svyChartJS/releases) or via Servoy's Web Package Manager.

If you would like to see the component in an example install the included solution, [svyChartJSExample.servoy](https://github.com/Servoy/svyChartJS/releases).

## Example Usage

First add the component to a form by dragging it into the form using the Palette Wizard. It should be under ChartJS (chart).

You can then simply connect the chart to a foundset and hook up dataproviders and set a label/value. This is the quickest way to setup a chart and bind it to an existing datasource.

If you need to render a custom dataset (non-foundset) you can setup a simple pie chart by doing the following example via some simple javascript.

```javascript
//Your data node object which requires a type and the data.
var data = {
	type: 'pie',
	data: {
		labels: ["Red",
		"Green",
		"Yellow"],
	datasets: [{
		data: [300, 50, 100],
		backgroundColor: [
                      "#F7464A",
		      "#46BFBD",
		      "#FDB45C"],
		hoverBackgroundColor: [
                      "#FF5A5E",
		      "#5AD3D1",
		      "#FFC870"]
		}]
	}
}

//Initialize the chart by using setData
elements.chart.setData(data);
```

Note that when we are using the **setData** method, we will be **overriding** the design-time properties of the chart so properties such as backgroundColor that you can set on the element designer will not apply for these charts.

To add additional options to a chart you can do the following :

```javascript
//The options object
var options = {
	responsive: false,
	scales: {
		x: {stacked: true},
		y: {stacked: true}
	}
}

//call the api to set the options
elements.chart.setOptions(options);
```

## Chart Customization

The ChartJS library has great potential for customization. By passing in your own modified options or by using additional plugins. We will try and support some of these options on a case by case basis. Please post an issue for any feature requests which are relevant.

## Support for Outlabels plugin

<https://piechart-outlabels.netlify.app/formatting>

### Option callbacks

If you need to use callback functions as a part of your options object. You can use the following method to do so:

```javascript
//As Servoy sanitizes functions from server side we are not able to use callback functions like normal:
//Instead of passing in a normal function like below:
var label_callback = function (context) {
	return ' $' + context.dataset.data[context.dataIndex];
}

//You will need to generate a browser function, for this you need to use clientutils.generateBrowserFunction and pass the function as a string.
var label_callback = clientutils.generateBrowserFunction("function(context) { return ' $'+context.dataset.data[context.dataIndex] }");

var options = {
	plugins: {
		tooltip: {
			callbacks: {
				label: label_callback
			}
		}
	}
}
//call the api to set the options
elements.chart.setOptions(options);
```

For additional options and documentation please refer to the official ChartJS [docs](https://www.chartjs.org/docs/4.4.2/).

### Using with responsive forms

When using the component with responsive forms we need to add some additional CSS styling to the component. In particular the **height** property must be greater than zero.

## svyChartJS Properties

svyChartJS events can be found [here](/reference/servoyextensions/ui-components/visualization/chart#properties).

## svyChartJS Events

svyChartJS events can be found [here](/reference/servoyextensions/ui-components/visualization/chart#events).

## svyChartJS API Documentation

svyChartJS API methods can be found [here](/reference/servoyextensions/ui-components/visualization/chart#api).

### Method Summary

#### [generateLegend](/reference/servoyextensions/ui-components/visualization/chart#generatelegend)

Returns a custom html stringed version of the legend.

#### [drawChart](/reference/servoyextensions/ui-components/visualization/chart#drawchart)

Force the chart to (re)Draw if for some reason it has not.

#### [refreshChart](/reference/servoyextensions/ui-components/visualization/chart#refreshchart)

Force the chart to update if it's options were changed.

#### [setData](/reference/servoyextensions/ui-components/visualization/chart#setdata)

Setup the chart's data. (This will automatically initialize and draw the chart)

#### [setPlugin](/reference/servoyextensions/ui-components/visualization/chart#setplugin)

Register a plugin. (This method must be called prior to drawing the chart)

An example of a chart plugin object can be found [here](https://github.com/Servoy/svyChartJS/blob/master/svyChartUtils/chartPlugins.js).

#### [setOptions](/reference/servoyextensions/ui-components/visualization/chart#setoptions)

Setup the chart's options. (This will automatically refresh the chart if it already exists)

#### [clearChart](/reference/servoyextensions/ui-components/visualization/chart#clearchart)

Clears the chart.


# Data Labels Plugin

```javascript
	var DATA_COUNT = 10;
	var labels = [];

	for (var i = 0; i < DATA_COUNT; ++i) {
		labels.push('' + i);
	}

	var dt = [];
	var dt1 = [];
	var dt2 = [];
	for (i = 0; i < DATA_COUNT; ++i) {
		dt.push(Math.ceil((Math.random() * 100)));
		dt1.push(Math.ceil((Math.random() * 100)));
		dt2.push(Math.ceil((Math.random() * 100)));
	}

	var data = {
		type: 'line',
		data: {
			labels: labels,
			datasets: [{
				backgroundColor: 'teal',
				borderColor: 'teal',
				data: dt,
				datalabels: {
					align: 'start',
					anchor: 'start'
				}
			}, {
				backgroundColor: 'blue',
				borderColor: 'blue',
				data: dt1
			}, {
				backgroundColor: 'purple',
				borderColor: 'purple',
				data: dt2,
				datalabels: {
					align: 'end',
					anchor: 'end'
				}
			}]
		}
	}

	var options = {
		plugins: {
			legend: {
				display: false
			},
			title: {
				display: true,
				text: 'Data Labels'
			},
			tooltip: {
				enabled: false
			},
			datalabels: {
				backgroundColor: clientutils.generateBrowserFunction("function(context) { return '' + context.dataset.backgroundColor }"),
				borderRadius: 4,
				color: 'white',
				font: {
					weight: 'bold'
				},
				formatter: clientutils.generateBrowserFunction("function(value) { return '' + Math.round(value) }"),
				padding: 6
			}
		},
		
		aspectRatio: 5 / 3,
		layout: {
			padding: {
				top: 32,
				right: 16,
				bottom: 16,
				left: 8
			}
		},
		elements: {
			line: {
				fill: false
			}
		},
		scales: {
			y: {
				stacked: true
			}
		}
	}

	elements.chart.setData(data);
	elements.chart.setOptions(options);
```

\*Note that this plugin will not work when used along side outlabels plugin (Use one or the other)

\*Listeners not yet supported fully in current release.


# Funnel Chart

```javascript
	var data = {
		type: 'funnel',
		data: {
			labels: ["Red", "Green", "Yellow"],
			datasets: [{
				data: [25, 200, 600],
				shrinkAnchor: 'middle',
				backgroundColor: ["#F7464A", "#46BFBD", "#FDB45C"],
				hoverBackgroundColor: ["#FF5A5E", "#5AD3D1", "#FFC870"],
				borderColor: 'transparent'
			}]
		}
	}
	
	var options = {
		indexAxis: 'y'
	}

	//Initialize the chart by using setData
	elements.chart.setData(data);
	elements.chart.setOptions(options);
```

## Options

For additional options and documentation please refer to the official Funnel Chart [docs](https://www.sgratzl.com/chartjs-chart-funnel/).


# OutLabels Plugin

```javascript
var data = {
	type: 'pie',
	data: {
		labels: ["Red",
		"Green",
		"Yellow"],
	datasets: [{
		data: [300, 50, 100],
		backgroundColor: [
                      "#F7464A",
		      "#46BFBD",
		      "#FDB45C"],
		hoverBackgroundColor: [
                      "#FF5A5E",
		      "#5AD3D1",
		      "#FFC870"]
		}]
	}
}

var options = {
	responsive: true,
	maintainAspectRatio: false,
	layout: {
		padding: 10
	},
	plugins: {
		legend: {
			display: false
		},
		outlabels: {
			text: "%l (%p)",
			textAlign: "center",
			font: {
				resizable: true,
				minSize: 18,
				maxSize: 25
			}
		}
	}
}

//Initialize the chart by using setData
elements.chart.setData(data);
//Initialize additional options for outlabels plugin
elements.chart.setOptions(options);
```

## Options

```javascript
options.plugins.outlabels = {
    backgroundColor: "#8C1DFF", // Background color of Label
    borderColor: "#001BFF", // Border color of Label
    borderRadius: 17, // Border radius of Label
    borderWidth: 10, // Thickness of border
    color: 'white', // Font color
    display: true,
    lineWidth: 10, // Thickness of line between chart arc and Label
    padding: 17,
    stretch: 100, // The length between chart arc and Label
    text: "%l (%p)",
    textAlign: "center"
}
```

![props](/files/1ZA4fI79UbRVPmwXHABO)

## Text Options

Label's content can be controlled by changing the text option's value. Labels can be displayed on multiple lines by using the newline character (\n) between each line.

The space between each line can be adjusted using the font.lineHeight option.

Following scopes will be replaced automatically:

```
%l: will be replaced by Label of the data
%p: will be replaced by Percent of the data
%v: will be replaced by Value of the data
\n: will be replaced by New Line
```

```javascript
//Example
options.plugins.outlabels: {
    text: '%l PER => %p \n VAL => %v'
}
```

![label](/files/ILpkrJyABFBfIIfc1PjM)

\*Note that this plugin will not work when used along side data labels plugin (Use one or the other)


# TreeMap

```javascript
var functionString = "function(ctx) {";
functionString += "const color = 'rgba(1, 25, 255, 0.1)';";
functionString += "if (ctx.dataset.data[ctx.dataIndex]) {"
functionString += "return color.split('.1').join('.' + ctx.dataset.data[ctx.dataIndex].v);"
functionString += "}";
functionString += "}";
	
var data = {
	type: 'treemap',
	data: {			
		datasets: [{
            label: 'Basic treemap',
            tree: [6,6,5,4,3,2,2,1],
            fontColor: '#000',
            fontFamily: 'serif',
            fontSize: 12,
            fontStyle: 'normal',
            backgroundColor: clientutils.generateBrowserFunction(functionString)
		}]
	}
}
	
//Initialize the chart by using setData
elements.chart.setData(data);
```


# Specialized Components


# Smart Document Editor

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Getting Started

Welcome to the **Smart Docs Editor** project wiki! The editor is a standard Web Component which can be added to your Servoy application. To get going, simply open the Servoy Package Manager (SPM) in your IDE and choose the Smart Document Editor package. The component will be installed and available to place on your form.

\* Please see the companion [**Smart Docs Utils API**](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/modules/svyutils/Smart-Doc-Editor-Utils.md#contents) module for the best documentation and examples.

**Working with documents**

Like all the standard input controls, the editor can be bound to a *"Data Provider"* in your project. This means that the document contents will be automatically rendered from, and updated to any persistent data source column or session variable. In short, loading and saving documents is easy!

## Smart Document Editor properties

Smart Document Editor properties can be found [here](/reference/servoyextensions/ui-components/smartdoceditor/smart-document-editor#properties).

## Smart Document Editor events

Smart Document Editor events can be found [here](/reference/servoyextensions/ui-components/smartdoceditor/smart-document-editor#events).

### Custom Types

Smart Document Editor Custom Types can be found [here](/reference/servoyextensions/ui-components/smartdoceditor/smart-document-editor#types).

## Smart Document Editor API

Smart Document Editor API methods can be found [here](/reference/servoyextensions/ui-components/smartdoceditor/smart-document-editor#api).


# Servoy PDF Viewer

Welcome to **svyPDFViewer**!

This wiki provides comprehensive documentation for using the **svyPDFViewer** web-component, which makes viewing PDF documents in Servoy's NGClient easy and intuitive.

{% hint style="info" %}
*<mark style="color:blue;">**Content under construction**</mark>*
{% endhint %}

## Getting Started

It's easy to get started. Simply import the [web package](https://github.com/Servoy/svyPDFViewer/releases/download/v1.1.0/pdfviewer.zip) via Servoy's Web Package Manager.

If you like to see a sample, install the example solution, \[**svyPDFViewerExample.servoy**] (<https://github.com/Servoy/svyPDFViewer/releases/download/v1.1.0/svyPDFViewerExample.servoy>)

### Example Usage

Load document using **absolute** URL

```javascript
elements.pdfViewer.documentURL = 'http://www.cbu.edu.zm/downloads/pdf-sample.pdf';
```

Load document using URL which is **relative** to the web application's root context. For example:

* <http://my-host:8080/myApplication/reports/test.pdf> - this would be in production server
* <http://localhost:8080/reports/test.pdf> - this would be in developer

```javascript
elements.pdfViewer.documentURL = 'reports/test.pdf'; 
```

## Servoy PDF Viewer properties

Servoy PDF Viewer properties can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/specialized-components/svypdfviewer/broken-reference/README.md).

### [reload](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/specialized-components/svypdfviewer/broken-reference/README.md)

Reloads the document. Use in combination with [noCache](#nocache). Call this method when document has changed on the server.

### [noCache](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/specialized-components/svypdfviewer/broken-reference/README.md)

Indicates if caching should be disabled. Set to true when PDF might change on the server.

### [documentURL](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/specialized-components/svypdfviewer/broken-reference/README.md)

The URL of the PDF document. Can be absolute or relative.

## Servoy PDF Viewer API

Servoy PDF Viewer API methods can be found [here](https://github.com/Servoy/gitbook/blob/master/guides/develop/application-design/ui-components/specialized-components/svypdfviewer/broken-reference/README.md).


# Fullcalendar Component

## Fullcalendar

## Introduction

The component provides a full-sized, drag & drop event calendar.\
The component is based on the JQuery fullcalendar library, version 2.6.1.\
The calendar component is a 1-to-1 implementation of the fullcalendar library. For documentation you can referer to the fullcalendar v2 docs available at <http://fullcalendar.io/docs/>.

## Documentation

Read the documentation on the Fullcalendar and Fullcalendar Events.

* [Fullcalendar](/guides/develop/application-design/ui-components/specialized-components/home-2/fullcalendar#fullcalendar).
* [Fullcalendar Events](/guides/develop/application-design/ui-components/specialized-components/home-2/fullcalendar-events#fullcalendar-events)
* [Migrating calendar from Smart and Web Client to NG Client](/guides/develop/application-design/ui-components/specialized-components/home-2/migrating-calendar-from-smart-and-web-client-to-ng-client#migrating-calendar-from-smart-and-web-client-to-ng-client)

## Quick Start

To add the FullCalendar Component package in your Servoy solution or Servoy module open the Servoy Developer IDE and download the FullCalendar Component from the Web Package Manager (the Web Package Manager is accessible from the context menu of the Web Components node of your solution). The component will be available on the palette of the form designer to be easily dragged and drop into your form. The component has to be initialized programmatically using the fullcalendar constructor available from the element's API.

NOTE: make sure the calendar component in form has the element name set.

```javascript
/** @type {svy-fullcalendar.FullCalendarOptions} */
var options = {
        eventSources: [ {events: [{ title: "lunch event", start: new Date() }]}],
		selectable: true,
		editable: true,
		defaultView: 'agendaWeek',
		showCurrentTimeline: true
}
var calendar = elements.fullcalendarElementName.fullCalendar(options);
```

The options object contains the calendar properties; see the fullcalendar docs for available properties. All the properties are optional.\
Set the eventSources options to feed the calendar with Event Source Objects. Event Sources will populate the calendat with Event objects.\
Call the FullCalendar constructor for the same element to destroy and recreate the Calendar.

## Demo Solution

You can download the Fullcalendar Component demo solution [fullcalendarComponent.demo.servoy](https://github.com/Servoy/fullcalendarcomponent/releases) and import it into your workspace as a Servoy solution. The demo solution fetches events from a database called 'fullcalendar'; metadata for all database entities are included.\
Before importing the solution create a new database called 'fullcalendar', then allow the import of metadata during import procedure.

Note: the Fullcalendar component is not included in the demo solution export. Once the demo solution is successfully imported into your workspace, open the Web Package Manager to add the Fullcalendar Component.


# Fullcalendar

## Fullcalendar

The Calendar Component is a Servoy NG Component. Use the form editor to place the **fullcalendar** NG Component into your form and use the calendar element's API to initialize the calendar. The component has to be initialized programmatically using the fullcalendar constructor available from the element's API.

NOTE: make sure the calendar component in form has the element name set.

```javascript
var options = {
        eventSources: [ events: [{ title: "lunch event", start: new Date() }]],
		selectable: true,
		editable: true,
		defaultView: 'agendaWeek',
		showCurrentTimeline: true
}
var calendar = elements.fullcalendarElementName.fullCalendar(options);
```

## Calendar Options

The `options` object contains the calendar properties; see the [fullcalendar docs](http://fullcalendar.io/docs/) for available properties. All the properties are optional.\
Set the eventSources options to feed the calendar with [Event Source](http://fullcalendar.io/docs/event_data/Event_Source_Object/) Objects. Event Sources will populate the calendat with [Event](http://fullcalendar.io/docs/event_data/Event_Object/) objects.\
Call the FullCalendar constructor for the same element to destroy and recreate the Calendar.\
Read more about Event and Event Sources at [Fullcalendar Events](https://wiki.servoy.com/display/WEB/Fullcalendar+Events).\
Fullcalendar options can be found [here](/reference/servoyextensions/ui-components/visualization/fullcalendar2#fullcalendaroptions).

## Update Calendar Options

The options `height` , `contentHeight`, `aspectRatio` can be updated at runtime using the calendar's API **options**.

To update any other of the calendar options call again the fullcalendar constructor to force the calendar to be destroyed and be recreated again with the new options.

Note: when calling the constructor the calendar view will be resetted to the default view ( for example if the user has navigated from *Today* to a different date as 1st December 2016, if the calendar constructor is called the calendar will re-render itself to *Today*'s date ). To preserve the calendar navigation set to \*\*true \*\*the additional argument *renderOnCurrentView of the calendar constructor.*

```javascript
// update the calendar aspect ratio
var calendar = elements.fullcalendarElementName.options(aspectRatio, 2);

// update the the calendar to scroll at 13.00.00
// for such update the calendar has to be destroyed and re-rendered again
// set renderOnCurrentView to true on the constructor to maintain the navigation date and view
var options = elements.fullcalendarElementName.getFullCalendarOptions();
options.scrollTime = "13:00:00";
elements.fullcalendarElementName.fullCalendar(options, true);
```

The calendar component offers several events handlers. You can register to the calendar events you would like to interact with from the properties view of the form editor.

## Fullcalendar Event Details

Fullcalendar events can be found [here](/reference/servoyextensions/ui-components/visualization/fullcalendar2#events).

[**onSelect**](/reference/servoyextensions/ui-components/visualization/fullcalendar2#onselectmethodid)

The method that is executed when user select any area of the calendar.

[**onDateClick**](/reference/servoyextensions/ui-components/visualization/fullcalendar2#ondateclickmethodid)

The method that is executed when the user clicks on any space of the calendar.

[**onEventClick**](/reference/servoyextensions/ui-components/visualization/fullcalendar2#oneventclickmethodid)

The method that is executed when the user clicks any event object rendered in the calendar.

[**onEventDrop**](/reference/servoyextensions/ui-components/visualization/fullcalendar2#oneventdropmethodid)

The method that is executed when an event is dropped on the calendar.

[**onEventResize**](/reference/servoyextensions/ui-components/visualization/fullcalendar2#oneventresizemethodid)

The method that is executed when an event is resized on the calendar.

## Fullcalendar Property Summary

Fullcalendar events can be found [here](/reference/servoyextensions/ui-components/visualization/fullcalendar2#properties).

[**styleClass**](/reference/servoyextensions/ui-components/visualization/fullcalendar2#styleclass)

The name of the style class that should be applied to this component.

[**tooltipExpression**](/reference/servoyextensions/ui-components/visualization/fullcalendar2#tooltipexpression)

The text expression to be shown as tooltip when hovering over the calendar events.Use double curly brackets to evaluate {{propertyName}} the event's properties. For non-standard properties, use {{extendedProps.yourPropertyName}}.

**Example**

```
This is the event title:{{title}}. The event starts at: {{start}}. Description: {{extendedProps.data.description}} 
```


# Fullcalendar Events

## Event Object

An [Event](http://fullcalendar.io/docs/event_data/Event_Object/) is a javascript Object which store information about a calendar event. The calendar component renders calendar event as Event Objects.

An Event Object must have a "**start"** date property and a "**title"**, it has other optionals properties which might modify it's behavior and it's style on the calendar component. Use the **"data"** property to add any other custom property to the event as "description", "location" and any other information that might be useful to the developer.

```javascript
var event = {
	title: "lunch event",
	start: new Date(),
	allDay: false,
	editable: true,
	data : {
       description : "This is an event object", 
       location: "Amsterdam"
    }
}
```

## Event Source Object

An [EventSource](http://fullcalendar.io/docs/event_data/Event_Source_Object/) is a javascript Object that provides Event data to the FullCalendar. It can be seen as a collection of Events. The Events associated to an EventSource inherit it's properties if are not specified in the event itself. For example an EventSource having set "yellow' as "backgroundColor\*\*" \*\*will color as yellow all the associated Events except of those having set their own "backgroundColor" property.

The Calendar component differentiates between different EventSource Types, depending on how Events are returned to the Fullcalendar.

* \*\*ArrayEventSourceType \*\*feeds the calendar with an Array of Event Objects.
* **FunctionEventSourceType** uses a Servoy function to feed the calendar with a collection of Event Objects. Any time the user navigates dates and/or calendar views the calendar will execute the events function to fetch Event Objects. The function must return an Array of EventType Objects. Set optional properties in the "data" property of the eventSource to use it as a filter parameters in the function feed.
* \*\*GoogleCalendarEventSourceType \*\*retrieves calendar event from a public Google Calendar feed. See the specific [Google Calendar docs ](http://fullcalendar.io/docs/google_calendar/)for further details.

```javascript
// ArrayEventSourceType sample
/**
 * @type {svy-fullcalendar.EventSourceType}
 */
var arrayEventSource = {
	events: [{
    	title: "source event",
		start: new Date(),
		allDay: true
	}],
	color: 'yellow'
}

// FunctionEventSourceType sample
/**
 * @type {svy-fullcalendar.EventSourceType}
 */
var functionEventSource = {
	events: fetchFunction,
	data: {search: 'Amsterdam'},
	color: 'green',
	ignoreTimezone: false
};

/** 
 * @param {Date} start
 * @param {Date} end
 * @param {Object<String>} [data] optional object to be used as filter parameters in fetching events
*/ 
function fetchFunction(start, end, data) {
 var foundset = databaseManager.getFoundSet("db:/yourserver/yourtable");
 // search data based on your search criteria
    if (foundset.find()) {
		if (data.search) foundset.location = data.search
        foundset.start_date = '>= ' + utils.dateFormat(scopes.svyDateUtils.toStartOfDay(new Date(start)), 'dd/MM/yyyy HH:mm:ss') + '|dd/MM/yyyy HH:mm:ss';
	    foundset.end_date = '<= ' + utils.dateFormat(scopes.svyDateUtils.toEndOfDay(new Date(end)), 'dd/MM/yyyy HH:mm:ss') + '|dd/MM/yyyy HH:mm:ss';
		foundset.search();
    }
	var events = []
    for (var i=1; i<=foundset.getSize(); i++ ) {
		var rec = foundset.getRecord(i)
		// Note: is up to the developer map a datasource to an event object
		events.push({
			start : rec.startDate,
			title :	rec.yourTitle,
			location: rec.location
		});
    }
	return events;
}
```

#### Populate the calendar

Populate the calendar with [Event Object](http://fullcalendar.io/docs/event_data/Event_Object/) and/or [EventSource Object](http://fullcalendar.io/docs/event_data/Event_Source_Object/). Provide the events and eventSources to the **FullCalendar** constructor to populate the calendar as soon it's rendered.

Use the calendar API **renderEvent** and **addEventSource** to render new events at any time without forcing a re-create of the calendar, or the **removeEvents** and **removeEventSources** to remove them from the calendar component.

```javascript
// populate the calendar providing events and eventSources to the constructor
var options = {
		eventSources: [{
			functionEventSource,
            arrayEventSource
		}]
	}
elements.fullcalendar.fullCalendar(options);
```

The API to remove event and eventSource requires the event id or eventSource id. If you haven't set any id to the event or eventSource object you won't be able to remove it.

```javascript
// add an eventSource to a Fullcalendar Object
var eventSource = {
            id : 1,
			events: [{
				title: "green source event",
				start: new Date(),
			}],
			color: 'green'
	}
calendar.addEventSource(eventSource);

// remove the eventSource using the eventSource id
calendar.removeEventSource(1);
```

#### Update Event and EventSource

Call the FullCalendar method \*\*updateEvent \*\*to update an Event which is visible on the calendar. Provide the updated Event object to the API. To update successfully the event the developer must have used an unique id for the event object. The updateEvent API will return false if the id is not provide or if the event is not visible.

To update an eventSource the developer should remove the eventSource from the calendar using \*\*removeEventSource \*\*and add the updated eventSource using the method **addEventSource**.

*NOT SUPPORTED. To update an eventSource developer can modify the original EventSource Object and call the methods \*\*rerenderEvents \*\*to make a change visible in the calendar and the method **refetchEvents** in case events has been added or removed from the EventSource Object.*

#### Display icon in the event object

Display a specific icon in the calendar event is a common use case. The FullCalendar component does not have an explicit property for event icons but such feature can be achieved using the \*\*className \*\*property of event or eventSource objects and CSS3 styling.

Use the CSS3 *before* or *after* pseudo-selector to place an icon before or after the event title (or event time). If you want to place the same icon on all the calendar events you can include the following CSS in your solution's CSS file.

```css
/* display the icon before the title text */
.fc-event .fc-title:before {
	content: url('servoy16x16.png');  /* the icon is picked from the media folder of your Servoy solution */
}

/* display the icon before the event time */
.fc-event .fc-time:before {
	content: url('servoy16x16.png');  /* the icon is picked from the media folder of your Servoy solution */
}
```

If you want to display specific icon on specific events use the **className** property of the event object (or of the eventSource object if you want to display the same icon for all the events of the eventSource).

If your event has className equal to 'custom-icon' then your CSS should look like:

```css
/* display the icon before the title text */
.fc-event.custom-icon .fc-title:before {
	content: url('servoy16x16.png');  /* the icon is picked from the media folder of your Servoy solution */
}

/* display the icon before the event time */
.fc-event.custom-icon .fc-time:before {
	content: url('servoy16x16.png');  /* the icon is picked from the media folder of your Servoy solution */
}
```

Font icons are often more effective then .png/.jpeg icons. You can easier control size color and other property of the icon from CSS. To use Font Icons include them in your solution's media folder and make sure are loaded togheter with your solution's styleSheet. You can simply use the same font icons content as in the example below:

```css
/* display the glyphon calendar icon before the event time */
.fc-event .fc-time:before {
	font-family: 'Glyphicons Halflings';   /* use the glyphicons */
	content: "\e109";     /* the calendar icon to be displayed */
	padding: 0 3px;
}

/* display multiple icons at the same time for events having className icon-multiple*/
.fc-event.icon-multiple .fc-time:before {
	font-family: 'Glyphicons Halflings';   /* use the glyphicons */
	content: "\e109 \e023";     /* display calendar and time icon next to each other */
	padding: 0 3px;
}
```

## Event Property Summary

#### id

String|Number\
Uniquely identifies the given event. Different instances of repeating events should all have the same id. Id is not a required property but is necessary to be able to update or remove the event on the calendar.

#### title

String\
The text shown on the event element. **Required.**

#### start

Date\
The date and time an event begins. **Required.**

#### end

Date\
The date and time an event ends.

#### allDay

Boolean\
Whether an event occurs at a specific time-of-day. This property affects whether an event's time is shown. Also, in the agenda views, determines if it is displayed in the "all-day" section.\
If this value is not explicitly specified, [allDayDefault](http://fullcalendar.io/docs/event_data/allDayDefault/) will be used if it is defined.

#### className

String|Array\
A CSS class (or array of classes) that will be attached to this event's element.

#### data

Object\
A custom object which can be used to add custom properties to the event object.

#### resourceIds

Array\
Associate the event with the resource ids provided. Scheduler feature.

#### editable

Boolean\
The event will not be editble if set to false.

#### startEditable

Boolean

#### durationEditable

Boolean

#### overlap

Boolean

#### rendering

String\
Use value 'background' to render the event as a background event.

#### constraint

Object

#### color

Color

#### backgroundColor

Color

#### borderColor

Color

#### textcolor

Color

## Event Source Property Summary

#### id

String|Number\
Uniquely identifies the given event source. Id is not a required property but is necessary to be able to remove the event source from the calendar without being force to redraw the calendar it self.

#### googleCalendarId

String\
The Google Calendar ID to be used to fetch the google calendar events. Do not set the "events" property if you are using the eventSource to fetch Google Calendar events.

#### googleCalendaApiKey

String\
The Google Calendar API Key which is required to allow the fetching of Google Calendar events.

#### className

Array\
A CSS array of classes that will be attached to this event's element.

#### data

Object\
A custom object which can be used to add custom properties to the event source object.

#### allDayDefault

Boolean\
Determines the default value for each Event Object's `allDay` property when it is unspecified.

#### editable

Boolean\
The event will not be editble if set to false.

#### startEditable

Boolean

#### durationEditable

Boolean

#### overlap

Boolean

#### rendering

String\
Use value 'background' to render the event as a background event.

#### constraint

Object

#### color

Color

#### backgroundColor

Color

#### borderColor

Color

#### textColor

Color


# Migrating calendar from Smart and Web client to NG client

NOTE: this page is a reference for who is migrating from the Smart and Web client version of the fullcalendar to the NG version.

The Web and Smart version of the fullcalendar, which was based on the javaFX panel, should be replaced with the fullcalendar web component in the NG Client. The Calendar NG Component API forare mostly back-compatible with the Smart and Web client version.

The initialization of the Calendar is slightly different in NG; read the documentation on how to use the Calendar NG Component.

In the Calendar NG Component most of the extra features that have been implemented for the Smart and Web client version of the calendar component have been deprecated; built-in feature of the fullcalendar library are used instead.

## Resources

Allow to use a calendar Resource View type which renders all the events related to the existing resources on the selected Date.\
The resourceView type has deprecated in favour of the fullcalendar Scheduler.\
See the Calendar Resources section for detailed documentation about the Scheduler.

## Annotations

Annotations Object are placed on the Agenda views slots. Use annotations to mark a specific timeslot and to change background color for the specified period.

The annotations objects are deprecated in the NG version of the calendar component. Instead of annotations object the developer can use the calendar option businessHours or add to the calendar event objects as background events.

The businessHours is used to emphasizes a specific time block in the agenda views. The businessHours is defined as a JSON object which may have any of the following properties

**start** The date/time the businessHours begins\
**end** The date/time an businessHours ends. Required\
**dow** The days of the week the businessHours is applied

```javascript
var options = {
        eventSources: [events: [{ title: "lunch event", start: new Date(), id: 1 }]],
		businessHours: {
				start: new scopes.svyDateUtils.DateTime().toStartOfDay().addHours(9).date,
				end: new scopes.svyDateUtils.DateTime().toStartOfDay().addHours(17).date,
				dow: [1,2,3,4,5] // Apply businessHours Monday to Friday
		}
}
elements.calendarElementName.fullcalendar(options);
```

Events that appear as background highlights can be achieved by setting an Event Object's rendering property to background.\
Background events that are timed will only be rendered on the time slots in agenda view. Background events that are all-daywill only be rendered in month view or the all-day slots of agenda view.

The color of background events can be manipulated by targeting the fc-bgevent className, one of your own custom classNames provided by the Event Object's className property, or by explicitly specifying a color with each Event Object's orEvent Source's color or backgroundColor properties.

It is possible to define daily or weekly recurring events. Use Duration-ish times in the Event Object's start and endproperties, or use the dow property. See businessHours for more information. For further details read the fullcalendar documentation on Background Events.

## Event rightClick

Triggered when the user right clicks an event.\
The eventRightClick is an event of the calendar component.

```javascript
function( eventObject, event, view ) { }
```

**eventObject** is an Event Object that holds the event's information (date, title, etc).\
**event** the JSEvent that triggered the action.\
**view** holds the current View Object.

## Calendar dayRightClick (deprecated)

Triggered when the user right clicks on a Day.

This event has been deprecated and is not supported in the NG version of the calendar component.

## Timeline

Show the current time as a red line in the calendar view.\
The calendar option showCurrentTimeline has been deprecated and replaced by the new calendar option nowIndicator.

Default: false

```javascript
var options = {
        eventSources: [events: [{ title: "lunch event", start: new Date()}]],
		nowIndicator: true
}
elements.calendarElementName.fullcalendar(options);
```

Use CSS to style the .fc-now-indicator border-color and change the timeline color

```css
/*CSS to customize timeline*/
.fc-now-indicator {
	border-color: blue;
}
```


# Fullcalendar Component 2

FullCalendar Component 2 is a Servoy Web Package containing the implementation of the Fullcalendar component as a Servoy Web Component for Titanium NG client.

## Requirements

The FullCalendar Component 2 can be used on Servoy 2021.12 or higher.

## Getting started

To add the FullCalendar Component 2 package in your solution, open the Servoy Developer IDE and download the FullCalendar Component 2 from the Servoy Package Manager (the Servoy Package Manager is accessible from the context menu of the Servoy Packages node of your solution).

To use the latest source code clone the git repository and checkout the master branch. Install the [egit](https://eclipse.dev/egit/download/) plugin for Eclipse to clone the repository and import the projects into the workspace.

## Documentation

See the NG1 [FullCalendar](/guides/develop/application-design/ui-components/specialized-components/home-2#introduction) guide for the available documentation.

## FullCalendar functions support

FullCalendar component has support in various places for client side (javascript functions), that can return dynamic content based on parameters. For example: [Content Injection](https://fullcalendar.io/docs/content-injection) or [Classnames callback](https://fullcalendar.io/docs/classname-input). In order for this to work in Titanium Client you have to use [generateBrowserFunction API](/reference/servoycore/dev-api/application#generatebrowserfunction-functionstring).

**Example (set in component options):**

```javascript
eventContent: application.generateBrowserFunction("function(arg) { return {html : '<b>my event<br/>123</b>'} }") ,
eventClassNames:  application.generateBrowserFunction("function(arg) { return 'dummyclass' }"),
```

## FullCalendar premium features

FullCalendar component also has some premium features (or premium plugins) that have a different licensing model. In order to use those you need to specify a valid schedulerLicenseKey in your options. For more information see : [schedulerLicenseKey Property](https://fullcalendar.io/docs/schedulerLicenseKey) and [Fullcalendar License Information](https://fullcalendar.io/license). See also [Fullcalendar Plugin Information](https://fullcalendar.io/docs/plugin-index) in order to figure out which are the premium features.




---

[Next Page](/llms-full.txt/1)

