# Komponent niestandardowy - CustomComponent

{% hint style="warning" %}
Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.
{% endhint %}

Komponent niestandardowy (CustomComponent) pozwala na tworzenie własnych komponentów dla wniosku z wykorzystaniem języka **JavaScript**.

CustomComponent składa się z ośmiu elementów:

* Skryptu JavaScript,
* Stylów CSS komponentu,
* Szablonu HTML komponentu,
* Mapowań parametrów wejściowych komponentu,
* Listy użytych serwisów,
* Listy akcji dostępnych dla tego komponentu,
* Tłumaczeń tekstów dla komponentu,
* Podglądu.

## Tworzenie komponentu <a href="#komponentniestandardowycustomcomponent-tworzeniekomponentu" id="komponentniestandardowycustomcomponent-tworzeniekomponentu"></a>

Nowy komponent tworzy się w ten sam sposób co inne komponenty. Po przejściu do modułu **Biblioteka** i wybraniu zakładki **Komponenty niestandardowe** klikamy przycisk **Dodaj komponent niestandardowy** i w otwartym oknie ustalamy nazwę i lokalizację tworzonego artefaktu (Więcej informacji na temat samego edytora: [Edytor komponentów niestandardowych](https://docs.eximee.com/budowanie-aplikacji/interfejs-uzytkownika/komponenty-rozszerzone/komponent-niestandardowy-customcomponent/edytor-komponentow-niestandardowych))

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2F5XKDHhiqh9TVb5pV12ub%2Fimage.png?alt=media&#x26;token=605edb4d-ee2a-41e2-b749-6449256fac73" alt=""><figcaption><p><em><strong>Ilustracja 1.</strong> Widok edycji nowo utworzonego komponentu</em></p></figcaption></figure>

## Skrypt JavaScript <a href="#komponentniestandardowycustomcomponent-skryptjavascript" id="komponentniestandardowycustomcomponent-skryptjavascript"></a>

Każdy z CustomComponent'ów składa się z jednej głównej funkcji, której przekazywany jest **Scope** komponentu:

```
function($scope) {
  
}
```

Za pomocą scopu twórca może m.in. pobierać dane komponentu, dane wejściowe oraz reagować na pewne zdarzenia z cyklu życia komponentu. Użytkownik może zaimplementować trzy systemowe metody komponentu:

* **afterViewInit** - wykonywana w momencie dodania komponentu do struktury DOM wniosku,
* **onModelChange** - wykonywana w momencie zmiany modelu (np. wartości) komponentu lub wartosci danych wejściowych,
* **onDestroy** - wykonywana w momencie usuwania komponentu ze struktury DOM wniosku.

Dodatkowo scope komponentu dostarcza kilka przydatnych elementów:

* pola:
  * **domId** - ID komponentu w strukturze DOM wniosku
  * **componentId** - ID komponentu
  * **componentMid** - MID komponentu
  * **visible** - zmienna sterująca widocznością komponentu
  * **translations** - mapa tłumaczeń zdefiniowanych na etapie tworzenia komponentu
  * **componentId** - mapa parametrów wejściowych komponentów
  * **componentData** - mapa wewnętrznych danych komponentu (pozwala na zachowanie stanu komponentu)
  * **componentInput** - mapa danych wejściowych komponentu (klucze definiowane są w sekcji **Inputs** oddzielone przecinkami)
* metody:
  * getValue() - pobiera aktualną wartość komponentu
  * setValue(value) - ustawia aktualna wartość komponentu
  * querySelector(query) - zwraca element struktury DOM komponentu, który został dopasowany do selektora.
  * putData(key, value) - ustawia określoną wartość (value) pod kluczem (key) w mapie danych komponentu - tylko po stronie klienta przeglądarki
  * saveData(key, value) - ustawia określoną wartość (value) pod kluczem (key) w mapie danych komponentu - także po stronie serwera
  * getData(key) - pobiera wartość określoną pod kluczem (key) w mapie danych komponentu
  * translate(key) - zwraca tłumaczenie z mapy tłumaczeń
  * clean() - czyści obiekt scope, gdy nie jest już używany przez CustomComponent
  * callServiceProxy(serviceName, params) - pozwala zawołać usługi ServiceProxy oraz ScriptService w sposób synchroniczny
  * callServiceProxyAsync(serviceName, params) - pozwala zawołać usługi ServiceProxy oraz ScriptService w sposób asynchroniczny
  * initTooltip(id, element, data) - pozwala zainicjować tooltip o zadanym identyfikatorze (wartość wymagana, musi spełniać wszystkie założenia atrybutu ID w języku HTML) na przekazanym elemencie
  * showTooltip(id) - pokazuje tooltip o zadanym id
  * hideTooltip(id) - ukrywa tooltip o zadanym id
  * destroyTooltip(id) - niszczy tooltip o zadanym id
  * destroyAllTooltips() - niszczy wszystkie tooltipy danego komponentu
  * goForward() - nawiguje do następnej (dozwolonej) strony lub wysyła wniosek (gdy użytkownik znajduje się na ostatniej stronie wniosku)
  * goBackward() - nawiguje do poprzedniej (dozwolonej) strony
  * setInactiveForward() - ustawia przycisk nawigujący do następnej strony na zablokowany (Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.)
  * setActiveForward() - ustawia przycisk nawigujący do następnej strony na aktywny (Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.)
  * triggerCustomEvent(eventName) - pozwala wywołać CustomEvent zdefiniowany wcześniej dla danego komponentu
  * sendCurrentValueEvent() - wysyła event zawierający aktualną wartość CustomComponentu wraz z jego id
  * isPageValid() - zwraca informację czy na stronie są błędy walidacji

## Interfejsy komponentu

{% code expandable="true" %}

```tsx
interface ExCustomComponentScope {
    // Metody, które można dostarczyć
    onDestroy?: () => void;
    afterViewInit?: () => void;
    onModelChange?: () => void;
    onMessagesUpdate?: (messages: ExWidgetMessage[]) => void;
 
    // Pola dostarczane przez platformę
    domId: string;
    componentId: string;
    componentMid: string;
    translations: { [key: string]: string; };
    componentInput: { [key: string]: string[]; };
    componentData: { [key: string]: string; };
    serviceResponses: { [key: string]: { [key: string]: string }[] };
    visible: boolean;
 
    // Metody dostarczane przez platformę - nie należy ich nadpisywać
    callNative(nativeFunction: (api: NativeAppApi) => any): void
    getValue(): string;
    setValue(value: string): void;
    /**
     * @deprecated Nowe CustomComponenty powinny korzystać z querySelector
    */
    queryChild(query: string): JQuery;
    querySelector(query: string): Element;
    putData(key: string, value: string): void;
    saveData(key: string, value: string): void;
    getData(key: string): string;
    translate(key: string): string;
    schedule(func: () => any): void;
    clean(): void;
    callServiceProxy(serviceName: string, params: { [key: string]: string[] }): Observable<ExServiceProxyResponse>;
    callServiceProxyAsync(serviceName: string, params: { [key: string]: string[] }): Observable<ExServiceProxyResponse>;
    initTooltip(id: string, element: any, data: ExWidgetTooltip): void;
    destroyTooltip(id: string): void;
    showTooltip(id: string): void;
    hideTooltip(id: string): void;
    destroyAllTooltips(): void;
    goForward(): void;
    goBackward(): void;
    setActiveForward(): void;
    setInactiveForward(): void;
    triggerCustomEvent(event: string): void;
    sendCurrentValueEvent(): void;
    isPageValid(): Observable<boolean>;
}
 
interface ExServiceProxyResponse {
    name: string;
    componentId: string;
    response: { [key: string]: string }[];
}
 
interface ExWidgetTooltip {
    text: string;
    position: ExWidgetTooltipPosition;
    type: ExWidgetTooltipType;
    width?: number;
    height?: number;
    styleClasses?: string;
    onFocus?: boolean;
}
 
enum ExWidgetTooltipPosition {
    TOP,
    BOTTOM,
    LEFT,
    RIGHT,
    ADAPTIVE,
// Depreacted:
    LEFT_TOP,
    LEFT_BOTTOM,
    RIGHT_TOP,
    RIGHT_BOTTOM
}
 
enum ExWidgetTooltipType {
    HOVER,
    BUTTON
}
interface ExWidgetMessage {
    getMessage(): string;
    getType(): ExWidgetMessageType;
}
 
enum ExWidgetMessageType {
    VALIDATION_POPUP,
    VALIDATION,
    INFO,
    COMPONENT_INFO
}
```

{% endcode %}

## Przykład funkcji komponentu

{% code lineNumbers="true" %}

```javascript
function($scope) {
      $scope.closePopup = function() {
        $scope.queryChild('.kg-positive-decision-popup-wrapper').fadeOut(200);
        $scope.saveData('visible', 'false');
      };
      $scope.afterViewInit = function() {
        let visible = $scope.getData('visible');
        if(visible === 'false') {
          $scope.queryChild('.kg-positive-decision-popup-wrapper').hide();
        } else {
          $scope.closeButton = $scope.queryChild('.kg-positive-decision-popup-close-button');
          $scope.closeButton.on('click', $scope.closePopup);
          $scope.nextButton = $scope.queryChild('.kg-positive-decision-popup-next-button');
          $scope.nextButton.on('click', $scope.closePopup)
        }
      };
    }
```

{% endcode %}

W powyższym przykładzie zdefiniowany został komponent prezentujący na wniosku Popup z informacją o pozytywnej decyzji kredytowej:

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FvzqJCrmb3w7VWP7O3yxG%2Fimage.png?alt=media&#x26;token=95bd540f-34ef-4dd3-b799-8bff8805935b" alt=""><figcaption><p><em><strong>Ilustracja 2.</strong></em> <em>Popup zaprojektowany za pomocą CustomComponentu</em></p></figcaption></figure>

W linii 6 zdefiniowana została systemowa funkcja *afterViewInit* inicjalizująca przyciski *X* oraz *DALEJ,* a także sterująca widocznością okna. W linii 2 zdefiniowano funkcją wykonywaną w momencie kliknięcia jednego z dwóch przycisków.

Struktura dom popupu:

{% code lineNumbers="true" %}

```html
<div class='kg-positive-decision-popup-wrapper'>
  <div class='kg-positive-decision-popup'>
    <div class='kg-positive-decision-popup-title-wrapper'>
        <div class='kg-positive-decision-popup-title'>
            _{kg.positive.decision.popup.title}
        </div>
        <button class='kg-positive-decision-popup-close-button'></button>
        <div class='clear'></div>
    </div>
    <div class='kg-positive-decision-popup-content-wrapper'>
        <div class='kg-positive-decision-popup-content-first-paragraph'>
            _{kg.positive.decision.popup.content.first.paragraph}
        </div>
        <div class='kg-positive-decision-popup-content-second-paragraph'>
            _{kg.positive.decision.popup.content.second.paragraph}
        </div>
    </div>
    <div class='kg-positive-decision-popup-next-button-wrapper'>
        <button class='kg-positive-decision-popup-next-button'>_{kg.positive.decision.popup.next.button}</button>
        <div class='clear'></div>
    </div>
  </div>
</div>
```

{% endcode %}

W definicji szablonu komponentu można odwoływać się do zdefiniowanych tłumaczeń stosując konwencję **\_{KLUCZ\_TŁUMACZENIA}** - przykład w linii 5.

### **Wywołanie skryptów lub ServiceProxy**

Z poziomu CustomComponentu można zawołać usługi ServiceProxy oraz ScriptService korzystając z metod *callServiceProxy* oraz *callServiceProxyAsync.* Obie metody zwracają *Observable* z response o następującym formacie:

```
{
    name: string;
    componentId: string;
    response: { [key: string]: string }[];
}
```

Aby uzyskać *response* należy wywołać metodę *.subscribe()* znaną z RxJS. Podobnie jak ma to miejsce w RxJS warto także wywołać *unsubscribe()* w odpowiednim momencie na tak zwróconym obiekcie. Dla przykładu *unsubscribe* może zostać wywołany w metodzie *onDestroy.*

W przypadku użycia ServiceProxy lub ScriptService należy go dodać do listy używanych serwisów na CustomComponent:

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FZIf9KbXuiykzc4nhUn4b%2Fimage.png?alt=media&#x26;token=f63e8331-eb30-4ab3-877b-c04f7d64d444" alt=""><figcaption><p><em><strong>Ilustracja 3.</strong></em> <em>Sekcja "Wykorzystywane serwisy"</em></p></figcaption></figure>

## Pola wejściowe komponentu <a href="#komponentniestandardowycustomcomponent-polawejsciowekomponentu" id="komponentniestandardowycustomcomponent-polawejsciowekomponentu"></a>

W sekcji **Dane wejściowe** definiowane są id pól wejściowych komponentu. Id nie powinny zawierać spacji.

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2F3SUcLy28j2RcUa6HQxKY%2Fimage.png?alt=media&#x26;token=7b63a748-5e28-4c6f-9d42-acfc0d635972" alt=""><figcaption><p><em><strong>Ilustracja 4.</strong></em> <em>Sekcja "Dane wejściowe"</em></p></figcaption></figure>

Zdefiniowane pola wejściowe można zasilać innymi komponentami wniosku w identyczny sposób jak [komponenty złożone (ComplexComponent)](https://docs.eximee.com/budowanie-aplikacji/interfejs-uzytkownika/komponenty-rozszerzone/komponenty-zlozone#parametry-wejsciowe) - mapując odpowiednie dane w sekcji **PARAMETRY WEJŚCIOWE**:

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FB514ZDvzuhGQh1VTtJqs%2Fimage.png?alt=media&#x26;token=e4075382-5273-4833-9caf-c11741aed541" alt=""><figcaption><p><em><strong>Ilustracja 5.</strong> Przykład sekcji "Parametry wejściowe" dla CustomComponentu dodanego na wniosku</em></p></figcaption></figure>

## Tłumaczenia

Dedykowane internacjonalizowane teksty definiowane są w sekcji **Tłumaczenia komponentu**, która wyświetla się po wybraniu w lewym panelu przycisku **Tłumaczenia**.

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FpDGrOGTiU6Q9g7IPJcIH%2Fimage.png?alt=media&#x26;token=912499cf-6e84-4566-84a8-3f92f624ff0f" alt=""><figcaption><p><em><strong>Ilustracja 6a.</strong></em> <em>Sekcja "Tłumaczenia komponentu"</em></p></figcaption></figure>

W widoku tym definiowany jest klucz oraz wartość domyślna tekstu obsługiwanego na CustomComponencie. Tłumaczenia tekstu w wymaganych językach definiowane są w sposób standardowy na wniosku, na którym komponent został podpięty.

Przykład dodawania klucza tłumaczeń:

1. Po kliknięciu u dołu panelu przycisku **Dodaj tłumaczenie** należy dodać klucz tłumaczeń i wartość domyślną:

   <figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FgKXasP77SV29LdCBFPFH%2Fimage.png?alt=media&#x26;token=3bd276d8-5683-478a-be0a-9e83939ce156" alt=""><figcaption><p><em><strong>Ilustracja 6b.</strong></em> <em>Dodawanie nowego klucza i tłumaczenia</em></p></figcaption></figure>
2. Dodany klucz tłumaczeń możemy wykorzystać w strukturze DOM CustomComponentu:

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2F3ox2dYRyonlrJR2OeSZB%2Fobraz.png?alt=media&#x26;token=56b0d0e3-953d-4d89-89ec-7d716f859c73" alt=""><figcaption><p><em><strong>Ilustracja 6c.</strong></em> <em>Sekcja "DOM" z wprowadzonym przykładowym kluczem "kg-final-survey-popup-title"</em></p></figcaption></figure>

3. Po dodaniu CustomComponent'u na wniosek lub do komponentu złożonego w zakładce **Tłumaczenia** pojawią się klucze z CustomComponentu. Możemy je także dodać ręcznie.<br>

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2F9Lpm5N6Hr5UiloRXd2AY%2Fimage.png?alt=media&#x26;token=eaa5a363-6bdc-489e-bdd5-70ac77f0927e" alt=""><figcaption><p><em><strong>Ilustracja 6d.</strong></em> <em>Zakładka "Tłumaczenia" z kluczami CustomComponentu</em></p></figcaption></figure>

## Przejmowanie komunikatów

Aby CustomComponent sam obsługiwał komunikaty walidacyjne, należy w sekcji parametrów zaznaczyć opcję **Niestandardowe prezentowanie komunikatu błędu**. Opcja ta zezwala na obsługę wiadomości poprzez metodę **onMessagesUpdate**.

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2F7iRkKvav68CprpZiopn9%2Fimage.png?alt=media&#x26;token=777ab5a7-a2d2-4445-9441-81791d2a1806" alt=""><figcaption><p><em><strong>Ilustracja 7.</strong> Włączona opcja "Niestandardowe prezentowanie komunikatu błędu"</em></p></figcaption></figure>

## Definicja customowych eventów dla komponentu

Dla każdego CustomComponent można zdefiniować indywidualne akcje (**CustomEvents**). Podpinane i obsługiwane są w ten sam sposób co standardowe eventy definiowane w platformie. Definicja akcji wygląda następująco:

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FSJOF8PaiHmFh4nTMTz2A%2Fimage.png?alt=media&#x26;token=dc2d50fe-8938-4a12-a530-8009a31dc05e" alt=""><figcaption><p><em><strong>Ilustracja 8.</strong> Akcje dodane dla komponentu</em></p></figcaption></figure>

Tak zdefiniowane akcje możemy podpiąć na wniosku do danej akcji. Przykładowo akcja TEST\_EVENT\_A służy do otwarcia popupa:

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2F0B3LiDaEB136FSMRcF21%2Fimage.png?alt=media&#x26;token=ae248ec1-7adc-4b85-93d5-bf79b51dd585" alt=""><figcaption><p><em><strong>Ilustracja 9.</strong> Widok właściwości wniosku - sekcja "Akcje" ze zdefiniowaną akcją z CustomComponentu</em></p></figcaption></figure>

Sam event możemy wywołać wewnątrz skryptu JS customComponentu, korzystając z metody **triggerCustomEvent**, na przykład:

```javascript
$scope.triggerCustomEvent('TEST_EVENT_A');
```

## Symulacja komponentu <a href="#komponentniestandardowycustomcomponent-symulacjakomponentu" id="komponentniestandardowycustomcomponent-symulacjakomponentu"></a>

Do sprawdzenia działania utworzonego CustomComponentu można wykorzystać funkcję symulacji.\
W tym celu klikamy znajdujący się w prawej części ekranu przycisk **Podgląd**. Jego kliknięcie zmienia wygląd ekranu w symulacyjny. Po lewej stronie zobaczymy okienka **JavaScript**, **CSS** i **HTML**, a po prawej parametry komponentu (pod warunkiem, że zostały zdefiniowane parametry wejściowe). Po uruchomieniu podglądu możemy zasilić komponent zmiennymi pobieranymi w komponencie i zaobserwować jego działanie bez konieczności osadzania na wniosku i uruchamiania na środowisku deweloperskim.

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FC3bZLbEkS0gNE3fi8Pak%2Fimage.png?alt=media&#x26;token=10dc8c12-aaf9-4d3f-ae6b-11ecf2e342b6" alt=""><figcaption><p><em><strong>Ilustracja 10.</strong> Widok komponentu z włączonym podglądem, bez wypełnienia parametrów wejściowych</em></p></figcaption></figure>

Jeśli chcemy aby zmiany w podglądzie pokazywały się na bieżąco, przed uzupełnieniem wartości pól parametrów komponentu warto zaznaczyć opcję **Automatyczne odświeżanie**. Po uzupełnieniu wszystkich pól klikamy przycisk **Odśwież**. Wówczas chowają się pola z wpisanymi wartościami, a pokazuje się wygląd komponentu. Zawsze można wyświetlić uzupełniane parametry, klikając opcję z liczbą parametrów i napisem **(pokaż)**.

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FIrrMtVvgjuwuF8spdFCF%2Fimage.png?alt=media&#x26;token=21150ed5-4f51-4fd7-93f9-fc8896ba2557" alt=""><figcaption><p><em><strong>Ilustracja 11.</strong> Widok komponentu z symulacją</em></p></figcaption></figure>

Po ponownym kliknięciu przycisku **Podgląd** wrócimy do standardowego widoku komponentu z listą parametrów po lewej stronie.

## Osadzanie na wniosku

Stworzony CustomComponent osadzany jest na wniosku/w komponencie złożonym poprzez dodanie go z palety komponentów. W tym celu w lewym bocznym panelu klikamy na przycisk **Dodaj komponent** i w wysuniętym panelu komponentów wybieramy zakładkę **Niestandardowe**, która dostępna jest po kliknięciu symbolu ![](https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FXpvGXQmoGnzv8PqfqsFN%2Fimage.png?alt=media\&token=bf402bc1-cab4-4256-8d54-9fc1f5100fca). Zostanie wyświetlona lista dostępnych w repozytorium CustomComponentów.\
W górnej części panelu dostępne jest pole wyszukiwania umożliwiające szybsze znalezienie szukanego do osadzenia artefaktu. Dodanie komponentu polega na przeciągnięciu go z palety i upuszczeniu w odpowiednim miejscu na wniosku.

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FvuGLqLYDVuNRo7RfmzsM%2Fimage.png?alt=media&#x26;token=54006942-3d8d-43a3-97ab-68f72851c9a6" alt=""><figcaption><p><em><strong>Ilustracja 12.</strong></em> <em>Lista komponentów po kliknięciu zakładki Niestandardowe</em></p></figcaption></figure>

\
Po osadzeniu komponentu na wniosku należy zasilić pola wejściowe komponentu (zdefiniowane zgodnie z sekcją **Pola wejściowe** **komponentu**) klikając w sekcji **Podstawowe** **właściwości** opcję **PARAMETRY WEJŚCIOWE**:

<figure><img src="https://1082717226-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CssJT0zIo4SJQLbSZ6l%2Fuploads%2FZXwJb1BKhLhBpG1LNnMK%2Fimage.png?alt=media&#x26;token=ea6861e9-ea7c-4059-8d58-1c378e28eccc" alt=""><figcaption><p><em><strong>Ilustracja 13.</strong></em> <em>Okno definiowania parametrów wejściowych CustomComponentu</em></p></figcaption></figure>

## Sterowanie aktywnością przycisku nawigującego do następnej strony

W zakladce JavaScript edytowanego CustomComponentu możemy skorzystać z metod:

* **setInactiveForward()** - ustawia przycisk nawigujący do następnej strony na zablokowany
* **setActiveForward**() - ustawia przycisk nawigujący do następnej strony na aktywny

Należy pamiętać, że wywołanie metody **setInactiveForward** wewnątrz **afterViewInit** spowoduje zablokowanie przycisku po każdej zmianie widoczności komponentu - należy zatem uwzględnić to w implementacji.

Sterowanie aktywnością przycisku można uzależnić od kanału w jakim wyświetlany jest wniosek za pomocą instrukcji warunkowej ***if*** , uwzględniającej zmienne sesyjne **channel** i **channelDescritpion** (należy pamiętać o ich wcześniejszym zmapowaniu do komponentu).

{% hint style="warning" %}
Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.
{% endhint %}

## Wołanie native API

Obiekt $scope udostępnia funkcję **callNative**, która przyjmuje funkcję w której parametrem jest obiekt native API (sygnatura: callNative(nativeFunction: (api: NativeAppApi) => any): void). Obiekt api ma zdefiniowany interfejs dostarczany przez platformę eximee. Funkcja żądana na obiekcie native zostanie wywołana tylko jeśli w kontekście ten obiekt jest dostępny.

```
function($scope) {
    $scope.afterViewInit = function() {
        $scope.callNative(nativeApi => nativeApi.setTitle('tytuł'));
    }
}
```

{% hint style="info" %}
Dostępność funkcjonalności zależy od licencji i może nie być dostępna we wszystkich wdrożeniach.
{% endhint %}

## Sterowanie loaderem platformowym <a href="#komponentniestandardowycustomcomponent-sterowanieloaderemplatformowym" id="komponentniestandardowycustomcomponent-sterowanieloaderemplatformowym"></a>

Na obiekcie window dostępne są metody umożliwiające sterowanie loaderem platformowym:

* startSpinner() - włącza loader
* stopSpinner() - wyłącza loader


---

# 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/komponenty-rozszerzone/komponent-niestandardowy-customcomponent.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.
