OpenWGA 7.10 - OpenWGA Concepts and Features

Design and development » WebTML » Features » Portlets

Portlets and AJAX

A major feature of WebTML portlets is their ability to be reloadable using AJAX technology out of the box.

AJAX means "Asynchronous Javascript and XML" and describes a technique to reload and display data without reloading the complete pageInstead only a special section of the page is rebuilt, which improves the user experience and performance, therefor making the web page more behave like a native application.

WebTML portlets normally use AJAX when an action link  is called that was generated in their code, unless it is explicitly deactivated by setting ajax="false", either on the portlet include or the tag that generates the action link. An exception is the root portlet, which ins not AJAX enabled.

A simple portlet include example:

<tml:include type="portlet" name="userinfo" ref="portlets:userinfo"/>

All WebTML tags that are able to generate action links have an attribute ajax themselves, which defaults to "true", but will only use AJAX if the portlet itself has not deactivated AJAX loading. For example, your portlet code may contain:

<tml:button clickaction="$store">Save</tml:button>

This is what now happens when the button is clicked:

  • The browser page sends a request to the server via JavaScript to perform an WebTML action and re-render the portlet. Optionall WebTML form data - if available - is transmitted earlier in a separate request.
  • The portlet part of the page is greyed out to show that there is an update going on.
  • The server processes the WebTML action. It eventually also modifies portlet mode and context if attributes portletcontext or portletmode were used on the action link tag.
  • Then the server renders only the WebTML portlet code again and sends it back to the JavaScript function which initiated the request.
  • The JavaScript function modifies the document of the current page and replaces the previous portlet code with the re-rendered code. The rest of the page remains untouched.

If you do not need any visual feedback in your portlet you can also set the ajax attribute of your action link tag to "norefresh". This does not even reload the portlet code. Portlet events however are still transmitted to the browser and will reload portlets that subscribed to them.

While it is trivial to enable the AJAX feature for a WebTML portlet there are some rules to be followed when writing the code of an AJAX-enabled portlet to let it behave the way it is intended:

  • Ensure that you have the tag <tml:htmlhead> in the HTML HEAD section of your page. This is needed for the AJAX feature to work.
  • Do not depend on WebTML variables that are passed to the portlet from the rest of the page. When a portlet gets re-rendered then these variables won't be available because the rest of the page was not rendered again. Use WebTML options instead to parametrize your portlets, as the options that were passed to the portlet on its first rendering are recovered and still available when the portlet is re-rendered via AJAX.
  • Use portlet events to communicate with other portlets. Often it is not only the current portlet which needs to be reloaded but also other portlets who are dependent on the state/data that was just altered by the action. To prevent reloading the complete page on that occasion you can make dependent portlets reload when you issue portlet events on your action. These dependent portlets will get reloaded via AJAX too if they are prepared to do so.
  • Use inline options for WebTML options with large content or reduce their scope. As options are recovered on AJAX reloading they need to be sent again for each AJAX request. If you have WebTML options with large content (for example the implicit "body" option of <tml:include>) then you might want to define them as Inline options.  These have a very small footprint on AJAX requests as the value does not need to be transferred. Note however that their value is evaluated in the context of the tag that reads the option which might not be what you want. You could also reduce the scope of large options to "local" to at least prevent them from being sent when child portlets of your portlet that do not use this option get AJAX-reloaded. Otherwise the performance of AJAX requests may decrease because of the additionally - and unintentionally - sent data.