# Data model on the interface

### Binding form fields to the data model

When the data model is already defined and attached, we can in **the application form** associate specific fields (UI components) with model fields. In the form editor, each component that stores some value (e.g. text field, choice field, date, etc.) has the property **"Data model key"**. It is enough to enter in this field the key defined in our model so that the data from this component is bound to the appropriate place in the model. From that moment, the component becomes **bidirectionally bound** (two-way binding) to the data model – during form initialization, the value from the model (if it exists) will be loaded into the field, and when the user fills in or changes this value, it will be saved back to the data model when the application is saved. This means that **after saving the form, all bound fields update their corresponding values in the data model**, so the model always reflects the current state of the application data.

<figure><img src="/files/75e6ef7114487338924a8853c2eeac2ce67b40b6" alt=""><figcaption><p>Illustration 1. Example of two-way binding using the data model key</p></figcaption></figure>

{% hint style="info" %}
**Info:** It is also possible to use **one-way binding** of a field to the model in situations where we only want to display a value from the model on the form, but not update it based on user input. Such a one-time read is implemented, for example, by inserting a reference to a model variable in texts (labels) or using the component property **`valueSourceId`**, which will fetch the value from the model read-only only. By default, however, for editable fields we use two-way binding so that the entered data is saved.
{% endhint %}

<figure><img src="/files/18973806107dc143af6b3728d98690d58a43c7b1" alt=""><figcaption><p>Illustration 2. Example of one-way binding using valueSourceId</p></figcaption></figure>

It should be remembered that **not every form component can be bound to the model**. A data model only makes sense for fields that store values. Therefore, we will not bind to the model, for example, such elements as:

* links (hyperlinks),
* CAPTCHA fields,
* individual radio buttons (except radio button groups),
* popup windows,
* QR codes (if they occur as an image/decorative element).

All other fields (text, number, list selections, checkboxes, dates, sections, etc.) can and **should** be bound to the data model if their value is to be preserved or used outside the form itself. This binding ensures consistency – every piece of data entered by the user has its place in the model, from where it can be further processed (e.g. passed to the process).

Values from the data model can be used in the TextContent artifact, e.g.

{% code expandable="true" %}

```java
<p>
    Sample content ${model:client.name}
</p>

```

{% endcode %}

### Handling array fields (lists)

The data model allows defining fields that are collections (arrays) of objects or simple values. If in the model a given field is to have multiple repetitions (e.g. a list of addresses, a list of products, etc.), its `multiplicityMax` > 1 (e.g. `null` for no upper limit) and prepare an appropriate data source returning a collection. In the form, such a field can be represented, for example, by **a Repeatable Section** (Repeatable Section) with appropriate fields inside. It is important to **correctly refer to array elements** in model keys:

* `collection[].field` – reference to *all* occurrences of the field in the collection (returns the entire list of values or, for example, a concatenation, depending on the context),
* `collection[0].field` – reference to the field in the **first** element of the collection (index 0 means the first element, 1 - the second, etc.),
* **Note:** The index cannot be omitted! The syntax `collection.field` (without `[]` or an index) is incorrect and will cause an error preventing the form from being launched. Always use array notation when referring to fields of collection elements.
* For repeatable sections in the form, where the user can dynamically add/remove elements, Eximee uses the variable `_rowIdx` assigned to a given section, to pass the index of the current row. In the model key, an identifier then appears in the form of `SectionName_rowIdx`. For example, if the repeatable section is bound to the collection `products[]` and has a field `name`, then the field key in the section may look like: `products[SectionName_rowIdx].name`. This mechanism ensures that each dynamically added field is bound to a unique index in the model.

<figure><img src="/files/e16684d6ad8dc5321dd5730158f9775bad196095" alt=""><figcaption><p>Illustration 3. Attaching an array field to a repeatable section</p></figcaption></figure>

<figure><img src="/files/684628eaa2a065193c60ca5fe534cc44ed588e6d" alt=""><figcaption><p>Illustration 4. Attaching a Combobox located in a repeatable section to the data model</p></figcaption></figure>

### dataModelTransformer

Thanks to **dataModelTransformer**, located in the XML ("Source" tab), you can influence the data that will drop into the data model after the application is saved.

To use this functionality, add a script in the XML (in ecMetadata inside iftTemplateMetadata) that will be able to modify the saved model.

Example of mapping session variables to the data model:

{% code expandable="true" %}

```java
<dataModelTransformer>
  <content>
      function transform(input) {
          input.put('bazaOfert.KredytNr', api.form.v1.value("agreementId"));
          input.put('bazaOfert.CIF', api.form.v1.value("cif"));
          if(api.form.v1.value("GesCheckbox5") == "false"){
              input.put('daneKlientaCis.NumerTelefonu', api.form.v1.value("phoneNumber"));
              input.put('daneKlientaCis.AdresEmail', api.form.v1.value("email"));
          }  
          return input;
      }
  </content>
</dataModelTransformer>
```

{% endcode %}

Example of mapping values from invisible fields to the data model:

{% code expandable="true" %}

```java
<dataModelTransformer>
  <content>
      function transform(input) {
              for (let node of api.form.v1.invisibleFormNodes()) {
                  if(node.model()) {
                      input.put(node.model(), '');
                  }
              }
              return input;
          }
  </content>
</dataModelTransformer>
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/interfejs-uzytkownika/formularze/praca-z-komponentami-bazowymi/model-danych-na-interfejsie.md?ask=<question>
```

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

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