38
Building an Ajax portlet for WebSphere Portal Skill Level: Intermediate Karl Bishop ([email protected]) Senior Software Engineer IBM Doug Phillips ([email protected]) Advisory Software Engineer IBM 16 Aug 2006 In our previous article, Using Ajax with WebSphere Portal, we discussed some issues and design concerns when using Ajax in a portal application. In this tutorial, we will put our newfound knowledge to use and create an Ajax portlet application. To make things interesting, we decided to build a portlet that makes heavy use of Ajax and DHTML. This provides you a glimpse into what's possible with this technology, and to also give you a useful tool to browse your databases. While most of the application is already written, it is up to you to fill in the blanks to get things running. Section 1. Before you start In this tutorial, you will write code for Ajax specific calls, review code that manipulates the DHTML of the page, and follow through the process of a complete round trip Ajax call from the browser to the server. The entire application is several hundred lines long, but we'll only ask you to code the important components while the rest will be provided. The steps are: Write browser independent code for creating XMLHttpRequest (XHR) and processing XML document objects. Send Ajax requests to the server and manipulate the returned results. Retrieve and manipulate the servlet context from the portlet configuration Building an Ajax portlet for WebSphere Portal © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 38

Building an Ajax portlet for WebSphere Portal

  • Upload
    others

  • View
    6

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Building an Ajax portlet for WebSphere Portal

Building an Ajax portlet for WebSphere PortalSkill Level: Intermediate

Karl Bishop ([email protected])Senior Software EngineerIBM

Doug Phillips ([email protected])Advisory Software EngineerIBM

16 Aug 2006

In our previous article, Using Ajax with WebSphere Portal, we discussed some issuesand design concerns when using Ajax in a portal application. In this tutorial, we will putour newfound knowledge to use and create an Ajax portlet application. To make thingsinteresting, we decided to build a portlet that makes heavy use of Ajax and DHTML.This provides you a glimpse into what's possible with this technology, and to also giveyou a useful tool to browse your databases. While most of the application is alreadywritten, it is up to you to fill in the blanks to get things running.

Section 1. Before you start

In this tutorial, you will write code for Ajax specific calls, review code thatmanipulates the DHTML of the page, and follow through the process of a completeround trip Ajax call from the browser to the server. The entire application is severalhundred lines long, but we'll only ask you to code the important components whilethe rest will be provided. The steps are:

• Write browser independent code for creating XMLHttpRequest (XHR) andprocessing XML document objects.

• Send Ajax requests to the server and manipulate the returned results.

• Retrieve and manipulate the servlet context from the portlet configuration

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 38

Page 2: Building an Ajax portlet for WebSphere Portal

for dynamically accessing the Ajax servlet included in the portlet .war file.

• Enable the JavaScript events to process the actions and display orupdate data on the JSP page.

• Deploy the portlet application onto WebSphere® Portal and see theresults.

We will also review the code that manipulates the data for this particular application,including how to:

• Enable and disable form elements during asynchronous Ajax calls.

• Use DHML to update select boxes after new data is retrieved from theAjax call.

• Dynamically update HTML <div> area tags using innerHTML to replacethe portions of the Web page.

Section 2. Setting up

This tutorial assumes that you will be using the Rational® Application Developer(RAD), or one of its kin, but you are free to use whatever you like to edit and deploythe portal application. Nothing in this exercise is tool specific. You will also need tohave WebSphere Portal v5.x or higher installed, and an available database, whichwe assume to be DB2® of course.

For all of these pieces to come together, you will need to import the application codeinto a RAD portal project and create at least one data source in WebSphere. Thefollowing steps will help you get started.

See Appendix A for the process of setting up a sample database and data source foruse in this tutorial. You can use any available data source once everything isconfigured.

Section 3. Configuring project and import files

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 2 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 3: Building an Ajax portlet for WebSphere Portal

1. Create a JSR 168 Portlet project in RAD.

1. Start RAD.

2. Select File > New > Other, then locate and select Portal > PortletProject (JSR 168). Note: Check Show All Wizards if you do notsee the Portal section.Figure 1. JSR 168 portlet project

2. Click Next.

3. Enter the following information as shown below.

• Name: Ajax_and_Portal

• Project location: Accept the default.

• WebSphere Portal version: Select your version of WebSphere Portal.

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 3 of 38

Page 4: Building an Ajax portlet for WebSphere Portal

• Create a portlet: Deselect this checkbox.Figure 2. New portlet project definition

4. Click Finished.

5. Import the provided source files into the new project.

1. Right-click on the top level of the "Ajax_and_Portal" project.

2. Select Import... > Import ...

3. Select Zip file.

4. Click Next.Figure 3. Import from the zip file

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 4 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 5: Building an Ajax portlet for WebSphere Portal

6. On the zip file import page, do the following:

• From Zip file: Locate and select the zip file you downloaded with thistutorial.

• Into folder: Ensure that the Ajax_and_Portal project is selected.

• Overwrite existing resources without warning: Select this checkbox.Figure 4. Select zip file to import screen

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 5 of 38

