How to Create a Controller for a Refreshed Parameterized Page

Extensibility
Extensibility covers the mechanisms by which you, as the user or developer, can extend the functionality of the Teradata Database, for example with the use of User Defined Functions, or UDFs.
Teradata Employee

How to Create a Controller for a Refreshed Parameterized Page

This is a particularly difficult task to implement in a portlet, so let's start by understanding the challenges. First, what is a refreshed, parameterized page? A parameterized page is a page that can display dynamic information and needs parameters to determine the content that will be displayed. There are several examples in existing Teradata Viewpoint portlets such as My Queries, Filtered Queries, Query Monitor, and System Health. All of these portlets allow the user to click on one item in the summary view to drill down to detailed information about that item. They also refresh that detailed information. System Health has an automatic refresh and the queries portlets have a manual refresh button.

What are your refresh options? The easiest is to let the user refresh the content using the browser refresh button. But you may want the page to automatically refresh at a periodic interval, so you could use a javascript timer to trigger a refresh of the page. However this has two major drawbacks:

  1. Drawing the entire page can take several seconds
  2. If the user is in the middle of filling out a form, that form content is lost.

So, the ideal solution is to just refresh the content of just one portlet without disturbing the other portlets on the page. You can do this using a web technology called AJAX. The tutorial page Adding Dynamic Updates with AJAX describes how to implement an AJAX refresh in a portlet with a single page.

When you have a multi-page portlet, you need to do some extra work that is not described in the tutorial.

Implementing Drill-Down to a Detail Page

The portlet specification doesn't address how to make a request for content for a single portlet, so you need to bypass the portal by creating a servlet in our portlet application that will respond to drill-down requests. Use the same servlet that is described in the Adding Dynamic Updates with AJAX tutorial for your drill-down requests. You just need to add an extra method to the ViewpointController class to process the drill-down request. Suppose you are writing a portlet similar to System Health in which the user drills down by clicking on a system. The new controller method is going to look something like this:

\MySystemPortlet\src\java\com\teradata\portlets\mysystem\controllers\MySystemViewController.java

public class MySystemViewController implements Controller
{
...
public void summary(ControllerContext ctx)
{
ctx.setViewName("summary");
...
}

public void detail(ControllerContext ctx)
{
ctx.setViewName("detail");
String system = ctx.getParameter("system")
ctx.addViewObject("data", getDetailData(system));
ctx.addViewObject("system", system);
}
}

Where getDetailData is a method in the service that fetches the detail data for a specific system.

How do you invoke this method from your summary page? You need to create a link (anchor tag) in the summary page that gets mapped to the detail method. For example:

\MySystemPortlet\web\WEB-INF\portlet-jsp\summary.jsp

<a href="/MySystemPortlet/dataserver/detail?context=${context}&system=prod1">Prod1</a>
<a href="/MySystemPortlet/dataserver/detail?context=${context}&system=prod2">Prod2</a>
<a href="/MySystemPortlet/dataserver/detail?context=${context}&system=qa">QA/a>

All three of these links get mapped to the detail method, but with a different parameter value. Note that you always need to pass a parameter named context to a servlet so that it knows which portlet instance has made the request. The ViewpointController automatically creates a request variable called context that you can reference in your JSP as we have done in the example.

You still need to tell your application that servlet requests named detail should be sent to the MySystemViewController class. Do this in the servlet configuration file:

\MySystemPortlet\web\WEB-INF\dataserver-servlet.xml

<!-- map requests to controllers by mapping url to the controller name -->
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/summary">mySystemViewController</prop>
<prop key="/detail">mySystemViewController</prop>
</props>
</property>
</bean>

<bean id="mySystemViewController"
class="com.teradata.portlets.mysystem.controllers.MySystemViewController">
<description>Controller for views</description>
</bean>

Implementing Refresh of a Detail Page

If you want the detail page to refresh periodically, you can use the Refresh tag:

\MySystemPortlet\web\WEB-INF\portlet-jsp\detail.jsp

<%@ taglib prefix="vp" uri="http://teradata.com/viewpoint-widgets"%>
<vp:Refresh context="${context}" refreshInterval="30"
refreshUrl="/SkewedSessionsPortlet/dataserver/detail?context=${context}&system=${system}" />

Accessing Parameters in a Portlet Request

So far, your detail page has only been accessed by AJAX servlet requests. But the user could navigate to another tab and back again or just refresh the entire page. These actions will cause the portal to make a portlet request to your application. To provide the best possible user experience, your portlet should redisplay the current detail page. However, as currently coded, it is going to display the summary page. This is because the portal doesn't know that the user navigated to the detail page and it doesn't know which system is being viewed in the detail page. The ViewpointController class can automatically direct this request to the detail page and provide the correct parameters, but you need to help it out by saving the current page name and parameter values in the user's session. There are two ViewpointController methods that you use to do this: setPageName and setSessionParameter. Let's extend our detail controller with these calls:

\MySystemPortlet\src\java\com\teradata\portlets\mysystem\controllers\MySystemViewController.java

public class MySystemViewController implements Controller
{
...
public void summary(ControllerContext ctx)
{
ctx.setViewName("summary");
ctx.setPageName("summary");
...
}

public void detail(ControllerContext ctx)
{
ctx.setViewName("detail");
ctx.setPageName("detail");
String system = ctx.getParameter("system")
ctx.addViewObject("data", getDetailData(system));
ctx.addViewObject("system", system);
ctx.setSessionParameter("system", system);
}
}

  This is all that we need to do for portlet requests to work correctly.

Implementing Drill-Up to Summary Page

The convention in Teradata Viewpoint portlets that have a detail page is for the user to be able to return to the summary page by clicking a back button in the portlet frame. You can add this back button to your detail page JSP using the following code:

\MySystemPortlet\web\WEB-INF\portlet-jsp\detail.jsp

<%@ taglib prefix="vp" uri="http://teradata.com/viewpoint-widgets"%>
<vp:portlet-header-overlay state="all" mode="replace" namespace="${context}">
<div class="portlet-header-nav-backbutton"
onclick="TDPortalManager.refreshPortlet('${context}',
'/MySystemPortlet/dataserver/summary');"></div>
</vp:portlet-header-overlay>

The portlet-header-overlay tag adds its contents to the portlet header. A div with the class portlet-header-nav-backbutton displays the back arrow image. TDPortalManager.refreshPortlet is a javascript method that refreshes the portlet using the specified URL.

2 REPLIES
Enthusiast

Re: How to Create a Controller for a Refreshed Parameterized Page

I am getting an error on vp:portlet-header-overlay of "tag not found". Can someone tell me as which jar to use to ge this tag lib working?

Thanks & Regards,
S. Fawad Ali Shah.
dfu
Teradata Employee

Re: How to Create a Controller for a Refreshed Parameterized Page

That should be in tdcommons-taglib.jar