OpenWGA 7.10 - OpenWGA Concepts and Features

Design and development » WebTML » Features » Portlets

Events

Portlet events are a way to let portlets communicate to each other.

The concept of portlet events is built especially with OpenWGA applications in mind that consist of many AJAX-enabled portlets, an architecture where traditional notification techniques are no longer suitable. If one portlet modifies some data then in many situations other portlets on the same page also need to be refreshed or perform special operations to react on the modification. Portlet events are the intended way to propagate information about these modifications and let dependent portlets react on them.

Firing events

Portlet events are created and fired using TMLScript, mostly in a WebTML action. First a portlet event object needs to be created using method this.createEvent(). A portlet event has a name, which should identify the cause that triggered it, plus an optional and custom set of event parameters, settable on the event object. These parameters are optional key/value pairs that may be used to give event receivers more information about the cause of the event:

var ev = createEvent("userInfoChanged");

ev.addParameter("changedData", "userName");

Finally the event should be fired via method portlet.fireEvent(). The TMLPortlet object that is used to fire the event is the event originator:

portlet.fireEvent(ev);

Subscribing to Events

In order to react on thrown event on a WebTML page a portlet must "subscribe" to a event. It does this by using the tag <tml:eventscript> in its WebTML code. The attribute onevent of this tag lists the names of events on which the current portlet wants to react. It can then either call an action when the event is fired when it specifies one using attribute action:

<tml:eventscript onevent="userInfoChanged, uiModeChanged" action="reloadData"/>

Or the body of the tag may contain a script that is to be executed on the portlet rendering that follows the event, just like a regular <tml:script>:

<tml:eventscript onevent="userInfoChanged, uiModeChanged">

msg = "Portlet reloaded because of modified data: " + portletEvent.getParameter("changedData");

</tml:eventscript>

In both cases the event itself is available as object "portletEvent" to the action or script code. On it you can retrieve the data of this event, like the event name, the name of the source portlet and parameters that were added to the event.

Portlet events in action

OpenWGA automatically handles the transport of portlet events across a WebTML page. A portlet event may be fired in a WebTML action - AJAX-enabled actions included - or in a script block on the WebTML page itself. After the event has been fired and either the page or portlet rendering is complete then the following happens:

  • OpenWGA looks thru the fired events of the reloaded page/portlet and finds other portlets that subscribed to these events
  • The receiver portlets are reloaded. If all of them are AJAX portlets then only the portlets are reloaded via AJAX, otherwise the complete page is
  • This is done for each reloaded portlet:
    • If an attribute action is defined on the <tml:eventscript> tag then this action is executed. The event object is provided to the TMLScript code as object "portletEvent".
    • If the <tml:eventscript> tag that triggered the reload had an attribute portletmode then the portlet is automatically switched to the given portlet mode. The same is done with an optional portletcontext attribute.
    • After that the portlet is re-rendered. If the <tml:eventscript> tag that triggered the reload contains TMLScript code then the code is executed on the reload as if it was a simple <tml:script> tag. The event object is provided to the TMLScript code as object "portletEvent"


Portlet events in the browser

Portlet events are actually distributed to their subscribing portlets on the browser via clientside JavaScript code. The server sends data about a fired event to the browser. There the clientside JavaScript looks for loaded portlets that subscribe to this event, then reloads those portlets.

Because of this it is possible to listen and react to portlet events on the clientside in your custom JavaScript code. For this you need to use the OpenWGA JavaScript API that is available to every WebTML page (that has a <tml:htmlhead> tag). Use JavaScript methods WGA.event.addListener() and WGA.event.removeListeners() to register listener functions that get called when a portlet event of a certain name is thrown.

WGA.event.addListener(

    "<tml:script expression="portlet.portletkey"/>",

    "open-document", 

    function(e){

        window.open(...);

    }

);

The code above will open a new browser window for every portlet event of name "open-document".  Note that this method needs to be supplied with a "portlet key", an internal key of WebTML portlets which is retrievable in TMLScript via portlet.portletkey. This is necessary for most clientside JavaScript functions that deal with portlets.

The event object available to your listener function (given to it as first function argument) contains the data of the event, like the name, the portlet key of the portlet that threw the event and JavaScript representations of the event parameters that were added to the event when firing it, provided they were of type String, Number, Date or Boolean. See the documentation of WGA.event.addListener() for details.

By using the OpenWGA JavaScript API It is also possible to fire events from the clientside. Use method WGA.event.fireEvent() to fire an event in clientside JavaScript. This method allows to specify a name, the portlet key of a throwing portlet, and also event parameters just like the serverside method:

WGA.event.fireEvent(

    "search-input", 

    "<tml:script expression="portlet.portletkey"/>", 

    {value: value}

);

The code above fires an event of name "search-input" and provides an event parameter "value" with it. If your listeners are clientside JavaScript listeners, like those described just above.  then the whole deal of firing and catching portlet events is done entirely in the browser client. The OpenWGA server is not involved, unlike of course your clientside listeners actually invoke server functions, which is absolutely possible

But the listeners of your clientside event may also be serverside <tml:eventscript> listeners that listen for the event name you are throwing on the client. This will cause the fired event to trigger a reload of the portlets having these event scripts and will execute the serverside functionality determined by that WebTML tag. Note however that clientside event parameters are not transported to the server because of security reasons. Serverside event parameters are regarded to be safe from client modification and therefor must and will not be influenced by code that runs in the browser.