Building Ajax-enabled JSP TagLib controls, Part 3: Update ...
Upcoming SlideShare
Loading in...5
×
 

Building Ajax-enabled JSP TagLib controls, Part 3: Update ...

on

  • 7,880 views

 

Statistics

Views

Total Views
7,880
Views on SlideShare
7,880
Embed Views
0

Actions

Likes
1
Downloads
16
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Building Ajax-enabled JSP TagLib controls, Part 3: Update ... Building Ajax-enabled JSP TagLib controls, Part 3: Update ... Document Transcript

    • Building Ajax-enabled JSP TagLib controls, Part 3: Update panel and popup dialog box controls Using JSP TagLib, JSON, and Ajax Skill Level: Intermediate Brian J. Stewart (BrianJStewart@AquaDataTech.com) Principal Consultant Aqua Data Technologies, Inc. 07 Apr 2009 Build Asynchronous JavaScript + XML (Ajax) controls that can be used in business-line applications. These configurable JavaServer Pages (JSP) TagLib-based controls leverage JavaScript Object Notation (JSON), JavaScript scripting language, and Cascading Style Sheets (CSS). Because they are standard JSP TagLib controls, find out how you can easily drop them into any application to provide more intuitive and responsive user interfaces. Introduction Two key technologies enable next-generation Web sites: Asynchronous JavaScript + XML (Ajax) and JavaScript Serialized Object Notation (JSON). Business-line applications can benefit from these technologies to provide more intuitive and responsive user interfaces. This article describes how to add Ajax and JSON to Java™ Platform Enterprise Edition (Java EE) Web applications by building reusable JavaServer Pages (JSP) TagLib controls based on Ajax. Within this article, learn how to build an update panel control that dynamically retrieves content asynchronously from the server, based on user events. For example, content can be retrieved when a user clicks a field, enters a value in a field, or selects a value in a drop-down selection list. I also describe how to build a pop-up dialog control that asynchronously retrieves the dialog content from the server when the dialog is displayed. For example, the dialog can be displayed when Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 1 of 40
    • developerWorks® ibm.com/developerWorks a user hovers over an item, clicks a button, or selects a value in a drop-down selection list. About this series This article is part of a multi-part series on developing a suite of Ajax-enabled controls for J2EE applications. The controls are built using JSP TagLib controls and leverage JSON, Servlet, and JavaScript technologies. About this article This article describes how to build the following controls: • Update panel—Asynchronously retrieves content to provide a dynamic user interface. The control provides configurable parameters for Cascading Style Sheets (CSS) formatting while content is being retrieved as well as post retrieval of content. It also provides standard event handlers (that is, before content is loaded, after the content is loaded) to allow for further customizations. • Pop-up dialog—Provides a window that retrieves content asynchronously when the dialog is first shown. This provides a responsive user interface by retrieving content only upon demand. The control provides optional configurable parameters for CSS formatting, a dialog title, a close button located in top right corner of the window (similar to a standard Windows® dialog), and the dialog size and location. Both of these JSP TagLib controls encapsulate all asynchronous communication, JavaScript code, CSS formatting, and Hypertext Markup Language (HTML) generation. Technical overview This article builds upon the design principles and code outlined in the first two articles of this series (see Resources). It introduces techniques for adding event handlers to a custom control, as well as advanced techniques for configuring the control's presentation and behavior. As in the previous articles in the series, the primary design goals of the JSP Ajax-enabled control suite developed in this article are as follows: • Provide easy integration with existing Web applications—the controls Update panel and popup dialog box controls Page 2 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® should encapsulate all logic and JavaScript code to simplify the deployment process • Allow easy configuration • Minimize data- and page-size overhead • Leverage the CSS and HTML standards • Provide cross-browser support (Windows Internet Explorer, Mozilla Firefox) • Leverage common design patterns/best practices to improve code maintainability Similar to the first two articles in this series, the <ajax:page/> control is used to encapsulate common JavaScript functions to minimize data and overhead. Web standards, including CSS and HTML, are used for cross-browser support. The JavaScript code, HTML, and CSS emitted by the controls are tested against Windows Internet Explorer 7.x and Mozilla Firefox 2.x/3.x. Class model The example in this article consists of the Data Abstract Layer (DAL), Data Transfer Objects (DTO), the Business Logic Layer (BLL), the Presentation Layer, and supporting helper classes. The article also uses the LocationDataService DAL class from the first article in the series. This class returns collections of LocationDTO DTO instances. No additional DAL or DTO classes are needed in this article. The BLL consists of value providers that provide data to the Ajax-enabled controls, and server-side validators that provide server validation for HTML form data. This article uses the LocationService class and the JdbcQuery helper class from the first article in the series. No other utility classes are required. Even though you are only building two controls, you need to create several tags to make those controls robust, flexible, and configurable. Start with the update panel control, which is shown in Figure 1. This is the implementation class for the <ajax:updatepanel/> tag. Figure 1. Unified Modeling Language (UML) class diagram of UpdatePanelTag Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 3 of 40
    • developerWorks® ibm.com/developerWorks Update panel and popup dialog box controls Page 4 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® The update panel control supports optional arguments that are passed along with the asynchronous request for the update panel. The implementation class for the <ajax:panelargument/> tag is shown in Figure 2. Figure 2. UML class diagram of PanelArgumentTag The pop-up control is more complicated and uses several tags. The key tag is <ajax:popupdialog/>. The implementation class for this tag is shown in Figure 3. Figure 3. UML class diagram of PopupDialogTag Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 5 of 40
    • developerWorks® ibm.com/developerWorks Update panel and popup dialog box controls Page 6 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® The <ajax:popupdialog/> can contain a <ajax:popuparguments/> tag for the arguments that are passed along with the asynchronous request for the dialog content. The implementation classes for the <ajax:popuparguments/> and <ajax:popupargument/> tags are shown in Figure 4. Figure 4. UML class diagram of PopupDialogButtonContainerTag and PopupDialogButtonTag The <ajax:popupdialog/> can contain a <ajax:popupbuttoncontainer/> tag for the buttons displayed for the pop-up dialog. The implementation classes for the <ajax:popupbuttoncontainer/> and <ajax:popupbutton/> tags are Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 7 of 40
    • developerWorks® ibm.com/developerWorks shown in Figure 5. Figure 5. UML class diagram of PopupDialogArgumentContainerTag and PopupDialogArgumentTag Build the update panel JSP TagLib control Traditionally, Web developers needed to refresh the entire Web page even if only a portion of the page changed as a result of a user action, such as when a user enters a value in a field, selects a value in a drop-down list, checks a check box, or clicks on a control. The content and business requirements differ, but most business-line applications have dynamic content that changes based on user events. The primary goal of the <ajax:updatepanel/> control is to build a reusable Update panel and popup dialog box controls Page 8 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® control that addresses this common scenario and lets you easily have only the portions of the page that change be updated dynamically. The control handles all communication and presentation functions, while leaving the content to the Web developers. The control provides the ability to optionally pass arguments, such as form field values, when the asynchronous request is made. To provide maximum flexibility, the update panel should be easily displayed or hidden without any knowledge of the internals of the update panel. Figure 6 shows how the update panel looks while the panel is being updated. Figure 6. Update panel while content is being retrieved When the server responds to the asynchronous request, the update panel content is updated. Figure 7 shows how the update panel looks after the asynchronous content is received and displayed. Figure 7. Update panel after content has been retrieved Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 9 of 40
    • developerWorks® ibm.com/developerWorks Technical overview of control When the page is first rendered, a DIV container is rendered for the dialog box. Initially, the update panel element is empty. When the event is triggered to show the update panel, the content is asynchronously retrieved from the server. The update panel is then updated with the dynamic content. The <ajax:updatepanel/> provides the configurable options described in Table 1. Table 1. Configurable options for the update panel Option Description id Control ID url URL to retrieve content for the update panel updatemessage Message to display while content is being asynchronously retrieved Update panel and popup dialog box controls Page 10 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® loadingcss CSS class name to be applied while the content is being loaded (for example, "Please wait..." message) cssclass CSS class name to be applied after content is loaded onclear Optional name of JavaScript function to invoke before the update panel is cleared oncleared Optional name of JavaScript function to invoke after the update panel is cleared onload Optional name of JavaScript function to invoke before the update panel is loaded onloaded Optional name of JavaScript function to invoke after the update panel is loaded Use case scenarios for event handlers The event handlers are a powerful feature of this control. Although the code to render and invoke the hooks is fairly straightforward, they provide a mechanism that makes the control highly flexible and reusable. You can use the onload event handler to test that specific fields (on which the update panel depends) are populated. A message can be displayed to the user if the required fields aren't populated and false can be returned to cancel the update to the panel. Another use of this function is to populate any hidden INPUT elements based on other form field values. For example, within the event handler, calculation can be performed or strings concatenated for data sent along with the asynchronous request. You can use the onloaded event handler to process other form fields based on the server response. For example, perhaps certain fields should be disabled, hidden, or populated based on the server response. You can use the onclear event handler to check certain criteria before clearing the update panel. For example, perhaps the user should be prompted to save the data before clearing the update panel. You can use the oncleared event handler to clear any other form fields or reset the form. If the update panel is used in a reporting solution, you can place a Clear button on the form. The button can invoke the hide panel function and, upon clearing the panel, clear the report criteria. Building the functions to display or hide the update panel The <ajax:page/> renders two key functions for the <ajax:updatepanel/> control: Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 11 of 40
    • developerWorks® ibm.com/developerWorks • showUpdatePanel—Shows the update panel by invoking the corresponding onShow event handler • hideUpdatePanel—Hide the update panel by invoking the corresponding onHide event handler These functions are nearly identical and are nothing more than wrappers around the show and hide dialog functions for the dialog-specific instances. The name of the dialog is passed into these functions via the controlName argument. The onShow function name is dynamically built by concatenating the name of the dialog and _onShow. The panel-specific function, which is rendered in the <ajax:updatepanel/> tag is then invoked using the JavaScript statement window['functionName'](). Listing 1 shows the showUpdatePanel function. Listing 1. showUpdatePanel JavaScript function function showUpdatePanel(controlName) { var functionName = controlName + '_onShow'; window[functionName](); } By using this approach, the details about how the dialog is displayed and the content is asynchronously retrieved are abstracted from the Web application developer who is using the <ajax:updatepanel/> control. You simply need to call the showUpdatePanel or hideUpdatePanel JavaScript functions, passing the name of the panel to show or hide. Showing the update panel The next step is to build the panel-specific function that is called by the showUpdatePanel JavaScript function. This function is rendered by the <ajax:updatepanel/> tag and is responsible for: • Invoking any of the event handlers specified in the onclear, oncleared, onload, and onloaded tag attributes • Making the asynchronous request to retrieve the update panel content • Displaying the update panel using the options specified in the attributes, such as cssclass, loadingcss, and updatemessage Start with the dialogName_onShow function, which is shown in Listing 2. Listing 2. dialogName_onShow JavaScript function function cityPanel_onShow() { // Invoke the onload event. Update panel and popup dialog box controls Page 12 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® // If true is not return by the event handler, // cancel the update to the panel if (!window['onCityPanelLoad']()) { return; } // Get the dialog element var controlName = 'cityPanel_Container'; var curControl= document.getElementById(controlName); // Update status message to the value specified in the // updatemessage attribute if (curControl != null) { curControl.innerHTML = 'Retrieving cities...'; curControl.className = 'loadingpanel'; } // Url for retrieving dialog content (specified in url attribute) var targetUrl = '/ajaxcontrols3/fragments/cityList.jsp'; // Build the POST data sent for the asynchronous request to // retrieve the update panel content // The arguments specified in the contained panelargument tags // are dynamically added to the post data var postData = 'panelId=cityPanel' + '&state=' + getFormValue('state') + '&cityPrefix=' + getFormValue('cityPrefix'); // Initialize XmlHttpRequest object initializeXmlHttpRequest(); if (req!=null) { req.onreadystatechange=cityPanel_onServerResponse; // Set window status window.status='Retrieving cities...'; // Open server request req.open('POST',targetUrl,true); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); req.setRequestHeader("Content-length", postData.length); // Send data req.send(postData); } } The optional event handlers onclear, oncleared, onload, and onloaded are invoked by using the same window['functionName']() JavaScript statement. The data sent to the asynchronous request is dynamically added to the request. You use POST instead of GET because you want to avoid any issues with the query string length being exceeded or escaping of strings. The name/value pair is added to the POST data for each contained panelargument tag. The value can either be static using the value attribute or dynamic using the sourcefield attribute. The final step in showing the update panel is to handle the server response, which is done by the dialogName_onServerResponse function. The code is uncomplicated. It's a matter of checking the response and, if successful, replacing the content contained in the update panel with the server response. Listing 3 shows this function. Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 13 of 40
    • developerWorks® ibm.com/developerWorks Listing 3. dialogName_onServerResponse JavaScript function function cityPanel_onServerResponse() { // If loaded if(req.readyState!=4) return; // If an error occurred if(req.status != 200) { alert('An error occurred retrieving data.'); return; } // Get panel var curControl= document.getElementById('cityPanel_Container'); // If panel not found simply return (this shouldn't happen) if (curControl == null) return; // Update CSS class to the value specified in the cssclass attribute curControl.className = 'normalpanel'; // Set content of element to the server response curControl.innerHTML = req.responseText; // Clear window status window.status=''; // Invoke the onloaded event handler (this is not rendered // if there is no event handler specified in the oncleared // attribute) window['onCityPanelLoaded'](); } Hiding the update panel Next you build the dialogName_onHide function. This is the function that is called by the hideUpdatePanel function. The key purpose, besides the obvious clearing of the panel, is to optionally enforce business rules with the custom event handlers. This function is shown in Listing 4. Listing 4. dialogName_onHide JavaScript function function onHide_cityPanel() { // Invoke the onclear event. // If true is not returned by the event handler, // the action is cancelled and the panel remains // visible if(!window['onCityPanelClear']()) { return; } // Retrieve the update panel container var controlName = 'cityPanel_Container'; var curControl= document.getElementById(controlName); // If control wasn't found, return if (curControl == null) { alert(controlName + ' control not found!'); return; } Update panel and popup dialog box controls Page 14 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® // Clear tag curControl.innerHTML = ''; // Invoke the oncleared event handler (this is not rendered // if there is no event handler specified in the oncleared // attribute) window['onCityPanelCleared'](); } Update panel TagLib library definition entry The next step is to define the <ajax:updatepanel/> JSP control in the TagLib library definition file. Listing 5 shows the update panel control's TagLib library definition entry (with embedded comments for a description of each attribute). Listing 5. Update panel TagLib library definition entry <tag> <name>updatepanel</name> <tagclass>com.testwebsite.controls.updatepanel.UpdatePanelTag</tagclass> <bodycontent>JSP</bodycontent> <info>Update Panel tag.</info> <!-- Panel ID--> <attribute> <name>id</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Url to fragment--> <attribute> <name>url</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Message displayed while retrieving panel content--> <attribute> <name>updatemessage</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Loading CSS class name --> <attribute> <name>loadingcss</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- CSS class name (Post loading) --> <attribute> <name>cssclass</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Event: on clear --> <attribute> <name>onclear</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Event: on cleared --> <attribute> <name>oncleared</name> <required>false</required> Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 15 of 40
    • developerWorks® ibm.com/developerWorks <rtexprvalue>false</rtexprvalue> </attribute> <!-- Event: on loading--> <attribute> <name>onload</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Event: post loaded--> <attribute> <name>onloaded</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> Panel argument TagLib library definition entry Listing 6 shows the <ajax:panelargument/> JSP control in the TagLib library definition file (with embedded comments for a description of each attribute). Listing 6. Panel argument TagLib library definition entry <tag> <name>panelargument</name> <tagclass>com.testwebsite.controls.updatepanel.PanelArgumentTag</tagclass> <bodycontent>empty</bodycontent> <info>Contains the argument tag.</info> <!-- Argument name --> <attribute> <name>name</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Source field for argument value --> <attribute> <name>sourcefield</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Value for argument (overrides source field value if specified --> <attribute> <name>value</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> Build the pop-up dialog JSP TagLib control Traditionally, Web developers use window.open or window.showModalDialog to display pop-up windows in Web applications. Although they work fairly well, they aren't without their quirks and complexities. First, referring to other form fields can be cumbersome. Second, the presentation isn't as crisp and intuitive as Document Object Model (DOM) Scripting and CSS-based dialog boxes. Third, they don't lend themselves to a smooth way to display more information when, for example, a user Update panel and popup dialog box controls Page 16 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® hovers over an item on the page. Through DOM scripting and the use of the CSS z-index property, you can simulate dialogs for a Web page. With Ajax and asynchronous techniques, you can build quite powerful and flexible dialog boxes because data can be asynchronously retrieved from the server on demand. The primary goal of the <ajax:popupdialog/> is to create a JSP-based pop-up dialog control that combines DOM scripting, CSS, and Ajax to create a reusable control that can be easily added to any business-line application. The pop-up dialog control consists of several tags, which are described in Table 2. Table 2. Popup dialog control tags Tag Description popupdialog Popup dialog popuparguments Optional tag that contains one or more arguments (popupargument tags) passed to popup dialog popupargument Popup dialog argument for the popup dialog popupbuttoncontainer Optional tag that contains one more buttons (popupbutton tags). It can also contain HTML for formatting the button layout. popupbutton Button for popup dialog Figure 8 shows the components of the pop-up dialog. Figure 8. Sample popup dialog container Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 17 of 40
    • developerWorks® ibm.com/developerWorks Technical overview of control When the page is first rendered, a DIV container is rendered for the dialog box. The style display: none is applied to hide the pop-up dialog. The container will optionally contain a title panel (depending on the showtitle and title attributes) and a button panel (depending on whether the <ajax:popupdialog/> contains a <ajax:popupbuttoncontainer/> tag). It also renders DIV within the dialog container for the dialog content. This element is initially empty, and the dialog content is added when the showDialog function is called for the corresponding Update panel and popup dialog box controls Page 18 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® pop-up dialog. When the pop-up dialog is displayed, the following occurs: 1. The style is changed to display: block to make the pop-up dialog visible. 2. The updatemessage is displayed in the pop-up dialog while the dialog content is being retrieved. 3. An asynchronous request is made to the server to retrieve the dialog content. 4. Upon receiving the server response, the dialog content is displayed. Two key CSS properties are also applied to the pop-up dialog container to make it work. The first is z-index: 100;, which ensures the dialog container is displayed on top of other Web page elements. The second is position: absolute;, which allows for the pop-up dialog to be positioned. The pop-up dialog control provides several configurable features that define the pop-up dialog's behavior and presentation. The configurable features described in Table 3 are supported. Table 3. Configurable features of the pop-up dialog control Feature Description id Control ID title Dialog title showtitle Option to control whether the dialog title is displayed (default: true) showclose Option to control whether the close button is displayed (default: true) width Overall width of dialog height Overall height of dialog contentheight Height of dialog content pane that is scrollable left Left position of dialog top Top position of dialog url URL to retrieve dialog content when the dialog is shown updatemessage Message displayed while content is being retrieved Building the functions to display or hide the pop-up dialog Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 19 of 40
    • developerWorks® ibm.com/developerWorks The <ajax:page/> renders two key functions for the <ajax:popupdialog/> control: • showDialog—Shows the pop-up dialog by invoking the corresponding onShow event handler. • closeDialog—Hide the pop-up dialog by invoking the corresponding onHide event handler. Similar to the update panel, these functions are nearly identical and do nothing more than provide wrappers around the show and hide dialog functions for the dialog-specific instances. As mentioned with the update panel, this approach abstracts the details about how the dialog is displayed and content is asynchronously retrieved from anyone who is using the <ajax:popupdialog/> control. You simply need to call the showDialog or closeDialog JavaScript functions, passing the name of the dialog to show or hide the update panel. Showing the pop-up dialog The next step is to build the dialog-specific functions to display the pop-up dialog. This function, rendered mostly by the <ajax:popupdialog/> tag, contains JavaScript code based on the options specified in the tag's attributes. For example, set the title of the dialog, build the POST data and URL, and make the asynchronous request. This function is shown in Listing 7. Listing 7. dialogName_onShow JavaScript function function stateDialog_onShow() { // Get dialog control var dialogControl = document.getElementById('stateDialog'); dialogControl.style.display = 'block'; // Set title (if showtitle attribute is not false) var titleControl = document.getElementById('stateDialog_dialogTitleText'); titleControl.innerHTML = 'Select States'; // Get dialog content control var dialogContentName = 'stateDialog_dialogContent'; var contentControl = document.stateDialog_dialogForm[dialogContentName]; // If dialog content control is not null if (contentControl != null) { contentControl.innerHTML = 'null'; } // Initialize XmlHttpRequest object initializeXmlHttpRequest(); if (req == null) { alert('XmlHttpRequest object not initialized.'); } // Url for retrieving dialog content (specified in url attribute) var targetUrl = '/ajaxcontrols3/fragments/selectState.jsp'; // Build the POST data sent for the asynchronous request to Update panel and popup dialog box controls Page 20 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® // retrieve the dialog content // The arguments specified in the optional argument tag(s) // contained in the popuparguments tag var postData = ''; // The dialogName_getPostData function is rendered by the // popuparguments tag (if specified). // Check if the function is defined and if so, invoke the // function if (window['stateDialog_getPostData'] != undefined) { postData = window['stateDialog_getPostData'](); } // Set server response function var responseFunction = 'stateDialog_onServerResponse'; req.onreadystatechange = eval(responseFunction); // Open server request req.open('POST',targetUrl,true); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); req.setRequestHeader("Content-length", postData.length); // Send data req.send(postData); } The next step is to handle the server response, which is handled by the dialogName_onServerResponse function. The code is not difficult. The dialog content is replaced with the HTML returned by the asynchronous server request. The server response function is shown in Listing 8. Listing 8. dialogName_onServerResponse JavaScript function function stateDialog_onServerResponse() { // If loaded if(req.readyState!=4) return; // If an error occurred if(req.status != 200) { alert('An error occurred retrieving panel content.'); return; } // Get response var responseData = req.responseText; // Get dialog content pane var dialogContentName = 'stateDialog_dialogContent'; var contentControl = document.getElementById(dialogContentName); // If dialog content pane found, set the content if (contentControl != null) { contentControl.innerHTML = responseData; } } Pop-up dialog TagLib library definition entry The next step is to define the <ajax:popupdialog/> JSP control in the TagLib Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 21 of 40
    • developerWorks® ibm.com/developerWorks library definition file. Listing 9 shows the pop-up dialog control's TagLib library definition entry (with embedded comments for a description of each attribute). Listing 9. Popup dialog TagLib library definition entry <tag> <name>popupdialog</name> <tagclass>com.testwebsite.controls.popupdialog.PopupDialogTag</tagclass> <bodycontent>JSP</bodycontent> <info>Popup Dialog tag.</info> <!-- Popup ID--> <attribute> <name>id</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Popup Title--> <attribute> <name>title</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Show Title --> <attribute> <name>showtitle</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Show Close Button --> <attribute> <name>showclose</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Size Width --> <attribute> <name>width</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Size Height --> <attribute> <name>height</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Size Content Height --> <attribute> <name>contentheight</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Position Left --> <attribute> <name>left</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Position Top--> <attribute> <name>top</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Url to fragment--> <attribute> Update panel and popup dialog box controls Page 22 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® <name>url</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Message displayed while retrieving panel content--> <attribute> <name>updatemessage</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> Pop-up argument container and pop-up argument controls The <ajax:popupdialog/> can optionally contain the <ajax:popuparguments/> tag to send POST data for the asynchronous request to retrieve the dialog content. This tag is responsible for rendering the dialogName_getPostData function. Listing 10 shows an example dialogName_getPostData function that simply returns a string containing all name/value pairs for the POST data. Listing 10. dialogName_getPostData JavaScript function function cityDetailsDialog_getPostData() { var data = 'dialogName=cityDetailsDialog' + '&zipCode=' + getFormValue('selectedZipCode'); return data; } A name/value is rendered for each popupargument tag. The following code fragment is rendered for each argument: + '&zipCode=' + getFormValue('selectedZipCode');. The popupargument tag is explained in more detail later. The doStartTag renders the start of the dialogName_getPostData function. The method for the <ajax:popuparguments/> is shown in Listing 11. Listing 11. Pop-up argument container doStartTag method public int doStartTag() throws JspException { StringBuffer html = new StringBuffer(); String dialogName = this.getDialogName(); html.append("<script type='text/javascript' language='javascript'>"); html.append("function "); html.append(dialogName); html.append("_getPostData() {"); html.append("var data = 'dialogName="); html.append(dialogName); html.append("'"); JspWriter out = pageContext.getOut(); try { Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 23 of 40
    • developerWorks® ibm.com/developerWorks out.append(html.toString()); } catch (IOException e) { e.printStackTrace(); } return PopupDialogArgumentContainerTag.EVAL_BODY_INCLUDE; } The doEndTag method closes the dialogName_getPostData function, and is shown in Listing 12. Listing 12. Pop-up argument container doEndTag method public int doEndTag() throws JspException { StringBuffer html = new StringBuffer(); html.append(";"); html.append("return data;"); html.append("}"); html.append("</script>"); // Write output JspWriter out = pageContext.getOut(); try { out.append(html.toString()); } catch (IOException e) { e.printStackTrace(); } return PopupDialogArgumentContainerTag.EVAL_PAGE; } The next step is to define the <ajax:popuparguments/> JSP control in the TagLib library definition file. Listing 13 shows the pop-up dialog argument container's TagLib library definition entry (with embedded comments for a description of each attribute). Listing 13. Pop-up arguments TagLib library definition entry <tag> <name>popuparguments</name> <tagclass>com.testwebsite.controls.popupdialog.PopupDialogArgumentContainerTag </tagclass> <bodycontent>JSP</bodycontent> <info>Popup Dialog Argument Container</info> <!-- Popup Argument Container ID--> <attribute> <name>id</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> The next step is to define the <ajax:popupargument/> JSP control in the TagLib library definition file. The pop-up argument's TagLib library definition entry (with embedded comments for a description of each attribute) is shown in Listing 14. Update panel and popup dialog box controls Page 24 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® Listing 14. Pop-up argument TagLib library definition entry <tag> <name>popupargument</name> <tagclass>com.testwebsite.controls.popupdialog.PopupArgumentTag</tagclass> <bodycontent>empty</bodycontent> <info>Contains the argument tag.</info> <!-- Argument name --> <attribute> <name>name</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Source field for argument value --> <attribute> <name>sourcefield</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- Value for argument (overrides source field value if specified) --> <attribute> <name>value</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> Pop-up button container and button controls The <ajax:popupdialog/> can optionally contain a button panel <ajax:popupbuttoncontainer/> tag. The container tag renders a DIV element named dialogName_dialogButtonContainer. The <ajax:popupbuttoncontainer/> tag can contain one or more <ajax:popupbutton/> tags. There are two types of buttons supported by the pop-up dialog control—cancel and normal. If the button type is cancel, the closeDialog is invoked when the button is clicked. If the button type is normal, the JavaScript function specified in the onclick attribute is invoked. The button is rendered in the doStartTag method of the pop-up button. The logic for the type of button and the event handler to be invoked is contained in this method, shown in Listing 15. Listing 15. Pop-up button doStartTag method public int doStartTag() throws JspException { StringBuffer html = new StringBuffer(); // Get button container PopupDialogButtonContainerTag buttonPane = (PopupDialogButtonContainerTag) this.getParent(); String dialogName = buttonPane.getDialogName(); // Render button html.append("<input type='button' id='"); html.append(this.getId()); Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 25 of 40
    • developerWorks® ibm.com/developerWorks html.append("' class='"); html.append(this.getCssclass()); String buttonLabel = this.getLabel(); if (buttonLabel != null && buttonLabel.length() > 0) { html.append("' value='"); html.append(buttonLabel); } html.append("' onclick='"); // Check button type and render event handler accordingly String buttonType = this.getType(); if (buttonType == null || buttonType.length() < 1 || buttonType.equalsIgnoreCase("cancel")) { html.append("closeDialog(""); html.append(dialogName); html.append("")"); } else { html.append(this.getOnclick()); html.append("(""); html.append(dialogName); html.append("", document."); html.append(dialogName); html.append("_dialogForm)"); } html.append("'/>"); // Write output JspWriter out = pageContext.getOut(); try { out.append(html.toString()); } catch (IOException e) { e.printStackTrace(); } return PopupButtonTag.EVAL_BODY_BUFFERED; } The next step is to define the <ajax:popupbuttoncontainer/> JSP control in the TagLib library definition file. The button panel container's TagLib library definition entry (with embedded comments for a description of each attribute) is shown in Listing 16. Listing 16. Pop-up dialog button container TagLib library definition entry <tag> <name>popupbuttoncontainer</name> <tagclass>com.testwebsite.controls.popupdialog.PopupDialogButtonContainerTag </tagclass> <bodycontent>JSP</bodycontent> <info>Popup Dialog Button Container</info> <!-- Popup Button Container ID--> <attribute> <name>id</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> Update panel and popup dialog box controls Page 26 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® Next, you'll want to define the <ajax:popupbutton/> JSP control in the TagLib library definition file. The button's TagLib library definition entry (with embedded comments for a description of each attribute) is shown in Listing 17. Listing 17. Pop-up button TagLib library definition entry <tag> <name>popupbutton</name> <tagclass>com.testwebsite.controls.popupdialog.PopupButtonTag</tagclass> <bodycontent>empty</bodycontent> <info>Contains the argument tag.</info> <!-- Button id --> <attribute> <name>id</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <!-- Button label --> <attribute> <name>label</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> <!-- Type of button --> <attribute> <name>type</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- onclick Event handler --> <attribute> <name>onclick</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> <!-- CSS class name --> <attribute> <name>cssclass</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> Testing the controls There are three test pages you use to demonstrate the new Ajax enabled controls. Those pages are described in Table 4. Table 4. Test pages Page Description SearchLocations.jsp Uses the <ajax:updatepanel/> to provide real-time filtering of a data grid containing cities. The city lists can be filtered by state (drop-down selection list) and city name (text field). The two fields call the showUpdatePanel when their respective values change. Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 27 of 40
    • developerWorks® ibm.com/developerWorks LocationReport.jsp Uses the <ajax:popupdialog/> to provide a mock reporting page. The reporting criteria include a state text field that, when clicked, displays a pop-up dialog containing a list of all states with check boxes. When the user clicks the Save button, a comma-separated list of states is built and the value of the state text field is set to the comma-separated list. NewYorkCityList.jsp Displays a list of all cities in New York. It uses the <ajax:popupdialog/> to display additional information for a city when a user hovers over a zip code in the city list. The pop-up dialog is hidden when the zip code loses focus. Search Locations page (SearchLocations.jsp) The Search Locations page demonstrates how to use the update panel control. Figure 9 shows a sample update panel. Figure 9. Update panel demonstration: Search Locations page The Search Locations page demonstrates how to use the event handlers, as well as how to hook the update panel to two controls (a SELECT and an INPUT text box). Listing 18 shows the code for this sample page. Update panel and popup dialog box controls Page 28 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® Listing 18. SearchLocations.jsp <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="ajax" uri="/WEB-INF/tlds/ajax_controls.tld"%> <html> <head> <title>Locations</title> <link href="core.css" rel="stylesheet" type="text/css" /> <ajax:page/> <script type='text/javascript' language='javascript'> function onCityPanelCleared() { var msgControl = document.getElementById('statusMessage'); if (msgControl != null) { msgControl.innerHTML = 'oncleared'; } } function onCityPanelClear() { var msgControl= document.getElementById('statusMessage'); if (msgControl != null) { msgControl.innerHTML = 'onclear'; } return true; } function onCityPanelLoad() { var msgControl = document.getElementById('statusMessage'); if (msgControl != null) { msgControl.innerHTML = 'onload'; } return true; } function onCityPanelLoaded() { var msgControl= document.getElementById('statusMessage'); if (msgControl != null) { msgControl.innerHTML = 'onloaded'; } } function displayCityPanel(curControl) { if (!curControl.checked) { hideUpdatePanel('cityPanel'); } } function retrieveCityData() { showUpdatePanel('cityPanel'); document.all.showCityPanel.checked = 'checked'; } </script> </head> <body> <b>State: </b> <select id="state" onchange="retrieveCityData()"> <option value=''> </option> <option value='AK'> Alaska</option> <option value='AL'> Alabama</option> <option value='AR'> Arkansas</option> ... ... <option value='WI'> Wisconsin</option> <option value='WV'> West Virginia</option> Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 29 of 40
    • developerWorks® ibm.com/developerWorks <option value='WY'> Wyoming</option> </select><br/> <b>City Prefix: </b> <input type="text" id="cityPrefix" onkeyup="retrieveCityData()"/> <br/> <input type="checkbox" id="showCityPanel" name="showCityPanel" checked="checked" onclick="displayCityPanel(this)" />Show City Panel<br/> <div><b>Result: </b><span id="statusMessage"></span></div> <div> <ajax:updatepanel id="cityPanel" url="/fragments/cityList.jsp" updatemessage="Retrieving cities..." cssclass="normalpanel" loadingcss="loadingpanel" onclear="onCityPanelClear" oncleared="onCityPanelCleared" onloaded="onCityPanelLoaded" onload="onCityPanelLoad"> <ajax:panelargument name="state" sourcefield="state"/> <ajax:panelargument name="cityPrefix" sourcefield="cityPrefix"/> </ajax:updatepanel> </div> </body> </html> Location report (LocationReport.jsp) The Location report demonstrates how to use the pop-up dialog let users select multiple states (check boxes). When the user selects the Save button on the pop-up dialog, a text box is set to a comma-separated list containing the selected states. Figure 10 shows the pop-up dialog. Figure 10. Pop-up dialog demonstration: Location report Update panel and popup dialog box controls Page 30 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® When the user double clicks the selectedStates control, the pop-up dialog is displayed using the showDialog function. When the user clicks the Save button on the popupdialog, the onSaveStates JavaScript function is invoked, which builds a comma-separated list of the selected values. The selectedStates text box is then populated with the list. The code for the Location report is shown in Listing 19. Listing 19. LocationReport.jsp <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="ajax" uri="/WEB-INF/tlds/ajax_controls.tld"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Search Locations</title> <link href="core.css" rel="stylesheet" type="text/css" /> <script type="text/javascript"> function onSaveStates(dialogName, dialogForm) { var values = ''; var stateList = dialogForm.states; for (var i = 0; i < stateList.length; i++) { if (stateList[i].checked) { if (values.length != 0) { values += ", "; } values += stateList[i].value; } } var targetControl = document.getElementById('selectedStates'); Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 31 of 40
    • developerWorks® ibm.com/developerWorks targetControl.value = values; closeDialog(dialogName); } </script> <ajax:page id="page"/> </head> <body> <h1>Report Criteria</h1> <table width="80%" > <colgroup> <col width="40%"/> <col width="60%"/> </colgroup> <tbody> <tr> <td align="right" style="border:none;"> <span style="font-weight:bold">Zip Code:&nbsp; </span> </td> <td align="left" style="border:none;"> <input type="text" size="50" id="zipCode" /> </td> </tr> <tr> <td align="right" style="border:none;"> <span style="font-weight:bold">States:&nbsp; </span> </td> <td align="left" style="border:none;"> <input type="text" size="50" readonly="readonly" id="selectedStates" onclick="showDialog('stateDialog')"/> </td> </tr> </tbody> <thead> <th colspan="2" class="subHeading"> Search Locations</th> </thead> <tfoot> <tr> <td colspan="2"> <input type="button" class="dialogButton" value="Run Report" id="runReport"/> </td> </tr> </tfoot> </table> <ajax:popupdialog url="/ajaxcontrols3/fragments/selectState.jsp" id="stateDialog" width="400px" height="28em" left="0" top="0" title="Select States" contentheight="23em"> <ajax:popuparguments id="stateDialogArgs"> <ajax:popupargument name="arg1" value="test1"/> <ajax:popupargument name="arg2" value="test2"/> </ajax:popuparguments> <ajax:popupbuttoncontainer id="stateDialogButtons"> <ajax:popupbutton id="cancelButton" label="Cancel" type="cancel"/>&nbsp; <ajax:popupbutton id="saveButton" label="Save" type="normal" onclick="onSaveStates"/> </ajax:popupbuttoncontainer> </ajax:popupdialog> Update panel and popup dialog box controls Page 32 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® <h1>Report Results</h1> <div>Show report results here...</div> </body> </html> Listing 20 shows the page displayed within the pop-up dialog box. The code is relatively simple. A list of locations is retrieved from the Location Data Service, and this list is then iterated through, and a check box is rendered for each state. Listing 20. selectState.jsp <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page import="com.testwebsite.dal.LocationDataService" %> <%@ page import="com.testwebsite.dto.LocationDTO" %> <%@ page import="com.testwebsite.dto.StateDTO" %> <%@ page import="java.util.Iterator" %> <%@ page import="java.util.TreeMap" %> <%@ page import="java.util.Set" %> <ul style="list-style: none;" <% TreeMap<String, StateDTO> stateData = LocationDataService.getStateData(); // Iterate through all data looking for matching // cities and add to temporary TreeMap Set<String> keySet = stateData.keySet(); Iterator<String> stateIter = keySet.iterator(); while (stateIter.hasNext()) { // Get current state String curKey = stateIter.next(); StateDTO curState = stateData.get(curKey); out.println("<li><input type='checkbox' name='states' value='"); out.println(curState.getAbbreviation()); out.println("'/>&nbsp;"); out.println(curState.getName()); out.println("</li>"); } %> </ul> New York City Listing page (NewYorkCityList.jsp) The New York City Listing page demonstrates another way the pop-up dialog box can be leveraged. A common scenario in many Web applications is to display additional information when a user hovers over an item in a list. The pop-up dialog box allows the detailed information to be retrieved only when requested through Ajax. This example is shown in Figure 11. Figure 11. Sample pop-up dialog container Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 33 of 40
    • developerWorks® ibm.com/developerWorks The code for the New York City Listing page is shown in Listing 21. The key function in this sample is showCityDialog, which takes a single parameter, the zip code, for the item the user is currently hovering over. The dialog box position is set using standard CSS properties and JavaScript code. The showDialog function is then shown. When the user hovers away from the zip code, the hideDialog function is called to hide the pop-up dialog. Listing 21. NewYorkCityList.jsp <html><head> <title>New York City Listing</title> <ajax:page/> <link href="core.css" rel="stylesheet" type="text/css" /> </head> <script type="text/javascript"> function showCityDialog(zipCode) { var xPosition = 0; var yPosition = 0; if (!e) var e = window.event; if (e.pageX || e.pageY) { posx = e.pageX; yPosition = e.pageY; } else if (e.clientX || e.clientY) { xPosition = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; yPosition = e.clientY + document.body.scrollTop Update panel and popup dialog box controls Page 34 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® + document.documentElement.scrollTop; } var dialogControl = document.getElementById("cityDetailsDialog"); if (dialogControl != null) { dialogControl.style.top = yPosition; dialogControl.style.left = xPosition; } // Get selected zip code var zipCodeControl = document.getElementById("selectedZipCode"); if (zipCodeControl != null) { zipCodeControl.value = zipCode; showDialog('cityDetailsDialog'); } } </script> <body> <table cellpadding="0" cellspacing="0" width="60%"> <tbody> <% TreeMap<Integer, LocationDTO> locData = LocationDataService.getLocationData(); // Temp map to ensure only unique cities are added. HashMap tempMap = new HashMap(); // Iterate through all data looking for matching cities and add to // temporary TreeMap Set<Integer> keySet = locData.keySet(); Iterator<Integer> locIter = keySet.iterator(); while (locIter.hasNext()) { // Get current state Integer curKey = locIter.next(); LocationDTO curLocation = locData.get(curKey); String curState = curLocation.getState(); String curCity = curLocation.getCity(); String lowerCurCity = curCity.toLowerCase(); if (!tempMap.containsKey(curCity) && curState.equalsIgnoreCase("NY")) { tempMap.put(curCity, curCity); out.println("<tr>"); out.println("<td><a href='#' style='text-decoration:none;color' onMouseOver="showCityDialog('" + curLocation.getZipCode() + "')" >"); out.println(curLocation.getZipCode()); out.println("</td>"); out.println("<td>"); out.println(curLocation.getCity()); out.println("</td>"); out.println("<td>"); out.println(curLocation.getCounty()); out.println("</td>"); out.println("</tr>"); } } %> </tbody> <thead> <tr> <th colspan="3"><b>Cities</b></th></tr> <tr> <th class="subHeading"> <b>Zip Code</b></th> <th class="subHeading"> <b>City</b></th> <th class="subHeading"> <b>County</b></th> </tr> </thead> </table> <input type="hidden" id="selectedZipCode" value=""/> <ajax:popupdialog url="/ajaxcontrols3/fragments/cityDetails.jsp" id="cityDetailsDialog" width="400px" Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 35 of 40
    • developerWorks® ibm.com/developerWorks left="0" top="0" title="City Information" height="10.5em" contentheight="8.5em"> <ajax:popuparguments id="stateDialogArgs"> <ajax:popupargument name="zipCode" sourcefield="selectedZipCode"/> </ajax:popuparguments> </ajax:popupdialog> </body></html> Listing 22 shows the JSP code for the pop-up dialog content. It is reasonably clear-cut. The detailed information for the city is retrieved from the Location Data Service, and the corresponding record is displayed. Listing 22. cityDetails.jsp <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page import="com.testwebsite.dal.LocationDataService" %> <%@ page import="com.testwebsite.dto.LocationDTO" %> <%@ page import="com.testwebsite.dto.StateDTO" %> <%@ page import="java.util.Iterator" %> <%@ page import="java.util.TreeMap" %> <%@ page import="java.util.Set" %> <% TreeMap<Integer, LocationDTO> locData = LocationDataService.getLocationData(); String zipCodeStr = request.getParameter("zipCode"); Integer zipCode = new Integer(zipCodeStr); LocationDTO curLocation = locData.get(zipCode); if (curLocation != null) { out.println("<div id='cityDetails'>"); // Render zip code out.println("<div>"); out.println("<span style='font-weight:bold;color: #00628B'>Zip Code:&nbsp;</span>"); out.println("<span style='color: #00628B'>"); out.println(curLocation.getZipCode()); out.println("</span>"); out.println("</div>"); // Render city name out.println("<div>"); out.println("<span style='font-weight:bold;color: #00628B'>City:&nbsp;</span>"); out.println("<span style='color: #00628B'>"); out.println(curLocation.getCity()); out.println("</span>"); out.println("</div>"); // Render county name out.println("<div>"); out.println("<span style='font-weight:bold;color: #00628B'>County:&nbsp;</span>"); out.println("<span style='color: #00628B'>"); out.println(curLocation.getCounty()); out.println("</span>"); out.println("</div>"); // Render state out.println("<div>"); out.println("<span style='font-weight:bold;color: #00628B'>State:&nbsp;</span>"); Update panel and popup dialog box controls Page 36 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® out.println("<span style='color: #00628B'>"); out.println(curLocation.getState()); out.println("</span>"); out.println("</div>"); // Render longitude out.println("<div>"); out.println("<span style='font-weight:bold;color: #00628B'>Longitude:&nbsp;</span>"); out.println("<span style='color: #00628B'>"); out.println(curLocation.getLongitude()); out.println("</span>"); out.println("</div>"); // Render latitude out.println("<div>"); out.println("<span style='font-weight:bold;color: #00628B'>Latitude:&nbsp;</span>"); out.println("<span style='color: #00628B'>"); out.println(curLocation.getLatitude()); out.println("</span>"); out.println("</div>"); out.println("</div>"); } %> Conclusion In this article, you learned a few asynchronous communication and JSP TagLib control techniques, including how to build composite controls, how to add client-side event hooks for custom controls, and how to leverage Ajax to make Web pages more dynamic. The article built on the Ajax communication techniques described in the first two articles in this series. Ajax enables you to build Web applications that are highly dynamic, scalable, and user-friendly. By developing JSP TagLib controls, you can reduce the time to build business-line applications. You can extend these controls further to: • Add additional presentation options to the pop-up dialog control, such as positioning the pop-up dialog box (for example, centering it or positioning it relative to another control. • Add animation to the pop-up dialog and update panel controls, such as fading, slide in, and so on. • Add a loading animation (while waiting for content to be retrieved) to the pop-up dialog and update panel controls, such as an hourglass. Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 37 of 40
    • developerWorks® ibm.com/developerWorks Downloads Description Name Size Download method Source code for this article ArticleCodeSample.zip 2560KB HTTP Information about download methods Update panel and popup dialog box controls Page 38 of 40 © Copyright IBM Corporation 2009
    • ibm.com/developerWorks developerWorks® Resources Learn • See the first article in this series, "Building Ajax-enabled auto-complete and cascading drop-down controls" (developerWorks, September 2008) for information about how to build a cascading drop-down control that dynamically populates values in an HTML SELECT control, based on other form field values. • Read the second article in this series, "Building auto-populate and field validator controls" (developerWorks, November 2008) for information about how to build an Ajax-enabled auto-populate control that dynamically populates form fields based on a selected value and an Ajax-enabled field validator control that adds server side validation. • Learn more about JSON in Java, an open source library for using JSON in Java. • The World Wide Web Consortium (W3C) Working Draft 15 April 2008 contains valuable information about the proposed standard for the XMLHttpRequest Object. • Read Introducing JSON to find out what JSON is all about. • Refer to Mozilla's official documentation for the JavaScript language. Get products and technologies • The Zip Code Database Project is a free zip code database. • About.com: ZIP Code Database is another free zip code database. About the author Brian J. Stewart Brian J. Stewart is currently a principal consultant at Aqua Data Technologies, a company that he founded to focus on content management, XML technologies, and enterprise client/server and Web systems. He architects and develops enterprise solutions based on the Java Enterprise Edition (Java EE) and .NET platforms. Trademarks Java and all Java-based trademarks and logos are trademarks of Sun Microsystems, Update panel and popup dialog box controls © Copyright IBM Corporation 2009 Page 39 of 40
    • developerWorks® ibm.com/developerWorks Inc. in the United States, other countries, or both. Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both. Update panel and popup dialog box controls Page 40 of 40 © Copyright IBM Corporation 2009