# Specialized component - ExternalSection

{% hint style="info" %}
Availability of the functionality depends on the license and may not be available in all implementations.
{% endhint %}

## Component properties

| Eximee Designer property | Attribute name in Source | Description                                                                   |
| ------------------------ | ------------------------ | ----------------------------------------------------------------------------- |
| **Resource URL**         | url                      | Allows specifying the resource URL to embed within the specialized component. |

## External data source for the specialized component

The content of the specialized component, apart from providing the resource URL, can be supplied using an external data source of type **SECTION**. The data source configuration procedure is described in chapter [Example of hooking it up in a service component](/documentation/documentation-en/budowanie-aplikacji/interfejs-uzytkownika/formularze/praca-z-komponentami-bazowymi/zasilanie-wartosciami-z-zewnetrznych-zrodel/przyklad-podpiecia-w-komponencie-uslugi.md).

## ExternalSection in the GWT channel

For all *ExternalSection* that create the DOM and use the old GWT classes, you should:

* for proper styling:
  * assign a class to these elements in Eximee Designer (**styleName**): **legacy** (e.g. in **ExternalSection** a button is drawn, there is a slider styled in the old way)
  * or add in the **ExternalSection** on the root element a class: **legacy** (transparent for old forms)
* assign a class to the element in Eximee Designer: *external-section-content* (**ExternalSection** without the class *external-section-content* will not take up space in the application. They will also not cause a small *spacer* separating components.)

In **legacy** not all styles are supported.

With **legacy** will be consistent with the new forms (a class capable of styling part of the application structure).

For old ES, in addition to the two classes mentioned above, you can also assign new ones. For new ones, you can use the above classes or assign new ones.

<figure><img src="/files/44550bfb2a14cd75201085f0ca152a8deab361d0" alt=""><figcaption><p><em><strong>Figure 1.</strong> Example appearance of the component in Eximee Designer</em></p></figcaption></figure>

If components are inserted from now on (without using old classes), any (new) class can be assigned; if old ones are used, you need to add *legacy.*

## Creating a service that returns ExternalSection content in Java

### New ServiceProxy API (since version 0.63.0)

Input parameters:

* The input is an object of type **ExternalSectionInput** containing the following fields:
  * **params** (accessible via the method **getParams**()) - a map of parameters mapped to the service on the application template
  * **targetApplication** (accessible via the method **getTargetApplication**()) - identifier of the channel calling the service. Current channels:
    * "W4" - webforms application (old GWT webforms)
    * "ex-forms" - ex-webforms application (new Angular application)
* Additionally, the parameter "**componentId**" is always passed in the parameter map, indicating the identifier of the component on which the service is embedded

Output parameters:

* The output is an object **ExternalSectionOutput** containing the following fields:
  * **output** (also passed in the single-argument constructor) - service output in HTML language (UTF-8 encoding)

```java
package pl.consdata.eximee.examples;
  
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
  
import pl.consdata.iew.serviceproxy.api.exceptions.ServiceProxyException;
import pl.consdata.iew.serviceproxy.api.section.AbstractExternalSection;
import pl.consdata.iew.serviceproxy.api.section.ExternalSectionInput;
import pl.consdata.iew.serviceproxy.api.section.ExternalSectionOutput;
import pl.consdata.iew.serviceproxy.api.types.ServiceProxyField;
  
@Component
@Service(AbstractExternalSection.class)
public class NewApiExampleExternalSection extends AbstractExternalSection {
  
   public NewApiExampleExternalSection() {
      this.name = "NewApiExampleExternalSection";
      this.inputFields.add(new ServiceProxyField(ENTRY_PARAM));
   }
  
   @Override
   public ExternalSectionOutput callServiceForExternalSection(ExternalSectionInput externalSectionInput)
         throws ServiceProxyException {
      String param = getSingleValue(externalSectionInput.getParams(), ENTRY_PARAM, "default value");
      if ("W4".equals(externalSectionInput.getTargetApplication())) {
         return new ExternalSectionOutput(String.format("<b>Webforms GWT</b><br><b>Input parameter:</b>%s<br>",
               param));
      } else if ("ex-forms".equals(externalSectionInput.getTargetApplication())) {
         return new ExternalSectionOutput(String.format("<b>EX-webforms</b><br><b>Input parameter:</b>%s<br>",
               param));
      } else {
         return new ExternalSectionOutput(String.format("<b>Channel: %s</b><br><b>Input parameter:</b>%s<br>",
               externalSectionInput.getTargetApplication(),
               param));
      }
   }
  
   static final String ENTRY_PARAM = "inputParameter";
}
```

### Old ServiceProxy API (since version 0.63.0 marked as deprecated)

Input parameters:

* **targetApplication** (accessible via the method **getTargetApplication**()) - identifier of the channel calling the service. Current channels:
  * W4 - webforms application (old GWT webforms)
  * OTHER (since version 0.63.0 API) - any channel other than W4
* **params** - map of parameters mapped to the service on the application template
* additionally, the parameter "**componentId**" is always passed in the parameter map, indicating the identifier of the component on which the service is embedded

Output parameters:

* The output is an object of type String, which contains the service output in HTML language (UTF-8 encoding)