Page 6: Building an Ajax portlet for WebSphere Portal

7. Click Finished.

8. Your project structure should now look like Figure 5.Figure 5. Imported project structure

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 6 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 7: Building an Ajax portlet for WebSphere Portal

Section 4. Initial deployment and test

The first thing to do is deploy the application in its current -- albeit lifeless -- state.

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 7 of 38

Page 8: Building an Ajax portlet for WebSphere Portal

Refer to Appendix B for instructions on deploying the portlet application into portalusing RAD. Once you have the portlet deployed and placed on a page, we want tolook at it.

Figure 6. Application web page

Try to lookup a data source. Nothing happens! Not very exciting is it? By the end ofthis exercise, all of these items on the page will take action or display new databased on the Ajax calls made to the server, and the JavaScript code used to updatethe HTML tags.

Note that the Context Path is at the top of the portlet. You need this in just a minuteto call the servlet directly from your browser. In our sample above, the context pathis: /wps/PA_dsllabu.

It really is a portlet, no kidding

Yes, it's a portlet. And it completely confirms to the Java® Portlet (JSR168)specifications. However, Ajax itself is a separate technology that this exercise willdemonstrate, and it happens to be using a portlet for displaying the data. This isimportant because we are also including a servlet that retrieves data for theapplication inside the portlet war file. WebSphere Portal is going to deploy thisportlet, along with the servlet, as a Web application into IBM WebSphere Portal. Thisgives the portlet the ability to dynamically access the servlet that is included with itsapplication. It does not have to be deployed separately in another J2EE application.

Let's first take a look at the portlet code.

1. Locate the Project Explorer on the left of the page. Expand theAjax_and_Portal project and keep expanding down to the

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 8 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 9: Building an Ajax portlet for WebSphere Portal

DBExplorerPortlet.java file. Use Figure 7 to determine the location andtree structure of the file.Figure 7. DBExplorerPortlet.java location

2. Double click the file to open it in the editor view. Browse through the codeand notice it does nothing but display the JSP page for the portlet. ThedoView() method is displayed below as an example of what you shouldsee.

public void doView(RenderRequest request, RenderResponse response)throws PortletException, IOException {

// ------------------------------------------------------------// Note: The portlet is just diplaying a JSP for the AJAX Lab.// It does absolutely nothing else.// ------------------------------------------------------------

// Set the MIME type for the render responseresponse.setContentType(request.getResponseContentType());

// Invoke the JSP to renderPortletRequestDispatcher rd =

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 9 of 38

Page 10: Building an Ajax portlet for WebSphere Portal

getPortletContext().getRequestDispatcher(JSP_FOLDER + VIEW_JSP);rd.include(request,response);}

Ajax technology uses JavaScript and DHTML to use its functionality. This particularexample does not require any pre-determined data for the JSP; therefore, the portletitself has nothing to do other than display the JSP.

Section 5. It's a normal servlet, I tell ya

Creating the servlet is a no-brainer. You've done it hundreds of times. Implementyour service methods (doGet/doPost) and whatever business logic you require.Under normal circumstances, you will want to return an XML document to the caller,but you can return any textual information to the client. Let's look at the providedservlet code to understand where the data is coming from for the Ajax calls.

1. Under the Project Explorer, expand the tree down to the code for theservlet. The file is called com.ibm.examples.Ajax.servlets >DBExplorerServlet.java. Double click this Java file to open it in theeditor.

2. Notice the doPost() method of the servlet and what it accomplishes. Thisparticular code is not Ajax specific, but it is one way of getting a servlet torespond to the request by using parameters sent by the XMLHttpRequestobject explained later in the exercise.

3. Feel free to browse the code if you want to have a better understanding ofwhat it does.

Each set of parameters requested to the servlet causes it to respond with a uniqueXML result. The browser-side JavaScript then parses the response data and rendersit as needed. For example, if the parameter "LIST=SCHEMAS" is sent to the servlet,it returns the list of database schemas in an XML format. Let's try it, just to prove thatthere is nothing special happening with the servlet code.

1. Enter the following URL into your browser window. An example is shownin Figure 8.

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 10 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 11: Building an Ajax portlet for WebSphere Portal

http://localhost:9081/wps/PA_dsllabu/DBExplorerServlet?DS=jdbc/sample&LIST=SCHEMAS

Figure 8. Results of calling the servlet directly

Note: You need to adjust the actual URL to match your deployment. The/wps/PA_dsllabu portion of our sample URL is defined by the portalwhen you deployed your portlet application the first time. To see thecontext of your portal, look at the top of the Ajax portlet we deployedearlier.

This servlet is a simple J2EE servlet. You can access it via the browser like anyother servlet normally deployed through the WebSphere Application Serverinterface. WebSphere Portal deploys WAR files with their own unique URI so thatthe portlets and other Web components can access files for that particularapplication, such as images, JavaScript, cascading style sheets and, in our example,servlets. Because it is deployed like any other Web application, the servlet is also

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 11 of 38

Page 12: Building an Ajax portlet for WebSphere Portal

deployed with the same Web context as the portlet application.

