August 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Hacking the Weblogic Portal UI Framework

  • February 28, 2006
  • By Scott Nelson
  • Send Email »
  • More Articles »

Would You Like Spreadsheets with That?

Next to printing, the most frequent thing business users want to do is to play with table data. Sure, you can do some AJAX thing to let them view the numbers in different ways while they are logged into your portal, and you probably should (again, contact me if you're interested in specifics). But, what about when you user wants to take your data with them and play with it on the flight? Rather than bog them down with a cached version of the whole portal, or hints on how to copy the data to a spreadsheet (unless you have a huge tech-support budget), why not just give it to them the way they want it?

We already found out how to get a handle on our portlet with label definitions, and building a spreadsheet instead of a printout just takes a little refinement.

One difference is you are going to create a hidden iFrame on our page to receive the page (since the result is a file, not a page) by adding the following to footer.jsp:

<iframe id="scriptRender"
        src=""
        style="visibility:hidden;
        height:0px; padding:0px;
        margin:0px"></iframe>

Then, you will make a new function in your js similar to the print function but with some changes to hide the page that is called and pass in the table values:

function excelPortlet(appPath, tableId, portletName)
{
   var tableData = document.getElementById(tableId).outerHTML;
   var pageString =
      appPath+'/resources/jsp/excelPage.jsp?tableData='
             +tableData+'&portletName='+portletName;
   document.getElementById('scriptRender').src = pageString;
}

Next, you will add your icon to the toolbar in the same way you did the print icon except that you will hide the icon until you want it and reference your table instead of the whole portlet:

<img src="<render:getSkinPath
     imageName="excelIcon.gif" />"
     id="<%=window.getDefinitionLabel()%>.excelIcon"
     style="cursor:pointer;
     position:relative; top:-2px;
     visibility:hidden"
     onclick=
        "excelPortlet('<%=request.getContextPath()%>',
                      '<%=window.getDefinitionLabel()%>.
                       excelTable',
                      '<%= title %>')">

Of course, to use the icon, you need to unhide it. You do this in the portlet JSP itself by adding a reference to the Window context then calling your label definition handle, like this:

<%@ page import="com.bea.netuix.servlets.controls.window.
                 WindowPresentationContext"%>
<%
   WindowPresentationContext window =
      WindowPresentationContext.
      getWindowPresentationContext(request);
%>
<script language="javascript">
document.getElementById('<%=window.getDefinitionLabel()%>.
                         excelIcon')
   .style.visibility = 'visible';
</script>

And, of course, write a small JSP to generate your spreadsheet:

<%@ page language="java"
         contentType="text/html;charset=UTF-8"%>
<%
   String tableData = request.getParameter("tableData");
   response.reset();
      response.setContentType("application/xls");
      response.setHeader("Content-Disposition",
                         "attachment;filename="
                         +request.getParameter("portletName")
                         +".xls");
%>

<%=tableData%>

Between the hidden iFrame and response changes, the user only sees the download, and none of the behind the screens magic:



Click here for a larger image.

If you use the <th> tag for your table's heading row, Excel will set it as a header row for sorting.

If you have multiple tables in a portlet, you can set the script call dynamically using the same ID referenced to turn on the icon.

Serving Data? Freshness Counts!

The last new titlebar item (in this article) is to set the date the portlet was last updated into the titlebar. Sure, you could put this into the portlet layout itself, but this saves some space.

Because BEA didn't think of this first, you need to make a slight change to titelbar.jsp by moving the declarations outside of the render context. Find the scriptlet section where WindowPresentationContext is declared and move this section above <render:beginRender> tag. There, that's better. Now that you can get at the window object outside of the render scope, add the following after the </tr>:

<tr><td colspan="3"
        id="<%=window.getDefinitionLabel()%>.dateCell"></td></tr>

And if you think that was easy, look at all you need to add to your portlet:

<% String myDate = "As of March 1, 2006"; %>
document.getElementById('<%=window.getDefinitionLabel()%>
                         .dateCell').innerHTML = '<%=myDate%>';

Yes, I'm too lazy to type all the Calendar and date formatting to do this with a real date, but you get the picture:



Click here for a larger image.

Together for the First Time on the BEA Desktop: Horizontal and Vertical Navigation

With all of these neat features, your portal's popularity will grow and folks will think of more and more portlets to add. More portlets leads to more pages (hopefully, or it's going to get awful crowded on the page, not to mention the coffee breaks prompted by slow page loads). If the page count continues to grow, your portal will eventually become difficult to navigate with out-of-the-box components (not to mention user-annoying side-scrolling as shown below).



Click here for a larger image.

The standard single-level navigation will wrap, but the extra rows of page navigation will eat up precious real estate at the top of the screen (if they have to scroll to it, they probably won't know it's there). You can use multi-level menus, but this adds two more mouse moves for the user to go where they want (although if your site has lots of pages, this solution is inevitable).

There is a cool hack to solve your growing navigation problem: Add a vertical navigation in addition to your horizontal tabs. This will last you as long as your visual design and page count can accommodate, giving you roughly double the page access on a single screen.

The key to the dual navigation approach is in using the hidden page setting.



Click here for a larger image.

The standard single-level menu code skips the hidden pages like this:

if (!pageCtx.isHidden() && pageCtx.isVisible())

At the end of the single-level menu code, you can add a DIV for your vertical menu and then run the same loop using the opposite check:

if (pageCtx.isHidden())

I've dropped the isVisible check because it is redundant anyway.

Now, with some simple CSS, you can position this menu anywhere you want. In the example, I chose to put it on the right:

<div id="verticalmenu"
     style="position:absolute;
     top:40px;
     right:20px;
     width:20px;">



Click here for a larger image.

Voilà! You've just bought a whole bunch of page real estate in 10 minutes.

If you already have hidden pages, use icons and then check for the existence of icons. I prefer using icons regardless for this type of navigation. In the portals where I have implemented this, the choice between horizontal or vertical navigation links was determined by the type of page it was. For example, in a portal that is geared towards business intelligence, there frequently are pages that are not BI related but still a desirable feature for your executive audience (such as event calendars and industry news). These "utility" pages lend themselves naturally to a different navigation model because they are separate from the rest of the portals' focus.

Prior to service pack 4, there's an annoying quirk in the API: pageCtx.isHidden()) never returns true because the framework pulls the hidden pages from the page list before returning it to the book context. You still can use hidden pages, but you have to hard code their values rather than being able to dynamically expand your vertical navigation simply by adding more hidden pages. To make sure your hard-coded menu is portable, be sure to use the render tag for the link, like this:

<a href="<render:pageUrl pageLabel=" hackinguiNews"/>">News</a>

So, even if your users were delighted the first time you released your portal into the wild and never asked for anything more, now you can give them a few extra things with very little work. I usually time that along with the next budget request.

About the Author

Scott Nelson is a Principal Developer in the Architectural Services division of Keane, Inc. where he has implemented custom portal functionality thought up by the best Information Architects and Visual Designers in the industry for large multi-national client companies.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel