# Sekcja powtarzalna - RepeatableSection

Zestaw pól, które mogą być wielokrotnie wypełnione we wniosku przez użytkownika.

![](/files/f853d33eb03110981670ad9427668f904670cca9)

## Właściwości komponentu

<table><thead><tr><th>Właściwość Eximee Designer</th><th width="187.583251953125">Nazwa atrybutu w Źródle</th><th>Opis</th></tr></thead><tbody><tr><td><strong>Minimalna liczba wystąpień sekcji</strong><br>(sekcja <strong>Podstawowe właściwości</strong>)</td><td>minCount</td><td>Minimalna liczba wystąpień sekcji powtarzalnej (początkowa wartość 1). W chwili wyświetlania wniosku jest to także liczba wystąpień, które są domyślnie widoczne i dostępne. Usuwając elementy sekcji podczas wypełniania wniosku nie można zejść poniżej tej liczby.</td></tr><tr><td><strong>Maksymalna liczba wystąpień sekcji</strong><br>(sekcja <strong>Podstawowe właściwości</strong>)</td><td>maxCount</td><td>Maksymalna liczba wystąpień sekcji powtarzalnej (początkowa wartość 1). Dodając elementy sekcji nie można przekroczyć tej liczby.</td></tr><tr><td><strong>Tytuł</strong><br>(sekcja <strong>Podstawowe właściwości</strong>)</td><td>title</td><td><p>Tytuł.</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Tytuł całej sekcji powtarzalnej</strong><br>(sekcja <strong>Podstawowe właściwości</strong>)</td><td>parentSectionTitle</td><td>Tytuł dla całej sekcji powtarzalnej.</td></tr><tr><td><strong>Etykieta przycisku zwinięcia sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td></td><td><p>Etykieta przycisku zwinięcia sekcji.</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Etykieta przycisku rozwinięcia sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td></td><td><p>Etykieta przycisku rozwinięcia sekcji.</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Sekcja zwijana</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>foldable</td><td><p>Określa czy sekcja powinna mieć możliwość zwinięcia (początkowo ustawiona na "false").</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Warunek zwinięcia sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>foldedCondition</td><td><p>Warunek zwinięcia sekcji.</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniami.</p></td></tr><tr><td><strong>Sposób prezentacji rozwijania sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>presentation</td><td><p>Określenie sposobu prezentacji rozwijania sekcji. Dostępne typy prezentacji zwijania/rozwijania: STANDARD i LABELS (poniżej szerszy opis).</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Dynamiczne etykiety przycisków</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>plusMinusLabels</td><td>Warunki dla widoczności przycisków dodawania/usuwania elementów sekcji powtarzalnej.</td></tr><tr><td><strong>Etykieta przycisku usunięcia sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>minusText</td><td>Etykieta dla przycisku minus (usunięcie elementu sekcji powtarzalnej).</td></tr><tr><td><strong>Etykieta przycisku dodania sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>plusText</td><td>Etykieta dla przycisku plus (dodanie elementu sekcji powtarzalnej).</td></tr><tr><td><strong>Tytuł rozwijanej sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>rowTitleExpanded</td><td><p>Tytuł wyświetlany dla rozwiniętej sekcji.</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Tytuł zwiniętej sekcji</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>rowTitleCollapsed</td><td><p>Tytuł wyświetlany dla zwiniętej sekcji.</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Obramowanie komponentu</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>parentSectionFrameVisible</td><td><p>Ustawienie flagi powoduje wyświetlenie ramki wokół wszystkich wystąpień sekcji powtarzalnej (początkowo ustawiona na "false").</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Wartość przesunięcia przycisku dodawania</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>plusButtonOffset</td><td><p>Wartość przesunięcia przycisku dodawania (początkowo ustawiona na 0).</p><p>Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.</p></td></tr><tr><td><strong>Pomoc kontekstowa przycisku usuwania</strong><br>(sekcja <strong>Pozostałe</strong>)</td><td>minusToolTipText</td><td>Pomoc kontekstowa przycisku usuwania wiersza</td></tr></tbody></table>

> Więcej informacji o właściwościach komponentu: [Wspólne właściwości komponentów](/budowanie-aplikacji/interfejs-uzytkownika/formularze/praca-z-komponentami-bazowymi/wspolne-wlasciwosci-komponentow.md)

## Praca z sekcją powtarzalną

Umieszczenie sekcji powtarzalnej na szablonie wniosku powoduje dodanie obszaru, z którym można pracować podobnie jak z całym wnioskiem. Oznacza to, że obszar ten ma swój własny układ strony i może zawierać dowolną liczbę komponentów bazowych. W przykładzie na rysunku wystąpienie sekcji powtarzalnej skonfigurowane zostało jako kompozyt składający się z pola tekstowego i pól wyboru wartości z listy z etykietami. Znak plus/minus w prawym dolnym rogu służy do dodawania kolejnych wierszy sekcji.

W wynikowym wniosku wystąpienia sekcji powtarzalnej wyświetlane są zgodnie z konfiguracją. Użytkownik ma możliwość usuwania bądź dodawania wystąpień, używając odpowiednio przycisku **minus** oraz **plus**.

<figure><img src="/files/29d77dca2b9eb2325166858a6aae9837b0bf4522" alt=""><figcaption><p><em><strong>Ilustracja 1.</strong> Przykładowy wygląd komponentu na wniosku.</em></p></figcaption></figure>