The only real trick when bundling a servlet with a portlet application is registering itinto the web.xml file. You do this exactly as you would in a normal Web application.

Below is a fragment of the web.xml file from our exercise. The important item tonotice is the Servlet-mapping > url-pattern. In this case, it's/DBExplorerServlet. This value is used when we define a JavaScript variablethat our Ajax calls will use to communicate with the servlet. Go ahead and view theDeployment Descriptor of our project. A sample is shown in Figure 9.

Figure 9. Portlet web.xml file with bundled servlet definition

Section 6. Defining a JavaScript variable to address theservlet

For the application to know how to call our servlet dynamically (because you do notknow what the URI context will be until it is deployed), you need to write some codeto dynamically define the URL for the servlet.

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 12 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 13: Building an Ajax portlet for WebSphere Portal

1. In the Project Explorer, open the following file: Ajax_and_Portal >WebContent > jsp > DBExplorer_View.jsp. Use Figure 10 to locate thefile in the tree structure.Figure 10. View JSP file location

2. Select the Source tab if not already selected, and locate the commenttext "Insert JavaScript for the Ajax_SERVLET servlet URL here", andcode the JavaScript section as shown below. Use the code sample belowto determine the location of the inserted code and the actual code to typein the application.

<%---------------------------------------------------------------------------------------Set AJAX response servlet URL variable-------------------------------------------------------------------------------------Placing this variable in the JSP allows for runtime compile updates to the javascriptWe are using encodeURL() and getContextPath() to get the path of the web applicationdeployed as a WAR file in Portal for accessing the servlet, stylesheet and javascript---------------------------------------------------------------------------------------%><%--------------- Insert JavaScript for the AJAX_SERVLET URL here --------%><script type="text/javascript">

var AJAX_SERVLET = "<%=renderResponse.encodeURL(renderRequest.getContextPath())%>"+ "/DBExplorerServlet";

</script>

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 13 of 38

Page 14: Building an Ajax portlet for WebSphere Portal

<%------------------------------- End JavaScript insert ------------------%>

You must place this code inside the JSP so that the portal runtime canuse the portlet objects (renderResponse and renderRequest) todetermine the servlet context generated when the portlet application wasdeployed. The Ajax functions in the JavaScript can now use this variableto make the calls to the servlet to retrieve the data needed for updatingthe page dynamically.

3. Look through the rest of the JSP file. Here are a few key points to look for:

1. None of the form fields have any event handlers (for example,onclick="event()") assigned to them. We will inject them atruntime using JavaScript.

2. There is not an actual <form> tag, nor a way to submit the forminput field contents to the server. Again, this will be handled by theAjax calls.

3. At the very end of the file there is a small Javascript block that callsan "init()" function. This function adds the event listeners toour input fields. In normal Web applications, this function is calledas an "onload" event to the body element. But, since this is aportlet JSP fragment, we have no body tag to use. Therefore, thiscall needs to be made after the HTML content has been loadedinto the DOM.

4. Save your JSP changes by selecting File -> Save on the top menu or bypressing Ctrl-S.

Section 7. So where's the Ajax stuff?

Good question! Let's get started coding the real thing. For Ajax to work properly, youneed to retrieve and use the XMLHttpRequest object from any browser your clientmay be using. To do that, code a JavaScript function to get a browser independentXMLHttpRequest object. Different browsers instantiate this XHR object differently.

1. In the Project Explorer, open the following file: Ajax_and_Portal >WebContent > js > DBExplorer.js.

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 14 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 15: Building an Ajax portlet for WebSphere Portal

2. Locate the getXMLHttpRequest function. Insert the following code into thescript at the lines indicated.

function getXMLHttpRequest() {var xhr = null;

// ---- Insert code here ----if ( window.XMLHttpRequest ) {// Mozilla/Safarixhr = new XMLHttpRequest();

} else if ( typeofActiveXObject != "undefined" ) {// IExhr = new ActiveXObject("MicroSoft.XMLHTTP");

}// ---- End insert code ----

return xhr;}

This function is the key to making the browser independent Ajax work because itdetermines if the browser supports the XMLHttpRequest or the ActiveXObject(Microsoft.XMLHTTP) object. This function returns the proper object, depending onthe supported type of the browser. The API itself is the same once the object iscreated, but different browsers support different instantiations and require uniquecalls to create each object. This function takes care of most of the browsers.

Section 8. Configuring the Ajax calls and retrieving data

Now that you can get the actual XMLHttpRequest object to make the Ajax call backto the server, you need to create functions that will implement this behavior.

To understand the code in the next section, you need to understand the differentstates specified for the XMLHttpRequest calls. In the JavaScript (at the top of thefile), the code has already been added as variables to help later in the exercise. Thecode snippet below shows an example of what is being used in this exercise. You donot have to code this part of the exercise because it is already in the script. This isfor reference only.

//-------------------------------------------------------------------------// Set global ready state and HTTP variables to checkAJAX status//-------------------------------------------------------------------------var READY_STATE_UNITIALIZED=0;

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 15 of 38

Page 16: Building an Ajax portlet for WebSphere Portal

