Remotely get an array return value from a Java object and use the data to populate a selection list. Sounds awesome, huh? You can take existing Java objects that have methods returning Java arrays, and use those return values to populate a select list on a web page. Figure 5-2 shows the web page that we will use in the next few hacks. The page lists some bike manufacturers in a pop-up widget, a few product codes associated with those companies, and then some date/time values. This hack fills the first pop-up or select list with its values when the browser loads the page. Figure 5-2. Dynamically fill a select list with server valuesThe page imports several JavaScript files using script tags. The first four files allow the application to use DWR; the last one contains the code for our application. Here is the underlying web page code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="/parkerriver/ajaxhacks/js/hacks5_1.js"></script> <script type="text/javascript" src="/parkerriver/dwr/interface/JsBikeBean.js"></script> <script type="text/javascript" src="/parkerriver/dwr/interface/JsDate.js"></script> <script type="text/javascript" src="/parkerriver/dwr/engine.js"></script> <script type="text/javascript" src="/parkerriver/dwr/util.js"></script> <title>Bike Information</title> </head> <body> <h3>Our list of Bike Designers</h3> <form action="javascript:void%200"> <p> Bikes: <select ></select> </p> <p> <button type="button" name="selection" value="Select">Select</button> </p> </form> <h3>Product codes</h3> <div ></div> <h4>The time now</h4> <div ></div> </body> </html> To use one of these bound JavaScript objects in your code, you have to set up the server component in the way the previous hack described, then use a script tag with the following syntax: <script type="text/javascript" src="/[name-of-your-web-app]/dwr/interface/JsBikeBean.js"></script> Substitute [name-of-your-web-app] with the name of your web application, or context root in Java web parlance. In addition, every Ajax application using DWR has to import the engine.js library, using similar syntax: <script type="text/javascript" src="/[name-of-your-web-app]/dwr/engine.js"></script> util.js is optional, but it contains a lot of useful JavaScript functions (a few of which the upcoming hacks use). Getting an Array from the ServerThis hack's code populates the select list using a Java array value it receives from a server component. The component is a Java servlet that this chapter's first hack installed, and the array source is an instance of a Java object we have running on the server. The array derives from the BikeBean class's getDesignerInfo( ) method. This method returns all the keys, such as "Trek" or "Cannondale," contained in a HashMap (a Java object that represents a hash table or associative array) named bikeInfo. Here is the code for the BikeBean class: package com.parkerriver; import java.util.Map; import java.util.HashMap; import java.util.Collections; public class BikeBean { private static Map BIKE_INFO; static { BIKE_INFO = Collections.synchronizedMap(new HashMap( )); BIKE_INFO.put("Trek","0001"); BIKE_INFO.put("Orbea","0002"); BIKE_INFO.put("Guru","0003"); BIKE_INFO.put("Giant","0004"); BIKE_INFO.put("Look","0005"); BIKE_INFO.put("Specialized","0006"); BIKE_INFO.put("Cannondale","0007"); } public String[] getDesignerInfo( ){ return (String[])BIKE_INFO.keySet( ).toArray(new String[]{}); } public static Map getBikeInfo( ) { return BIKE_INFO; } } This BikeBean object is loaded into and stored in the server's memory (specifically, inside the Java Virtual Machine that the server is using). How does the JavaScript code running inside a distant user's browser get access to the Java object's methods? The XML configuration that this chapter's first hack explained bound a JavaScript name (JsBikeBean) to the BikeBean object. The DWR servlet and the engine.js file that the web page imports handle the intermediate magic that connects the browser code to the server code. Here is the JavaScript code in hacks5_1.js that gives the select list its values: window.onload=function( ){ setupSelect( ); setupMap( ); setupDates( );}; function setupSelect( ){ JsBikeBean.getDesignerInfo(populate); } function populate(list){ DWRUtil.removeAllOptions("bikes"); DWRUtil.addOptions("bikes", list); } /* CODE SNIPPED FOR: setupMap( ); setupDates( ); */ When the browser finishes loading the web page, the window.onload code calls three different functions. This hack deals with setupSelect( ); upcoming hacks feature the other two functions. setupSelect( ) remotely calls (via JsBikeBean) the getdesignerInfo( ) method. This method returns an array of strings that represent the names of some bike manufacturers. These names will end up as the labels for a select list (see Figure 5-2).
DWR uses a \xd4 callback design pattern as one of the options for initiating its remote calls. When the code calls Java methods from JavaScript, an additional parameter representing a callback function is added at the end of the method's parameter list (or is the only parameter, for methods that are not defined in Java as having any parameters). The only parameter to getdesignerInfo( ) is the name of a function that will handle the Java method's return value (an array). The callback function's name is populate( ), and its parameter is the returned array, here represented by the list variable. This code can also pass in a function literal instead of a function name to geTDesignerInfo( ), as in: JsBikeBean.getDesignerInfo( function(list){ DWRUtil.removeAllOptions("bikes"); DWRUtil.addOptions("bikes", list); } ); The code is in essence saying, "I'm calling this Java method remotely, and here is the JavaScript function that will handle the return value."
Eccentric UtilityThe rest of the code takes this array of bike-maker names and dynamically fills a select list with them, using a couple of DWR's utility functions. The web page made these functions available by importing util.js using a script tag, as this hack explained earlier. DWRUtil.removeAllOptions( ) takes the id of a select list as a parameter, then removes all the options (a logical first step before you change the options in the list). The web page's select list looks like: <select ></select> DWRUtil.addOptions( ), on the other hand, takes the id of a select list as its first parameter and an array as its second parameter. The array members then become the options or labels in the select list. You might recall that the list variable contains the array returned by the Java method to which our JavaScript code is bound. Again, our code looks like: DWRUtil.addOptions("bikes", list); If you are a Java web developer, this is cool stuff. The next hack populates a select list from a Java Map type such as java.util.HashMap. |