Oracle WebCenter Interaction Web Service Development Guide

     Previous Next  Open TOC in new window   View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

About Adaptive Pagelet/Portlet Design Patterns

Adaptive pagelet/portlet design patterns provide solutions for broad classes of problems, and provide the base for a range of cross-platform services.

The Master-Detail design pattern uses two pagelets/portlets; users select an item from a list in one, and the details for that item are retrieved from the remote server and displayed in another. For example, a set of customers could be listed by name in the "master" pagelet/portlet. When the user clicks a name in this pagelet/portlet, the "detail" pagelet/portlet presents details about the item. The detail pagelet/portlet for a customer list could list all the important information about that customer, such as name, address, and phone number. This pattern assumes a tight coupling between the two pagelets/portlets; both the master pagelet/portlet and detail pagelet/portlet must be displayed on the same page. For a looser coupling, use the Broadcast-Listener pattern. For details and sample code, see Using Session Preferences.

The Broadcast-Listener design pattern is similar to the Master-Detail pattern, but assumes a loose coupling between pagelets/portlets. Users can select an item or perform some other action in a "broadcast" pagelet/portlet, which causes the content in other related "listener" pagelets/portlets to be redrawn. The major difference is that the Broadcast-Listener pattern relies on the Oracle WebCenter Interaction Scripting Framework to raise an event when an action is performed in the "broadcast" pagelet/portlet. One or more "listener" pagelets/portlets can respond to this event and update their content accordingly. For details and sample code, see Using Oracle WebCenter Interaction Scripting Framework Event Notification.

In Place Refresh allows you to refresh the content in a pagelet/portlet without refreshing the page. For details and sample code, see Using In-Place Refresh.

The Structured Response design pattern handles structured HTTP responses, typically encoded as XML. In many cases it can be expensive and inefficient to send large amounts of HTML back in response to some HTTP request, if only a small part of the user interface needs to be changed. This is especially true with more complex user interfaces. In these cases, the response can be encoded in XML. The client-side response handler can then parse the XML, and update the user interface (or perform some other action) based on that response. Use the Structured Response design pattern to redraw a small area of the user interface after making an HTTP request, or to access a simple HTTP/URI type web service from a pagelet/portlet. The example code below (structuredresponse_portlet.html) accesses an RSS feed from a selection of news sites.
<!-- jsxml includes -->
<a id="imgServerHref" href="pt://images/plumtree" style="display:none"></a>
<script type="text/javascript"
src="pt://images/plumtree/common/private/js/PTLoader.js"></script>
<script type="text/javascript">
var oImgServer = new Object();
oImgServer.location = document.getElementById('imgServerHref').href;
var imageServerURL = document.getElementById('imgServerHref').href;
var imageServerConnectionURL = oImgServer.location;
new PTLoader(imageServerURL, imageServerConnectionURL).include('jsxml','en');
</script>

<!-- jscontrols includes -->
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTMenu.css"/>
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTRichTextEditor.css"/>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/strings/PTControls-en.js"></script>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/PTControls.js"></script>

<!-- Inline JS helper functions -->
<!-- NOTE: It is standard practice to use namespace tokens (e.g., <pt:nameSpace pt:token="$$TOKEN$$" xmlns:pt="http://www.plumtree.com/xmlschemas/ptui/"/>) to ensure unique global JavaScript function and object names. For simplicity, we do not do that here.
-->

<script defer type="text/javascript" id="structured-response-portlet-A-script">
// Function that gets the RSS XML feed found at the specified url
getRSSFeed = function(url)
  {
  // First clear out any existing rows in the table
  channelTable.clearRows();

  // Force the transformer to fix up the url
  var oURL = new Object();
  oURL.location = url;

  // Do the http get
  var get = new PTHTTPGETRequest(oURL.location, handleRSSResponse);
  get.invoke();
  }