var READY_STATE_LOADING=1;var READY_STATE_LOADED=2;var READY_STATE_INTERACTIVE=3;var READY_STATE_COMPLETE=4;var HTTP_OK = 200;

Next, we need to create code that makes an XMLHttpRequest call to the server andrequests specific data.

1. Locate the event_setDataSource function. Insert the following code asindicated below.

function event_setDataSource() {log("event_setDataSource: starting", "#660");

// ... Existing code removed for brevity...

// XHR for Schemaslog("event_setDataSource: getting schemas", "#660");

// ---- Insert code here ----xhr_getSchemas = getXMLHttpRequest();xhr_getSchemas.onreadystatechange = callback_getSchemas;xhr_getSchemas.open("POST",AJAX_SERVLET,true);xhr_getSchemas.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");xhr_getSchemas.send("LIST=SCHEMAS&" + getFormDataParams() );

// ---- End insert code ----

log("event_setDataSource: finished", "#660");}

This particular function is used to make a call to the Ajax servlet andrequests a list of schemas from the database. There are several otherfunctions in this script already coded for you that make similar calls, butyou should focus on this particular one because of the scope of thisexercise. This section of the code creates an XHR object, assigns acallback function, and opens a POST connection to the AJAX_SERVLET(defined in the JSP file earlier). Finally, it initiates the request passing insome parameters. Identify the following methods used with theXMLHttpRequest object and what they do.Method name Function

.onreadystatechange Tells which JavaScript function tocall if the state of the requestchanges. (You will be coding this inthe next section.)

.open Sets the request method (POST inour example), the URL anddetermines if the browser shouldmake the call asynchronously (true)or wait for a result (false). Thisexample does not need the browser

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 16 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 17: Building an Ajax portlet for WebSphere Portal

to wait for a response, so we set it totrue for asynchronous calls.

.setRequestHeader Tells the servlet what type of contentis being sent in the request. In thisexample, the call will contain HTTPform parameters.

.send Initiates the call to the servlet andattaches the parameters to therequest.

The following functions for the other form fields are already completed forthis exercise and do not need to be added. They use similar code thatwas added above to update other areas of the screen. It is for referenceonly:

• event_setSchema

• event_setTable

• event_addColumn

• event_deleteColumn

• event_getTableData

2. Since you told the XMLHttpRequest object you were going to use a statehandler in the previous step, you need to code the callback function andhave it take action when states change. Locate the callback_getSchemasfunction , and insert the following code at the area indicated.

function callback_getSchemas() {handlerLog("callback_getSchemas", xhr_getSchemas, "#00c");

// ---- Insert code here ----// Show object is updating if the ready state is loadingif (xhr_getSchemas.readyState == READY_STATE_LOADING) {showSelectUpdating("schema_select");

}// Handle results if the ready state is completeif (xhr_getSchemas.readyState == READY_STATE_COMPLETE) {if (xhr_getSchemas.status == HTTP_OK) {

fillSelect("schema_select", xhr_getSchemas.responseXML, true);formUnlockField("schema_select");

} else {error("Failed to retrieve schema list:" + xhr_getSchemas.status);

}}

// ---- End insert code ----}

Notice in this code there are two different sections. If the state on therequest changes to "READY_STATE_LOADING" (or 1), it updates the

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 17 of 38

Page 18: Building an Ajax portlet for WebSphere Portal

data on the page indicating the request has been made and the data isbeing updated. This part of the application is already coded for you. It is agood idea to show data is being updated for Ajax-related calls becauseyou do not know how fast the network connection will be or how long itwill take to return the data. Setting an "updating" indicator gives the enduser a sense of activity while the browser waits on a response. Without anindicator, the end user may think nothing is happening, especially if thereis a slow response.The second section of this function will execute if the state on the requestchanges to "READY_STATE_COMPLETE" (or 4). This means the requestis finished and typically ready for the results to be processed. ThisfillSelect function takes the resulting XML document and updates theHTML select tags with the returned data. The following functions for theother fields on this page are already included in the file and do not needto be added. They use similar code that was added above to update otherareas of the screen. It is for reference only:

• callback_getDatabaseProperties

• callback_getTables

• callback_getColumns

• callback_getTableData

3. Save the file before continuing by selecting File > Save or typing Ctrl-S.

Section 9. Kick starting the code

Now that you have all of the Ajax code in place, it's not going to start by itself. Youneed to tell the browser that you actually want something to happen when an actionis performed. You need to have some JavaScript events coded so the end user cankick off the Ajax calls when the user is interacting with the application. In this section,you will add the "onclick" event to the datasource lookup button.

1. Locate the init() function in the DBExplorer.js file. Add an event handlerfor the load data source button by inserting the following code into thescript at the lines indicated.

document.getElementById("datasource_button").onclick =event_setDataSource;

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 18 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 19: Building an Ajax portlet for WebSphere Portal

