Ray44
Tera Explorer

In this article I will be discussing how to comunicate across widgets. I'll be using as an example 4 different widgets. (This is the demo in the attachment)

find_real_file.png

Depending on the project plan, this might be either useful or the other way a round. What am I going to talk about are 3 way to transmit data from one widget to another.

Broadcast

In this section we will be demonstrating how to set up a broadcast type comunication.

This type of comunication is one way only and need a trigger for the execution, either executed along with the loading of the page or with event.

In this case I’ll be using a button that will trigger the event:

find_real_file.png

In the HTML code I created a button and an input for the demo, in which case all text written in the input will be sent to the other widget to display.

<div class="panel panel-primary">
  <div class="panel-heading">Write your input here to send it to the other widget</div>
  <div class="panel-body">
    <input class="form-control" type="search" placeholder="Start typing here"
      ng-model="c.data.keywords" ng-change="c.server.update()" ng-model-options="{debounce: 250}" />
  </div>
  <div>
    <button class="form-control" ng-click="send(c.data.keywords)">Send</button>
  </div>
</div>
<div>
  <sp-widget widget="c.data.embeddedWidget"></sp-widget>
</div>


In the Client controller I added the button logic and also the broadcast call to the other widget.

api.controller = function ($rootScope, $scope, spUtil) {
    var c = this;

    $scope.send = function (value) {
        c.server.get({});
        $rootScope.$broadcast('scanner', value);
    };

    spUtil.get("embedded_widget").then(function (response) {
        c.embeddedWidget = response;
    });
};

The broadcast call requires 2 inputs, the first one a string type and its the name of the receiver on the other side, the latter is the data you want to send. There is no limitation on type of data you can send, but in this case I use a string as a demonstration.


In server side I added the code to read the input and pass it to the broadcast for demo and other pieces of code relate to the other type of comunication.

(function () {
    /* populate the 'data' object */
    /* e.g., data.table = $sp.getValue('table'); */

    if (input.keywords != null && input.keywords != '') {

        //comunicate using broadcast
        data.keywords = input.keywords;

        //comunicate using sessione
        gs.getSession().putClientData('dataSession', input.keywords);

        //comunicate using embedded widget
        var obj = { 'data': input.keywords };
        data.embeddedWidget = $sp.getWidget('embedded_widget', obj);
    }
})();

Note: The demo uses this same widget as a starting point for all communication.

 

On the other side on a differente widget, the HTML code is simple with a block to diplay what we receive from the previous widget.

<div class="panel panel-primary">
  <div class="panel-heading">This widget receive using broadcast communication</div>
  <div class="panel-body">
    <input ng-model="obj.value">
  </div>
</div>

While the server side is empty, in the Client controller has the other important part of the broadcast, the receiver.

api.controller = function ($rootScope, $scope) {
    /* widget controller */
    var c = this;

    var obj = {};
    obj.value = "Default value";
    $scope.obj = obj;

    $rootScope.$on('scanner', function (event, args) {
        obj.value = args;
    });
};

The code snippet in evidence define the receiver, which are identified by a name (in this case ‘scanner’). Following the name the function that defines what the receiver will do in case it receive something.

find_real_file.png

Note: a caracteristic of this method is that one broadcast can call multiple receivers (its called broadcast for a reason) and a widget can contain multiple broadcast call and multiple receivers.

$rootScope.$on('scanner', function (event, args) {
    obj.value = args;
});

If the receivers all have the same name identification the broad cast will call all of them and send the data to all.

Note: In some cases is useful to have all widget have the data shared and this methid is advide for those cases, but if needed you can differenciate receivers by either use the data sent as a confrontation parameter, or by changing the name of the receiver not involved or with specifiec needs and then creare another broadcast circuite with differente mansions.

Is advised to not use this method in a 1 on 1 comunication design since its unneeded and if not check on receivers side it could create undesirable situation.

 

Embedded widget

In this section we will be demonstrating how to set up inter-comunication with embedded widget.

As the name implies this type of communication embed a widget inside the widget and as previously its one way only transmission.

We’ll be using the same main widget for the demo

find_real_file.png

In the HTML source code you will notice at the end of the code.

<div>
  <sp-widget widget="c.data.embeddedWidget"></sp-widget>
</div>

This is where the widget will be embedded. (Here how it looks like from demo)

find_real_file.png

