Custom component - CustomComponent

Custom component (CustomComponent) allows creating your own application components using the JavaScript.

A CustomComponent consists of eight elements:

  • JavaScript script,

  • CSS styles of the component,

  • HTML template of the component,

  • Mappings of the component's input parameters,

  • List of used services,

  • List of actions available for this component,

  • Translations of texts for the component,

  • Preview.

Creating a component

A new component is created in the same way as other components. After going to the Library module and selecting the Custom components tab we click the Add custom component button and in the opened window we set the name and location of the created artifact (More information about the editor itself: Custom Components Editor)

Illustration 1. Edit view of the newly created component

JavaScript script

Each of the CustomComponents consists of one main function, which is passed the Scope of the component:

function($scope) {
  
}

Using the scope the author can, among other things, fetch component data, input data and react to certain lifecycle events of the component. The user can implement three system methods of the component:

  • afterViewInit - executed when the component is added to the application DOM structure,

  • onModelChange - executed when the model (e.g. value) of the component or input data value changes,

  • onDestroy - executed when the component is removed from the application DOM structure.

Additionally the component scope provides several useful elements:

  • fields:

    • domId - ID of the component in the application DOM structure

    • componentId - ID of the component

    • componentMid - MID of the component

    • visible - variable controlling the visibility of the component

    • translations - map of translations defined during component creation

    • componentId - map of component input parameters

    • componentData - map of the component's internal data (allows preserving the component state)

    • componentInput - map of the component's input data (keys are defined in the Inputs section, separated by commas)

  • methods:

    • getValue() - gets the current value of the component

    • setValue(value) - sets the current value of the component

    • querySelector(query) - returns the DOM element of the component that matches the selector.

    • putData(key, value) - sets a specified value (value) under the key (key) in the component data map - client-side only in the browser

    • saveData(key, value) - sets a specified value (value) under the key (key) in the component data map - also on the server side

    • getData(key) - retrieves the value specified under the key (key) in the component data map

    • translate(key) - returns the translation from the translations map

    • clean() - clears the scope object when it is no longer used by the CustomComponent

    • callServiceProxy(serviceName, params) - allows calling ServiceProxy and ScriptService synchronously

    • callServiceProxyAsync(serviceName, params) - allows calling ServiceProxy and ScriptService asynchronously

    • initTooltip(id, element, data) - allows initializing a tooltip with the given identifier (value required, must satisfy all ID attribute assumptions in HTML) on the provided element

    • showTooltip(id) - shows the tooltip with the given id

    • hideTooltip(id) - hides the tooltip with the given id

    • destroyTooltip(id) - destroys the tooltip with the given id

    • destroyAllTooltips() - destroys all tooltips of the given component

    • goForward() - navigates to the next (allowed) page or submits the application (when the user is on the last page of the application)

    • goBackward() - navigates to the previous (allowed) page

    • setInactiveForward() - sets the button navigating to the next page to locked (Feature availability depends on the license and may not be available in all deployments.)

    • setActiveForward() - sets the button navigating to the next page to active (Feature availability depends on the license and may not be available in all deployments.)

    • triggerCustomEvent(eventName) - allows triggering a CustomEvent previously defined for the given component

    • sendCurrentValueEvent() - sends an event containing the current value of the CustomComponent along with its id

    • isPageValid() - returns information whether there are validation errors on the page

Component interfaces

interface ExCustomComponentScope {
    // Methods that can be provided
    onDestroy?: () => void;
    afterViewInit?: () => void;
    onModelChange?: () => void;
    onMessagesUpdate?: (messages: ExWidgetMessage[]) => void;
 
    // Fields provided by the 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;
 