This tells the browser to execute this function when the button is clicked.We could have added these event listeners directly inside the form inputtags, but that is not near as much fun. When adding event listeners usingthis method, you add the actual function object, and therefore, do notinclude quotes or the parenthesis. The events for the other fields havealready been coded for you. The table below contains the other "onXXX"events that are already coded and need no action by you. You can reviewthese areas of the code if you wish to have a better understanding.Input field Event Handler

functionActionperformed

Datasourceload button

onclick event_setDataSource Retrievesdatabasepropertiesandschemalist.

Schemaselect

onchange event_setSchema Retrievesthe tablelist.

Tableselect

onchange event_setTable Retrievesavailablecolumns.

Availablecolumnsselect

ondblclick event_addColumn Addscolumn toactivecolumnslist andretrievestable data.

Activecolumnsselect

ondblclick event_deleteColumn Removescolumnfrom activecolumnslist andretrievestable data.

2. Save your changes before continuing to the next step by selecting File ->Save from the menu or type Ctrl-S.

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 19 of 38

Page 20: Building an Ajax portlet for WebSphere Portal

Section 10. Deploying and testing the application

Now that you have coded the Ajax sections of the JavaScript and told the JSP toexecute code upon lookup of a data source, you need to deploy the completedapplication onto the server. Refer to Appendix B on the procedures to deploy theportlet application.

Now that the portlet is deployed, you need to test the application.

1. Point your browser to your portal page containing our portlet.

2. Start by entering a data source name, or accepting the default of"jdbc/sample", and click on the Lookup button. Notice the other itemsstart to dynamically changing the information based on the data sourcevalue and the onclick event coding that you put into the JSP. A log areashows the various activities taking place.So what exactly is happening? When you entered a data source andclicked the Lookup button, the onclick event was fired causing a call to the"event_setDataSource" function. This function initiates a couple of XHRAjax processes to retrieve data from the server. Once the responses arereceived from the server, they are processed by the various"callback_XXX" functions. The received XML data is parsed and used topopulate the respective areas of the document. All of this activity occursasynchronously! There was no portal page refresh as shown by thetimestamp at the top of the page, and multiple items were updated on thepage. This is Ajax!

3. Now select a schema such as DB2INST1. The fields automatically updateto show only the tables defined for that particular schema.

4. Select a table from the list of available tables. For example, if you choseDB2INST1 as the schema, you could choose EMPLOYEE as the table.As you do this, the columns become available for that particular table inthe selection box below the table list.

5. Double click a few of the columns to add them to the selected columnslist. If you chose the EMPLOYEE table, you could add EMPNO,FIRSTNAME, MIDINIT and LASTNAME to the columns. Notice how thedata table is automatically updated to reflect the selected columns.

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 20 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 21: Building an Ajax portlet for WebSphere Portal

6. Double click entries in the Active columns list to remove them. The datatable is updated to reflect the new selections. Remember, all this activityoccurs without any page refresh or any portal interaction! The following isan example of the entire page filled in with data after making the callsusing Ajax.Figure 11. Demo application in action

You may try and use different data sources and explore your data. Experiment, trydifferent things. How can you enhance the application?

Section 11. Troubleshooting

You've done it! You are now a master in the arts of Ajax and portal development.What? Something is not working? You have a few options.

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 21 of 38

Page 22: Building an Ajax portlet for WebSphere Portal

1. Go back and review all of your code updates. A cheat file is also providedin the Ajax_and_Portal zip file called solutions.txt. Compare the sourcecode blocks included there with what you have in your code.

2. Use the Mozilla Firefox browser along with the FireBug extention to debugthe JavaScript. Firebug, written by Joe Hewitt, is easy to learn and willquickly help you track down any errors in the code. Spend 30 minutesusing this amazing tool, and you'll save yourself hours, or even days,trying to figure out any JavaScript related bugs.

3. Review the portal log files for error messages generated by the servlet.Common problems will be related to the data source connections to thedatabase.

4. As a last resort, you may also send the authors an email detailing what'shappening, and we'll try our best to get you back on track.

Section 12. The magic behind the screen updates

As far as Ajax is concerned, you have made the calls to get data and have updatedthe page with the data returned. That is Ajax in a nutshell. If you want to continue toexplore some of the DHTML used in updating this data, you can continue theexercise. In the following sections, you will understand how the HTML objects areupdated dynamically. These are just a few examples of what you can do once youretrieve the data. This part of the exercise is mostly DHTML examples and isoptional. We cover:

• Dynamically updating HTML select contents using DOM

• Dynamically updating HTML DIV content using innerHTML

• Disabling form fields and re-enabling them once the Ajax calls arecomplete

• Getting the form data to send as parameters in the Ajax call

• Logging area

Dynamically updating HTML select contents using DOM

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 22 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 23: Building an Ajax portlet for WebSphere Portal

Using the methods described previously, locate the DBExplorer.js file and find thefunction fillSelect().

// -------------------------------------------------------------------------------------// Function to fill a specific select object from a properly formatted XML document// -------------------------------------------------------------------------------------function fillSelect( id, xmlResults, addAny) {