```java
package pl.consdata.eximee.account.szkolenie;
  
import static org.apache.commons.lang3.StringUtils.EMPTY;
  
import java.util.List;
import java.util.Map;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
  
import pl.consdata.iew.serviceproxy.api.exceptions.ServiceProxyException;
import pl.consdata.iew.serviceproxy.api.section.AbstractExternalSectionServiceProxy;
import pl.consdata.iew.serviceproxy.api.section.ExternalSectionTargetApplication;
import pl.consdata.iew.serviceproxy.api.types.ServiceProxyField;
  
@Component
@Service(AbstractExternalSectionServiceProxy.class)
public class ExampleExternalSection extends AbstractExternalSectionServiceProxy {
  
    public ExampleExternalSection() {
        this.name = "ExampleExternalSection";
        this.description = "ExampleExternalSection description";
        this.inputFields.add(new ServiceProxyField(INPUT_FIELD));
    }
  
    @Override
    public String callServiceForExternalSection(
            ExternalSectionTargetApplication targetApplication,
            Map<String, List<String>> params) throws ServiceProxyException {
        String input = getSingleValue(params, INPUT_FIELD, EMPTY);
        return String.format("<script>alert('%s')</script>", input);
    }
  
    private static final String INPUT_FIELD = "input";
  
}
```

### Designing specialized components

The service supplying a specialized component can return two types of content:

* Resource URL,
* Content to be embedded in the presented application.

#### Resource URL

A service returning a resource URL responds with a one-line message in the form:

```
URL:resourceUrl
```

For example:

```
URL:http://image.server.address/photo.png
```

A specialized component supplied with a URL presents static content.

#### Content to be embedded in the presented application

The content returned by the service will be embedded directly in the presented application. The specialized component can take the form of:

* an HTML document,
* JavaScript script:
  * saved in \<script>...\</script> tags
    * it is possible to provide multiple consecutive \<script /> tags one after another
  * saved in \<script src="..." /> tags
    * it is possible to provide multiple consecutive \<script /> tags one after another
* a combination of an HTML document and \<script /> tags.

Application **eximee WebForms** provides the library by default *jQuery,* which can be used when designing a specialized component. External libraries must be provided manually by adding the appropriate \<script src="..." /> tags.

The prepared specialized component is embedded directly in the DOM tree of the presented application, and during rendering, the instruction is invoked on all \<script /> tags *eval*.

#### Saving the value of a specialized component

A specialized component can be a rich application written in JavaScript that can update the application model with its value. In this way, the saved value is taken into account when calculating component conditions, updating dependent components, supplying services, saving when submitting the application, etc.

To set the value of a specialized component, call the global method provided by the **eximee WebForms application:**

```
updateExternalSectionValue(SpecializedComponentIdentifier, NewComponentValue);
updateExternalSectionValue(externalSection.attr('id'), 'newValue');
```

{% hint style="info" %}
The structure externalSection.attr('id') means that the DOM tree node corresponding to the specialized component has the attribute id = specialized component identifier.
{% endhint %}

Its invocation updates the model of the presented application and notifies all components dependent on the specialized component about the changes.

### Integration at the application frontend level

The specialized components API enables, among other things, integration with the application in which the form is embedded (e.g. in the case of a WWW channel embedded as a portal element) at the JavaScript level. The API provides methods for reading and writing the state of components in the application.

#### Retrieving the value of another component

To retrieve the value of another component, call the function getComponentValue("ID\_OF\_THE\_COMPONENT\_WHOSE\_VALUE\_WE\_WANT\_TO\_READ") from the ExternalSection script, e.g.:

```
var textfieldValue = getComponentValue("GesTextField1");
```

However, keep in mind the following limitations:

* If you want to read session variables, they must have the "exposed" property checked,
* Only the client-side model can be read - i.e. components from already visited pages, potentially unvalidated fields.

#### Setting the value of another component from a script

All fields that can be changed by the specialized component code must be added to the *writableFields* parameter of the component that we set in the application in the **Source**. A request to change the value of a component not included in the *writableFields,* will be ignored by the platform.

To set values for other components from JavaScript, call the following function:

```
/**
 * @param externalSectionId - id of the externalSection that will want to call setComponentValue
 * @param componentId - id of the component whose value we want to set. Webforms automatically sends it to each component under the key componentId
 * @param newValue - new value for this component
 */
setComponentValue(externalSectionId,componentId, newValue);
```

The set of components whose values we can set includes:

* GesTextField
* GesRadioGroup (important! set a value that is in the radio group domain. Otherwise, an error will be returned on the application).
* GesCheckboxSection
* GesCheckbox
* GesTextArea
* GesStatementPopup
* Combobox (id of the item we want to set)
* Slider (value from the appropriate range)
* StepSlider (value from the appropriate range)
* PlusMinus (value from the appropriate range)
* DatePicker (Long value)

Function parameters *setComponentValue* then **Strings**. An example function call is shown below:

```
setComponentValue('GesComplexComponent1.GesExternalSection1','GesComplexComponent1.GesTextField3', 'aaaaaa');
```

Passing a value to GesStatementPopup:

* the value should be a string containing a JSON object with the following structure: { MID\_STATEMENT1 : value, MID\_STATEMENT2 : value ... }
* the value passed in the object must be of type boolean (true / false)
* only in the object will be changed
* example call:

  ```
  setComponentValue('GesComplexComponent1.GesExternalSection1','GesComplexComponent1.GesStatementPopup1', '{ "GesComplexComponent1.item1": true }')
  ```


---

# 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/komponenty-rozszerzone/komponent-specjalizowany-externalsection.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.