    // Methods provided by the platform - should not be overridden
    callNative(nativeFunction: (api: NativeAppApi) => any): void
    getValue(): string;
    setValue(value: string): void;
    /**
     * @deprecated New CustomComponents should use 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
}

Example of a component function

function($scope) {
      $scope.closePopup = function() {
        $scope.queryChild('.kg-positive-decision-popup-wrapper').fadeOut(200);
        $scope.saveData('visible', 'false');
      };
      $scope.afterViewInit = function() {
        var 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)
        }
      };
    }

In the above example a component presenting a popup on the application with information about a positive credit decision is defined:

Illustration 2. Popup designed using CustomComponent

In line 6 the system function afterViewInit initializing the buttons X and NEXT, and also controlling the visibility of the window. In line 2 a function executed when one of the two buttons is clicked was defined.

DOM structure of the popup:

<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>

In the component template definition you can refer to defined translations using the convention _{TRANSLATION_KEY} - example in line 5.

Calling scripts or ServiceProxy

From within a CustomComponent you can call ServiceProxy and ScriptService using the methods callServiceProxy and callServiceProxyAsync. Both methods return an Observable with a response in the following format:

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

To obtain the response you should call the method .subscribe() known from RxJS. As with RxJS it is also worth calling unsubscribe() at the appropriate time on the returned object. For example unsubscribe can be called in the onDestroy

method.

Illustration 3. When using ServiceProxy or ScriptService you must add it to the list of used services on the CustomComponent:

Section "Used services"

In the section Component input fields Input data

Illustration 4. are defined by the ids of the component input fields. Ids should not contain spaces.

Section "Input data" INPUT PARAMETERS:

Illustration 5. The defined input fields can be fed by other application components in the same way as complex components (ComplexComponent) - by mapping the appropriate data in the

Translations

Example of the "Input parameters" section for a CustomComponent added to the application Dedicated internationalized texts are defined in theComponent translations Translations.

, which is displayed after selecting the button in the left panel Illustration 6a.

Section "Component translations"

In this view the key and default value of the text handled on the CustomComponent are defined. Translations of the text in required languages are defined in the standard way on the application where the component was attached.

  1. Example of adding a translation key: Add translation After clicking the button at the bottom of the panel

    you should add the translation key and the default value: Illustration 6b.
  2. Adding a new key and translation

    The added translation key can be used in the DOM structure of the CustomComponent: Illustration 6c.

  3. Section "DOM" with the example key "kg-final-survey-popup-title" entered Translations After adding the CustomComponent to the application or to a complex component in the

    tab the keys from the CustomComponent will appear. We can also add them manually. Illustration 6d.

Tab "Translations" with keys of the CustomComponent

Handling messages For the CustomComponent to handle validation messages itself, in the parameters section select the optionCustom error message presentation . This option allows handling messages through the method.

Illustration 7. onMessagesUpdate

Enabled option "Custom error message presentation"

Definition of custom events for the componentFor each CustomComponent you can define individual actions (CustomEvents

Illustration 8. ). They are attached and handled in the same way as standard events defined on the platform. The action definition looks as follows:

Actions added for the component

Illustration 9. Such defined actions can be attached to an action on the application. For example the action TEST_EVENT_A serves to open a popup:

Application properties view - "Actions" section with an action defined from the CustomComponent We can trigger the event inside the customComponent JS script using the methodtriggerCustomEvent

, for example:

$scope.triggerCustomEvent('TEST_EVENT_A');

Component simulation PreviewTo check the operation of the created CustomComponent you can use the simulation function. To do this click the button located on the right side of the screen JavaScript, . Clicking it changes the screen to simulation mode. On the left side we will see the panes and CSSHTML

Figure 10. , and on the right the component parameters (provided input parameters have been defined). After launching the preview we can feed the component with variables retrieved in the component and observe its behavior without the need to embed it in the application and run it in the development environment.

Component view with preview turned on, without filling input parameters If you want preview changes to show up live, before filling the component parameter fields it is worth selecting the optionAutomatic refresh . After filling all fields click theRefresh button. Then the fields with entered values hide and the component appearance is shown. You can always display the filled parameters by clicking the option with the number of parameters and the label.

Figure 11. (show)

Component view with simulation Preview Clicking the button again

will return us to the standard component view with the list of parameters on the left side.

Embedding in the application The created CustomComponent is embedded in the application/in a complex component by adding it from the components palette. To do this in the left side panel click the Add component button and in the slid-out components panel select theCustom tab, which is available after clicking the

Figure 12. symbol. A list of CustomComponents available in the repository will be displayed. At the top of the panel there is a search field enabling faster finding of the artifact to embed. Adding the component involves dragging it from the palette and dropping it in the appropriate place on the application.

List of components after clicking the Custom tab After embedding the component in the application you should populate the component's input fields (defined according to the Input fields) section of the component by clicking in the window the INPUT PARAMETERS:

Figure 13. Basic

properties

Window defining input parameters of the CustomComponent

  • Controlling the activity of the button navigating to the next page In the JavaScript tab of the edited CustomComponent we can use the methods:

  • setInactiveForward()- sets the button navigating to the next page to locked

setActiveForward () - sets the button navigating to the next page to active Keep in mind that calling the method afterViewInit setInactiveForward

inside will lock the button after every visibility change of the component - so you should take this into account in the implementation. You can make the button activity depend on the channel in which the application is displayed using a conditional statement channel and if that considers session variables

channelDescritpion

(remember to map them to the component beforehand). Calling native APIThe $scope object provides the function

function($scope) {
    $scope.afterViewInit = function() {
        callNative
    }
}

The availability of features depends on the license and may not be available in all deployments.

, which accepts a function whose parameter is the native API object (signature: callNative(nativeFunction: (api: NativeAppApi) => any): void). The api object has an interface defined and provided by the eximee platform. The function requested on the native object will be invoked only if that object is available in the given context.

$scope.callNative(nativeApi => nativeApi.setTitle('title'));

  • Controlling the platform loader

  • On the window object there are methods available that allow controlling the platform loader:

Last updated

Was this helpful?