clearSelect(id);selectObj = document.getElementById(id);if ( selectObj ) {if (addAny) {

selectObj.options[0] = new Option("All Schemas", "any");}var xmlRoot = xmlResults.getElementsByTagName("htmlselect")[0];if (xmlRoot) {

for(var i=0; i < xmlRoot.childNodes.length; i++) {child = xmlRoot.childNodes[i];if (child.nodeName == "select") {attrs = child.attributes;selectObj.options[selectObj.length] = new Option(

child.firstChild.nodeValue, attrs.getNamedItem("value").value);}

} //for}if (selectObj.length==0) {

selectObj.options[0] = new Option("Not Available", "None");selectObj.disabled = true;

}if (selectObj.options[0]) {

selectObj.options[0].selected = true;}

} // if obj}

Notice how the code checks for the tag element htmlselect in the XML sent by theAjax servlet and parses through select tags to get the data for updating the selectoptions. If you accessed the servlet directly at the beginning of the exercise, you willnotice the format of the XML returned is familiar. When a select tag is found in theXML, a new option is created on the select list. This allows for dynamic changes tothe select boxes once the list is cleared using the clearSelect(id) method, which isalso included in the JavaScript.

Dynamically updating HTML DIV contents using innerHTML

Locate the function updateDivHtml() in the DBExplorer.js file.

// -------------------------------------------------------------------------------------// Function to update a specific DIV object from an XML Document// -------------------------------------------------------------------------------------function updateDivHtml(xmlDoc, divName) {

var divHtml = "<table class='property_table'>";var xmlRoot = xmlDoc.getElementsByTagName("htmldiv");if (xmlRoot) {// Limit to only the first matching element.// Should only ever be one, but still need to state it

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 23 of 38

Page 24: Building an Ajax portlet for WebSphere Portal

xmlRoot = xmlRoot[0];if (xmlRoot.childNodes.length == 0) {

divHtml = createDivRow("No data available","");} else {

for(var i=0;i<xmlRoot.childNodes.length;i++) {textLine = xmlRoot.childNodes[i];if (textLine.nodeName=="textline") {attrs = textLine.attributes;if (attrs && textLine.firstChild) {

divHtml += createDivRow(attrs.getNamedItem("label").value,textLine.firstChild.nodeValue);

}}

}} // if

}divHtml += "</table>";document.getElementById(divName).innerHTML = divHtml;

}

The DIV tag is updated differently in this example. It is similar in that it parses theXML returned, but the XML is in a different format. It dynamically creates HTML intable format to insert into the DIV. Notice on the last line of the function that theDOM element's innerHTML attribute is updated with the table HTML created duringthe parsing. This completely replaces the current HTML inside the DIV with thenewly formatted HTML dynamically, and updates the screen.

Disabling form fields and re-enabling them once the Ajax calls are complete

The following two functions located in the Ajax_and_Portal.js file enable and disablea form object on the page when an Ajax call is made. This reduces the number ofproblems that can occur if there are multiple items that can be changed during asingle request. By disabling the field, you ensure none of the other selectable itemsare updated by the end user while they are waiting on a request from the servlet.

// ----------------------------------------------------------------------------// Functions to lock/unlock form objects. Used when processing// requests so the user doesn't try to update the field when the// requests are not finished processing.// ----------------------------------------------------------------------------function formLockField( id ) {

document.getElementById( id ).disabled = true;}function formUnlockField( id ) {

document.getElementById( id ).disabled = false;}

The typical logic flow has the event handler function disable any fields that will beupdated during the Ajax call. Once the Ajax responses are received, it is theresponsibility of the callback function to unlock the appropriate form fields.

Getting the form data to send as parameters in the Ajax call

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 24 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 25: Building an Ajax portlet for WebSphere Portal

The form data is sent as parameters just like a normal request is made for a HTMLform. In this code, each DOM object that has information we want to send as part ofthe Ajax call is encoded and placed in a parameter string to send along with therequest. Notice the code also sends a timestamp along with the request. This helpsthe browser not cache the URL to the servlet, in case there are multiple requests tothe same system.

// -------------------------------------------------------------------------------------// Function to retrieve all of the form data to send to the AJAX servlet as parameters// -------------------------------------------------------------------------------------function getFormDataParams() {

var params = "DS=" + encodeURIComponent( document.getElementById("get_ds").value )+ "&SCHEMA=" + encodeURIComponent(getSelectedOption("select_schema"))+ "&TABLE=" + encodeURIComponent(getSelectedOption("select_table"))+ "&COLUMNS=" + getOptionList("selected_columns")+ "&NOCACHE=" + new Date().getTime();log("Form params: " + params);return params;

}

Logging area

One section of our application provides a window for logging event to better tracethe process flow. This is a simple sub-system to implement. Toolkits will typicallyoffer similar functionality, but this serves our purpose.

First, open the css > DEBExplorer.css file and locate the div.logger and stanza thatare located near the bottom of the file.

div.logger {height: 200px;width: 100%;font-family: monospace;font-size: small;background-color: #eaeaea;overflow: scroll;border: 1px solid #000099;

}

As you can see, we are creating a scrollable DIV area with a fixed height. Thiscauses the content to scroll down as we add new log messages to the top of thelogging area. Next, open the DBExplorer.js file and locate the logger functionlocated near the bottom of the file.