// Function that handles the RSS XML response and updates the table based on the RSS items
handleRSSResponse = function(response)
  {
  // Get the rss xml
  var xml = response.responseText;
  if (!xml || xml.indexOf('<?xml') == -1) { return; }

  // Parse into a dom, and get the channel node
  var xmlDOM = new PTXMLParser(xml);
  var rssNode = xmlDOM.selectSingleNode('rss');
  var channelNode = rssNode.selectSingleNode('channel');

  // Get the channel title and set the status bar text in the table
  var channelTitle = channelNode.selectSingleNode('title').getNodeValue();
  channelTable.statusBarText = '<b>Loaded Channel</b>: ' + channelTitle;

  // Get channel item nodes
  var itemNodes = channelNode.selectNodes('item');
  
  // Build table rows
  channelTable.rows = new Array();
  for (var i=0; i<itemNodes.length; i++)

    {
    var itemNode = itemNodes[i];

    // Get channel item properties
    var itemTitle = itemNode.selectSingleNode('title').getNodeValue();
    var itemLink = itemNode.selectSingleNode('link').getNodeValue();
    var itemDescription = itemNode.selectSingleNode('description').getNodeValue();
    if (itemNode.selectSingleNode('author'))
      var itemAuthor = itemNode.selectSingleNode('author').getNodeValue();
    if (itemNode.selectSingleNode('category'))
      var itemCategory = itemNode.selectSingleNode('category').getNodeValue();
    if (itemNode.selectSingleNode('pubDate'))
      var itemPubDate = itemNode.selectSingleNode('pubDate').getNodeValue();

    // Create a row and add it to the table
    var row = new PTRow();
    row.parent = channelTable;
    row.id = i;
    row.uid = i;
    row.previewText = itemDescription;
    row.link = itemLink;
    row.columnValues[0] = new PTTextColumnValue(itemTitle);
    row.columnValues[1] = new PTTextColumnValue(itemCategory);
    row.columnValues[2] = new PTTextColumnValue(itemAuthor);
    row.columnValues[3] = new PTTextColumnValue(itemPubDate);
    channelTable.rows[channelTable.rows.length] = row;
    }

  // Redraw the table
  channelTable.draw();
  }
</script>

<b>Select RSS Feed:</b>
<a href="#" onclick="getRSSFeed('http://www.wired.com/news/feeds/rss2/0,2610,,00.xml'); return false;">Wired News</a>
<a href="#" onclick="getRSSFeed('http://news.com.com/2547-1_3-0-5.xml'); return false;">CNET News.com</a>
<a href="#" onclick="getRSSFeed('http://partners.userland.com/nytRss/nytHomepage.xml'); return false;">NY Times</a>
<br><br>

<!-- Set up a table control to display channel items -->
<div id="channelTableContainer"></div>
<script defer type="text/javascript">
  var channelTable = new PTTableControl();
  channelTable.locale = 'en_US';
  channelTable.objName = 'channelTable';
  channelTable.container = 'channelTableContainer';
  channelTable.baseURL = '/imageserver/plumtree/common/private/portal-remote-server/js/jscontrols/1/';
  channelTable.statusBarText = 'No RSS Feed Selected';
  channelTable.rowDetailAction = new PTJavaScriptAction('window.open(\'${ROW.link}\');');
  channelTable.columns[0] = new PTColumn();
  channelTable.columns[0].name = 'Title';
  channelTable.columns[0].width = '40%';
  channelTable.columns[1] = new PTColumn();
  channelTable.columns[1].name = 'Category';
  channelTable.columns[1].width = '20%';
  channelTable.columns[2] = new PTColumn();
  channelTable.columns[2].name = 'Author';
  channelTable.columns[2].width = '20%';
  channelTable.columns[3] = new PTColumn();
  channelTable.columns[3].name = 'Publication Date';
  channelTable.columns[3].width = '20%';
  channelTable.areColumnsResizable = true;
  channelTable.clientSortEnabled = true;
  channelTable.scrollHeight = 250;

  channelTable.init();
  channelTable.draw();
</script>
</div>

  Back to Top      Previous Next