{% hint style="warning" %}
W Repeatable Section nie można użyć [zmiennych sesyjnych](/budowanie-aplikacji/interfejs-uzytkownika/formularze/zmienne-sesyjne.md) — tutaj używamy pól technicznych (np. komponent Pole tekstowe z zaznaczoną właściwością [Pole techniczne](/budowanie-aplikacji/interfejs-uzytkownika/formularze/praca-z-komponentami-bazowymi/wspolne-wlasciwosci-komponentow.md)). Również zasilanie pól z usługi w sekcji powtarzalnej może powodować nietypowe błędy — np. nieprawidłowe wyświetlanie komponentów (ale nie musi). W takiej sytuacji należy zastosować obejście w postaci pola technicznego.
{% endhint %}

## Zasilenie sekcji powtarzalnej usługą

Zalecane jest, aby tworząc ServiceProxy dziedziczyć po klasie **AbstractRepeatableServiceProxy**. Klasa ta automatycznie zwraca 3 wartości: minCount, maxCount i count. Wartości te można ustawić lub nic z nimi nie robić — są one opcjonalne.

Przykładowe ServiceProxy:

* Są w nim dodane 2 pola wejściowe,
* Są w nim dodane 2 dodatkowe pola wyjściowe (**minCount**, **maxCount**, **count** dodane są w klasie wyżej),
* Aby ustawić parametry trzeba jedynie na modelu **RepeatableSectionMetadata** wywołać odpowiednie settery,
* Po ustawieniu powyższych parametrów, ustawiamy wartości które potem będziemy mapować na poszczególnych polach.

```java
@Component
@Service(AbstractServiceProxy.class)
public class RepeatableTestSp extends AbstractRepeatableServiceProxy {

    public RepeatableTestSp(String name, String description) {
        super("RepeatableTestSp", "Description...");
        this.inputFields.add(new ServiceProxyField("input1"));
        this.inputFields.add(new ServiceProxyField("input2"));
        this.outputFields.add(new ServiceProxyField("output1"));
        this.outputFields.add(new ServiceProxyField("output2"));
    }

    @Override
    protected RepeatableSectionMetadata callRepeatableSectionService(
            Map<String, List<String>> requestParams, String lang) throws ServiceProxyException {
        final RepeatableSectionMetadata repeatableSectionMetadata = new RepeatableSectionMetadata();
        repeatableSectionMetadata.setMinCount(1);
        repeatableSectionMetadata.setMaxCount(10);
        repeatableSectionMetadata.setCount(5);
        repeatableSectionMetadata.setRepeatableSectionRows(createRows());
        return repeatableSectionMetadata;
    }

    private List<Map<String, String>> createRows() {
        final List<Map<String, String>> rows = new ArrayList<>();
        rows.add(createRow());
        rows.add(createRow());
        return rows;
    }

    private Map<String, String> createRow() {
        final Map<String, String> map = new HashMap<>();
        map.put("output1", "1");
        map.put("output2", "abc");
        return map;
    }
}
```

Aby skorzystać z powyższego ServiceProxy, w **externalDataSource** powinien być typ **REPEATABLE\_SCECTION\_SERVICE**.

Podsumowując: usługa dodała 2 wiersze, jednak ustawiła wartość count na 5. Tak więc zostanie wyświetlone 5 wierszy, z czego tylko 2 się wypełnią zmapowaną wartością z endpointu output1.

{% hint style="info" %}
Istnieje również możliwość zasilenia sekcji powtarzalnej skryptem.
{% endhint %}

## Przykład sekcji powtarzalnej z wartościami do zsumowania

Gdy chcemy zsumować wartości z powtarzającego się komponentu GesTextField1 w sekcji powtarzalnej, tworzymy nowy GesTextField2 poza sekcją i podpinamy w **Źródle danych zewnętrznych** skrypt SumService:

```javascript
function callService(context) {
    let parts = context.getParameters('parts');
    
    let result = BigDecimal.valueOf("0");
    
    if (!!parts) {
        for (let i = 0; i < parts.size(); i++) {
            let part = parts.get(i);

            if(!!part){
                let bigDecimalItem = BigDecimal.valueOf(part.replace(',','.'));
                result = result.add(bigDecimalItem);
            }
        }
    }
    
    return [{'output': result.setScale(2)}];
}
```

W parametrach wejściowych skryptu podpinamy powtarzający się komponent z wartościami do zsumowania GesTextField1, a w parametrach wyjściowych wybieramy output, czyli sumę wartości, jako atrybut text.

<figure><img src="/files/sWKZ0VySHPcZLoUCHdq6" alt=""><figcaption><p><em><strong>Ilustracja 2.</strong> Podpięcie parametru wyjściowego w skrypcie SumService</em></p></figcaption></figure>

{% hint style="info" %}
Wnioski demo:

* demoRepeatableSection
* repeatable\_section\_service (wniosek pokazujący zasilenie sekcji usługą lub skryptem)
* demoRepeatableSectionValidator (wniosek z walidatorem dla powtarzających się wartości w sekcji)
  {% endhint %}

{% hint style="info" %}
♿WCAG: [Dobre praktyki WCAG dla low-code dev](/budowanie-aplikacji/proces-biznesowy/tworzenie-procesu-biznesowego-w-bpmn-2.0/dobre-praktyki.md)
{% endhint %}


---

# 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/budowanie-aplikacji/interfejs-uzytkownika/formularze/biblioteka-komponentow-bazowych/7-komponenty-specjalne/sekcja-powtarzalna-repeatablesection.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.