// -------------------------------------------------------------------------------------// update logging window with messages// -------------------------------------------------------------------------------------function log(msg, color) {

var logger = document.getElementById("logger");

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 25 of 38

Page 26: Building an Ajax portlet for WebSphere Portal

if ( color == null ) {color = "black";

}if ( logger ) {var d = new Date();var time = (d.getHours() + ":" + d.getMinutes() + ":"

+ d.getSeconds()).replace(/\b(\d)\b/g, '0$1');logger.innerHTML = "<span style='color:"+color+"'>"

+ time + ": " + msg + "</span><br />" + logger.innerHTML;} else {alert("No logging area found! Log message is:\n" + msg);

}}

In this function, we obtain a reference to the logger DIV using its ID attribute. Wewant to add a nicely formatted timestamp to each message, as all logs should do, sowe create a Date object, and get the desired fields. The replace regular expressionshown just inserts a leading zero to any single digit within a word boundary (forexample, "3:47:2" is converted to "03:47:02"). Finally, we insert the log message withthe requested color, before the existing content that exists in the logging area.Notice how the innerHTML property is both writable and readable, all within thesame context.

Section 13. Appendix A. Configuring the sample databaseand data source

The default data source for our application is DB2's ubiquitous "sample" database,defined as a data source named "jdbc/sample". If you know the name of anotherdata source that exists within your application server, you can overwrite the defaultwith your own. Otherwise, let's go ahead and configure the sample.

First, let's create the sample database. DB2 makes this easy. Either run DB2's "FirstSteps", and select Create sample database, or from the command line, as the DB2instance user, run db2sampl. Refer to the DB2 getting started documentation if youneed more help.

Second, we need to define a data source for the sample database. Start up yourprimary WebSphere Application Server, typically it is server1.

1. Log into the administrative console:

• For WebSphere Application Server v5: http://localhost:9090/admin

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 26 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 27: Building an Ajax portlet for WebSphere Portal

• For WebSphere Application Server v6:http://localhost:9060/ibm/console

2. Create a new JDBC driver provider:

1. Select Resources > JDBC Providers.

2. Click the New button.

3. For JDBC Providers, select DB2 Universal JDBC DriverProvider.

4. Click OK.

5. You can leave everything as is on the New provider definitionpage.

6. Click OK.

7. Click the Save link at the top of the page and save the settings.

3. Define the location of our DB2 JDBC drivers:

1. Select Environment > Manage WebSphere Variables.

2. Set the following environment variables to the location of yourdb2java.zip file. If you do not have DB2 or DB2client installed, youwill need to obtain this file from an installed DB2 deployment andplace it somewhere on your system.

${DB2UNIVERSAL_JDBC_DRIVER_PATH}${UNIVERSAL_JDBC_DRIVER_PATH}

3. For each variable:

1. Click the variable name.

2. For the Value field, enter the directory where the db2java.zipfile is located. For Linux: /opt/IBM/db2/V8.1/java.

3. Click OK.

4. Click the Save link at the top of the page and save thesettings.

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 27 of 38

Page 28: Building an Ajax portlet for WebSphere Portal

4. Create a J2C authentication alias:

1. Select Security > JAAS Configuration > J2C AuthenticationData.

2. Click the New button.

3. Enter the following fields, adjust as required for yourimplementation:

• Alias: sampleDBAuth

• User ID: Your DB2 instance user ID, such as db2inst1

• Password: Your DB2 instance's password

4. Click OK.

5. Click the Save link at the top of the page and save the settings.

5. Create a new Data Source for our sample database.

1. Select Resources > JDBC Providers.

2. Click on the new JDBC provider we just created, DB2 UniversalJDBC Driver Provider.

3. Click the Data Sources link at the bottom of the page.

4. Click the New button.

5. Set the following fields on the Configure Data Source page:

• Name: sample

• JNDI name: jdbc/sample

• Container-Managed Authentication Alias: xxxxx/sampleDBAuthNote: The value is prefixed by your application server node name.

6. Click OK.

7. Click the link for the newly created sample data source link.

8. Click the custom properties link at the bottom of the page.

9. For each of the variable names shown below, set the value to the

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 28 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 29: Building an Ajax portlet for WebSphere Portal

appropriate value based on your configuration. The values shownare for a default installation.

• serverName:localhost

• portNumber:50001

10. After the fields are updated, click the Save link at the top of thescreen and save the settings.

6. Test out the new data source:

1. Select Resources > JDBC Providers.

2. Click on the new JDBC provider we just created, DB2 UniversalJDBC Driver Provider.

3. Click the Data Sources link at the bottom of the page.

4. Click the link for the newly created sample data source link.

5. Click the Test Connection button. You should see a successmessage at the top of the screen. If you see an error, review all ofyour settings and try again. Also, make sure you actually have yourdatabase running!

7. Congratulations, your database and data source are now ready to use.

Section 14. Appendix B. Deploying the portlet

This section provides information on how to deploy a portlet WAR file through RADwith just a few simple clicks.

1. In the Project Explorer, right-click on the Ajax_and Portal project andselect Deploy Portlet... from the menu as shown in Figure 12.Figure 12. Deploy Portlet menu option

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 29 of 38

Page 30: Building an Ajax portlet for WebSphere Portal

2. Configure a portal server to enable deployment. The first time you run thiswizard, there will not be a server configured. If there is not a serverconfigured, then follow these steps, otherwise continue to Step number 3.

1. Click the New... button to configure a new server. Note: If you havea remote portal server you wish to deploy to, then you either FTPaccess or a shared directory (for example, NFS). Setting up remoteservers is out of the scope of this exercise, and you will need toconsult the RAD and WebSphere Portal help documentation.

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 30 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 31: Building an Ajax portlet for WebSphere Portal

2. For a normal portal environment, you will want to select the valuesshown in Figure 13. Adjust these to match your environment andclick Next.Figure 13. Deploy and define new server

3. Enter the following information. Standard values are shown inFigure 14, but you may have to adjust for your particulardeployment. When finished, click Next.Figure 14. Deploy portal settings

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 31 of 38

Page 32: Building an Ajax portlet for WebSphere Portal

4. Configure the publishing settings. The values shown in Figure 15are for a local installation on a Linux platform. Adjust these tomatch your configuration, then click Finish.Figure 15. Deploy, publishing settings

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 32 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 33: Building an Ajax portlet for WebSphere Portal

3. Select the appropriate server to deploy your portlet to. Typically, this islocalhost > WebSphere Portal v5.1 for Import, Export and Deploy @localhost, and click Finish. See Figure 16.

4. If the portlet has been previously deployed, you will receive a pop-upasking to overwrite the existing content. Answer Yes to continue to deploythe changes.Figure 16. Deploy, server select

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 33 of 38

Page 34: Building an Ajax portlet for WebSphere Portal

5. Your portlet should now be deployed on the server!

If this is the first time deploying the portlet, you need to add it to a page on yourportal:

1. Using your Web browser, log into your portal using an administrativeaccount.

2. [Optional] Create a new page for the portlet.

1. Select the portal Administration link.

2. Select Portal User Interface > Manage Pages.

3. Select My Portal link from the list pages.

4. Click the New page button.

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 34 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 35: Building an Ajax portlet for WebSphere Portal

5. Provide a name of Ajax and Portal,and customize as you see fit.Then click the OK button, and then OK again.

3. Add the portlet to a page:

1. Select the portal Administration link.

2. Select Portal User Interface > Manage Pages.

3. Select My Portal link from the list pages.

4. Click the Edit Page Layout button for your page that you will placeyour portlet.

5. Click the Add portlets button.

6. Search for "Ajax", select the Ajax Database Explorer portlet, andclick OK.

7. Click Done to finish the page edit.

Section 15. Conclusion

In this tutorial, we described how and why you would use Ajax in your portalapplications. We also built a fully functional portlet application that uses Ajax inseveral areas. We also introduced you to the tightly coupled technologies involvedwith DHTML manipulation. While it is impossible to examine all conceivable uses ofAjax and WebSphere Portal in this tutorial, it was our intention to whet your appetiteto learn, and to apply this exciting technology into your future applicationdevelopment toolkit.

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 35 of 38

Page 36: Building an Ajax portlet for WebSphere Portal

Downloads

Description Name Size Download method

Sample code for this tutorial AJAX_and_Portal.zip38KB HTTP

Information about download methods

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 36 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.

Page 37: Building an Ajax portlet for WebSphere Portal

Resources

Learn

• Using Ajax with WebSphere Portal

• Introduction to Ajax on developerWorks

• Dojo

• Rico

• DWR

• Behaviour

• Zimbra

• Ajax Patterns

• Mozilla Developer Center

• Ajax in Action

• Dynamic HTML, The Definitive Guide, O'Reilly

• JavaScript, The Definitive Guide, O'Reilly

• Build enterprise SOA Ajax clients with the Dojo toolkit and JSON-RPC

Get products and technologies

• Ajax Toolkit Framework (IBM alphaWorks)

• Ajax Toolkit Framework (eclipse.org)

About the authors

Karl BishopKarl Bishop is a Senior Software Engineer on the IBM Web Enablement and Supportteam. He works from the wilds of North Carolina. Karl works on various internal andexternal portal-based applications, as well as being a strong proponent of Linux basedsolutions.

ibm.com/developerWorks developerWorks®

Building an Ajax portlet for WebSphere Portal© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 37 of 38

Page 38: Building an Ajax portlet for WebSphere Portal

Doug PhillipsDoug Phillips is an Advisory Software Engineer for IBM's elite group of skilledprofessionals known as IBM's Web Enablement and Support team. He has worked inmany organizations within IBM and currently designs and develops both internal andexternal WebSphere Portal applications using IBM middleware and Linux. Doug isWebSphere and DB2 certified.

developerWorks® ibm.com/developerWorks

Building an Ajax portlet for WebSphere PortalPage 38 of 38 © Copyright IBM Corporation 1994, 2008. All rights reserved.