The client script doesn't do anything in this matter while in server side we have to call the widget using getWidget, which has 2 arguments: the former is the ID of the widget and the latter is the data you want to transmit. (Snippet of the source code)

//comunicate using embedded widget
var obj = { 'data': input.keywords };
data.embeddedWidget = $sp.getWidget('embedded_widget', obj);

 

Moving on to the embedded widget,the HTML code doesn’t have changes worth mentioning except the heading.

<div class="panel panel-primary">
  <div class="panel-heading">This widget receive using embedding</div>
  <div class="panel-body">
    <input ng-model="c.data.value">
  </div>
</div>

The client side is empty and everything is on server side. Retrieve data, in this case, is simple as writing options which is where the data received is.

(function () {
    /* populate the 'data' object */
    /* e.g., data.table = $sp.getValue('table'); */

    var keywords = options.data || '';
    if (keywords != '') {
        data.value = keywords;
    }
})();

Note: I suggest use object as data to transmit, since dot walking will help you trace the information you need.

Note:  The embedding will inject HTML code of the called widget inside the caller widget HTML code, depending on the application you might place the sp-widget in a different place.

 

Data Session

In this section we will be demonstrating how to set up comunication using data Session.

This type uses the client session as a container for transporting info, is useful for data carried all the time the user is logged in.

We’ll be using the same main widget for the demo

find_real_file.png

So nothing will change in both server and client side, but the important part is in server side.
The line of code in evidence shows how to put data in the client session, the first argument of the method is the identification of the data, the latter is the data you want to communicate.

//comunicate using sessione
gs.getSession().putClientData('dataSession', input.keywords);

 

The receiving end won’t change much in the HTML code, except for the heading.

<div class="panel panel-primary">
  <div class="panel-heading">This widget receive using client data</div>
  <div class="panel-body">
    <input ng-model="obj.value">
  </div>
</div>

 

In server side we only have to retrieve the data from session using the following code, the retrieval has one argument which is the identification set previously while putting data.

(function () {
    /* populate the 'data' object */
    /* e.g., data.table = $sp.getValue('table'); */

    var keywords = gs.getSession().getClientData('dataSession') || '';
    if (keywords != '') {
        data.value = keywords;
    }
})();


In client side is all settings and such to display the data,

api.controller = function ($scope) {
    /* widget controller */
    var c = this;

    var obj = {};
    obj.value = "Default value";
    $scope.obj = obj

    $scope.$on('scanner', function (event, args) {
        c.server.get({}).then(function (response) {
            obj.value = response.data.value;
        });
    });
};

 

Note1: the line of code

c.server.get({})

it’s a execution call for server script, since in this demo on load the session have yet to be retrieved, the second server call its a given.

 

Note2: You might notice that I used a broadcast to call the widget, its not necessary in most cases and here its used to call the widget to make it responsive for the sake of the demo.

 

Note3:  I suggest to use server side for data retrieval. Although its possible to retrieve data in client side, it will load client session on client side only one time, which means if you plan on using getSession multiple times with different data it won’t work properly.

 

 

Hi I'm Ray, junior developer for Digix srl. This is my first article ever, so l really appreciate if you could leave comments for corrections or explanation about the article, also I would gladly take any suggestion for future articles. Thanks you so much for reading.

Comments
Roman Haas
Giga Guru

Very nice and clear article, thank you!

Prasant Kumar 1
Kilo Sage

Hi,

Please explain the inter widget communication on different pages of service portal also.

 

Thanks & Regards

Prasant Kumar Sahu

Ray44
Tera Explorer

Hi,

In case of widgets on different pages, both embedded and data session methods are the same.

  • The embedded calls the widget and pass data regardless whether its within the page definition or not.
  • The Data session its data attached to the current user session, if you not logout and login within each widget call then they work exactly the same way.

 

The story its a little bit trickier with the broadcast, which doesn't work if the widgets in question are not both visible in the UI.

Because broadcast uses $rootScope, it can send data across only if both receiving and sending widgets are loaded in the UI.

find_real_file.png

If we immage (example above) that the broadcast widget was from a different page, then in this case it would work just fine, but in case of widgets being in another window (example down) it won't work since the rootScope of the receiver is different.

find_real_file.png

Depending on the case you might want to use either embedded or data session for cases where you have to redirect to a different page.

Version history
Last update:
‎10-02-2020 08:44 AM
Updated by: