Contents


GMaps4JSF in the JSF 2.0 Ajax world

Comments

GMaps4JSF aims to integrate Google maps with JavaServer Faces (JSF) and lets JSF developers construct complex street view panoramas and maps with just a few JSF tags. You can also easily attach different components (markers, information texts, controls, ground overlays, polygons, polylines) to the map. GMaps4JSF also allows attaching different server-side and client-side events to components without writing JavaScript code to bind the event with the component. You only need to write JavaScript code if you want to implement the components' client-side event handlers.

Ajax is a primary technology in any modern Web application. Although Ajax was not introducted in the earlier versions of JavaServer Faces, it was provided by many JSF component libraries like Apache MyFaces Trinidad, JBoss RichFaces, ICEFaces, and others. Now the good news is that Ajax is supported natively in JSF 2.0 implementations.

In this article, I explain how to configure GMaps4JSF inside your JSF 2.0 application and give a brief introduction to JSF 2.0 Ajax. Finally, I'll illustrate a simple mashup application that uses both GMaps4JSF and JSF 2.0 Ajax.

Configuring GMaps4JSF with your JSF 2.0 application

First, let's configure GMaps4JSF with your JSF 2.0 application. To do this:

Sign up for the Google Maps API (see Related topics). You will need to accept the usage agreement and register the site that you are using for your application. In return, Google provides a key specific for your application.

Figure 1. Sign up for the Google Maps API
Screen shot of the agreement screen for Google Maps API
Screen shot of the agreement screen for Google Maps API

To use the Google Maps API you must include the Google Maps API's script in your page. Listing 1 shows the Google Maps API's script that must be included in your <h:head> tag. You can find full details of how to use this code in the Google Maps API documentation (see Related topics).

Listing 1. Header codes to include the Google Maps API
<head> 
     <script 
          src="//maps.google.com/maps?file=api&amp;v=2&amp";
          key="gen_website_key"
          type="text/javascript">
     </script>
</head>

In the code in Listing 1 you will need to replace the phrase "gen_website_key" with they key provided to you during your registration. Figure 2 shows an example of this key on the Google Maps Web site and how it fits into your code.

Figure 2. Put in your page <h:head> tag the Google Maps APIs script include
The code sample from Listing 1 is shown with a partial screen shot of the Google Maps API page.  gen_website_key in the code is circled with red and an arrow points to the lengthy key string on the Google Maps web page.
The code sample from Listing 1 is shown with a partial screen shot of the Google Maps API page. gen_website_key in the code is circled with red and an arrow points to the lengthy key string on the Google Maps web page.

Next you will need the JAR file for GMaps4JSF. Download the latest version from the project Web site (see Related topics). Figure 3 shows the project page with the downloads on the right.

Figure 3. Download the latest library snapshot jar
 Screen shot of the GMaps4JSF home page with the download files in the right-hand menu circled with red.
Screen shot of the GMaps4JSF home page with the download files in the right-hand menu circled with red.

Place the downloaded JAR file in the WEB-INF/lib directory of your JSF 2.0 Web application.

Finally, add the library declaration shown in Listing 2 to your XHTML page in order to use GMaps4JSF components.

Listing 2. Library declaration for GMaps4JSF components
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:m="http://code.google.com/p/gmaps4jsf/">

Using JSF 2.0 Ajax

Ajax is now a part of most of modern Web 2.0 applications. Writing "Ajaxified" applications from scratch can be a headache. On the client side, you must write a JavaScript client to send the Ajax requests and to receive the Ajax responses. On the server side, the application must prepare a response that can be understood by the client. In addition to all of these complexities, the JavaScript client code should be cross-browser compatible. JSF 2.0 Ajax does all of this for you.

In JSF 2.0, there are two ways of adding Ajax support to the JSF 2.0 applications. You can use the JavaScript library provided by the framework or the new <f:ajax> tag to declare Ajax support for the JSF components.

The <f:ajax> tag enables the creation of Ajax requests that are attached to the JSF components' actions. For example, if the <f:ajax> tag is put inside an action source component such as <h:commandButton>, it allows sending Ajax requests upon the "onclick" action of this component. If the tag is put inside a value holder component like <h:selectOneListbox>, it allows sending the Ajax requests upon the "onchange" action of the component.

Listing 3 shows how easy it is to use JSF 2.0 Ajax. In this example, the <f:ajax> tag is put inside the <h:inputText> component. So when the user enters a value in the txtName input text and tabs out, the txtEnteredNameoutputText will be updated with the entered value.

Listing 3. The JSF 2.0 <f:ajax> tag usage example
<h:panelGrid columns="2">
    <h:outputText value="Enter your name:"/>
    <h:inputText id="txtName" value="#{person.name}">
        <f:ajax render="txtEnteredName"/>
    </h:inputText>
    <h:outputText value="You entered: "/>
    <h:outputText id="txtEnteredName" value="#{person.name}"/>
</h:panelGrid>

The Countries application

Now, let's move to the Countries application, which uses both GMaps4JSF with JSF 2.0 Ajax. In this application, you have a master dataTable and a detailed map. Each row of the dataTable represents a country, and when the user clicks on a row the country location is displayed in the detailed map. Figure 4 shows a screenshot of the Countries application in action.

Figure 4. The Countries application screenshot
A screenshot of the Countries application shows a list of various countries in the top of the window with a google country map below.  There is a marker in Egypt with a description window giving details about the country.
A screenshot of the Countries application shows a list of various countries in the top of the window with a google country map below. There is a marker in Egypt with a description window giving details about the country.

Listing 4 shows a partial listing of the mashups.xhtml code, the Countries application XHTML page. I put the <f:param> tags inside the <f:ajax> tag so I can send the parameters when the table row "View Country Location" commandLink is clicked. In the render attribute of the <f:ajax> tag, the ID of the panel group containing the map component is specified "mapGroup". When the response comes from the server, the map will be updated with the new information #{param.selectedCountry}, #{param.selectedCapital}, and #{param.continent}.

Listing 4. (mashups.xhtml) the Countries application XHTML page
<!-- some code here -->
<h:dataTable value="#{countryTable.data}" var="row">
   <!-- some code here -->
   <h:column>
    <f:facet name="header">
      <h:outputText value="Action"/>
    </f:facet>
	<h:commandLink id="cmdShow" value="View Country Location"> 
       <f:ajax render="mapGroup"> 
          <f:param name="selectedCapital" value="#{row.capital}"/> 
          <f:param name="continent" value="#{row.continent}"/> 
          <f:param name="selectedCountry" value="#{row.id}"/> 
       </f:ajax> 
    </h:commandLink> 
   </h:column>
</h:dataTable>   
<!-- some code here -->
 <h:panelGroup id="mapGroup"> 
    <m:map id="map" width="460px" height="460px" type="G_NORMAL_MAP" 
            address="#{param.selectedCountry}" 
      rendered="#{param.selectedCountry ne null}" renderOnWindowLoad="false" zoom="4"> 
    <m:marker id="marker"/> 
    <m:htmlInformationWindow id="window" 
       htmlText="Country: #{param.selectedCapital} <br/> Continent: #{param.continent}"/> 
    </m:map> 
    <!-- some code here --> 
 </h:panelGroup>

Listing 5 shows the Countries application sample managed bean. Note that you can get this managed bean data from a database or a Web service, but for the case of my demonstration it just holds static information about the different countries.

Listing 5. Countries application sample managed bean
@ManagedBean(name="countryTable")
@RequestScoped
public class CountryTableModel {
	private static List<Country> data = new ArrayList<Country>();
	static {
		data.add(new Country("Egypt", 
		                     "Cairo, Egypt", 
		                     "Africa"));
		data.add(new Country("Germany", 
		                     "Berlin, Germany", 
		                     "Europe"));
		data.add(new Country("Austria", 
		                     "Vienna, Austria", 
		                     "Europe"));
		data.add(new Country("US" , 
		                     "Washington, USA", 
		                     "North America"));
		data.add(new Country("China" , 
		                     "Beijing, China", 
		                     "Asia"));
		data.add(new Country("Brazil" , 
		                     "Brazilia, Brazil", 
		                     "South America"));		
	}

	public List<Country> getData() {
		return data;
	}

	public void setData(List<Country> data) {
		this.data = data;
	}	
}

Conclusion

In this article, you saw how JSF 2.0 simplifies building "Ajaxified" applications. You also saw how it is easy to construct Google maps, and attach different markers, notes, and controls to them using GMaps4JSF. I explained how simple it is to use GMaps4JSF in JSF 2.0 applications, and now you, as a JSF 2.0 developer, can easily build Web 2.0 mashups inside JSF 2.0 applications without having to write JavaScript code.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Java development
ArticleID=422291
ArticleTitle=GMaps4JSF in the JSF 2.0 Ajax world
publish-date=08252009