Skip to main content

Integrate XForms with the Google Web Toolkit, Part 1: Introducing GWT's JavaScript Native Interface

Create a Web application for rock star hopefuls

Michael Galpin (mike.sr@gmail.com), Developer, Ludi Labs
Michael Galpin has been developing Java software professionally since 1998. He currently works at Ludi Labs, a start-up in Mountain View, Calif. He holds a degree in mathematics from the California Institute of Technology.

Summary:  This four-part series demonstrates how to use the Google Web Toolkit (GWT) and XForms together to create a dynamic Web application. Part 1 starts with a bottom-up approach to the problem of using GWT and XForms together. It takes a look at some of the underpinnings of each technology, examining the common ground between them that will allow for their peaceful coexistence. This will lay the foundation for developing a Web application that uses both GWT and XForms together.

View more content in this series

Date:  18 Sep 2007
Level:  Intermediate
Activity:  1761 views
Comments:  

Introduction

The Google Web Tookit (GWT) has become a very popular way to develop Ajax applications. It allows Java developers to rapidly create Ajax applications by leveraging their knowledge of Java™ technology without requiring any knowledge of JavaScript. XForms represents an evolution in the HTML standard, and allows for simple constructs to create complex, dynamic behavior. Both GWT and XForms are powerful enough to provide complete solutions to many problems. So what about using them together? That's exactly what this series is going to show.

In this series, you'll develop a simple Web application for managing rock stars and their albums. You'll use both GWT and XForms, and by the end you'll be mixing these two technologies interchangeably. For Part 1, you'll use some simple examples to demonstrate the technologies. For GWT in particular, you'll use its KitchenSink sample. This sample is used to showcase all of its numerous UI widgets.


Prerequisites

This article uses GWT version 1.4 and the Mozilla XForms plugin 0.8 (see Resources for download links). The Mozilla XForms plugin works with any Mozilla-based Web browser, such as Firefox and Seamonkey. GWT requires knowledge of Java technology, and Web technologies such as HTML and CSS. This article makes heavy use of JavaScript as well. XForms uses the Model-View-Control paradigm, so familiarity with that is helpful. Prior exposure to XForms and GWT is helpful, of course, but is not necessary.


XForms

If you're creating Web applications, you're probably creating Ajax-enabled Web applications. There are a lot of Ajax patterns that you've probably encountered, such as being able to add or edit data asynchronously. You might be surprised to know that many of these patterns were thought of before anybody had ever uttered the term Ajax. Many of the common things you do with Ajax can be done with XForms.

XForms is a standards-based technology that will be central in the next generation of the HTML specification. The key to XForms is separating data from the physical view of the data. Sound like a familiar concept? With the data separated, it can be viewed in any HTML-way you can imagine. It can also be bound to form elements to allow for a seamless way to enter data and to edit existing data.

Ajax is used to solve many of these same problems. In Ajax, you want to keep data and presentation (HTML) separated. Often you wind up creating JavaScript objects to represent the data. XForms provides a more standardized approach to this. It keeps instance data as XML. Let's take a look at an example.


XML instance data

XForms uses the familiar Model-View-Controller paradigm. Therefore, the data behind an XForm is contained in an XForm-model. An example of one is shown in Listing 1.


Listing 1. Sample XForms model
                
        <xf:model id="my-model" xmlns="http://www.w3.org/1999/xhtml" 
		xmlns:xf="http://www.w3.org/2002/xforms">
            <xf:instance id="my-data" src="my-data.xml" xmlns=""/>
            <xf:bind calculate="sum(../Item/Amount)" nodeset="/Data/Total"/>
            <xf:submission action="my-data.xml" id="update-from-local-file" 
			instance="my-data" method="get" replace="instance"/>
            <xf:submission action="my-data.xml" id="view-xml-instance" 
                 method="get"/>
            <xf:submission action="my-data.xml" id="saveToServer" 
                 method="put"/>
        </xf:model>

There are several things you should notice here. The first is the XForms-instance that is contained in the XForms-model. The instance is the actual data that this model represents. You can provide a source for the instance. This is very similar to reference other resources like JavaScript and CSS. If you provide a source attribute, then a separate HTTP request will be made by the browser to load the data. Alternatively, you can inline the instance data. Also notice that both the model and the instance have IDs. This is the key to exposing them to other technologies, as you'll see later.

Finally, notice the the various XForm-submission declarations. The actions listed here are similar to the actions you would see on a basic HTML form. They are URLs that will have form data submitted to them. Notice the method attribute. Again, this is just like the method attribute you would see on an HTML form. It is specifying what kind of HTTP request will be made for the submission. This is all part of the mode. Now look at a view in XForms.


XForms view

With a model declared, you can easily create views from the data encapsulated by the model. XForms contains numerous common controls for working with model instance data. Each control can reference data from the model's instance data. The instance data is in an XML format, so we can easily navigate and reference it arbitrarily using XPath. XForms supports the full XPath 2.0 specification. Let's take a look at a few examples.

The simplest thing you can do with model data is to simply echo it back to the browser. This can be done using the output control, as shown in Listing 2.


Listing 2. XForms output
                
<xhtml:div id="sum">
  <xf:output class="item-amount" ref="/Data/Total" 
  xmlns="http://www.w3.org/1999/xhtml">
  </xf:output>
</xhtml:div>

The ref attribute is simply an XPath expression. It is evaluated against the instance data of our model. Notice how we can mix XHTML expressions, such as the div or the CSS class attribute on the output control, with XForms controls. This is not some hack; it is a subtle reminder that XForms is an integral part of the future of HTML.

XForms is designed for interaction, not just displaying data. So, of course, there are controls for editing data. Take a look at Listing 3.


Listing 3. Form controls in XForms
                
<xf:input class="item-amount" ref="Amount" xmlns="http://www.w3.org/1999/xhtml">
    <xf:label>Amount</xf:label>
</xf:input>
<xf:submit submission="saveToServer" xmlns="http://www.w3.org/1999/xhtml">
    <xf:label>Save</xf:label>
</xf:submit>

Listing 3 shows a simple example that creates an input field with a label and a Submit button. Everything here is bound back to the model. The input field is bound to instance data. If you think in terms of HTML elements, the input field will be pre-filled with the bound value from the data model.

The submit control will, of course, become an HTML Submit button. Once again it is bound to the model. It references a submission element of our model. That element specifies a form action. Thus, our submit control will create an HTML Submit button, and clicking on that button will cause an HTTP post to the URL in the action of the model's submission specification. And what exactly will be posted to the URL? The XML data, of course. The data is bound to the input control, so if the user enters a new value it will be propagated to the model automatically before the HTTP POST is made back to the server.

Now, normally you associate the submission of an HTML form to the navigation to the action URL of that POST. This is the prototypical "Web 1.0" experience, but luckily it has no place in XForms. In an XForms application, the submission is just data being posted to the server. It has nothing to do with navigation. That's part of the clean separation between the model (the data and the operation on the data, such as submitting it to a server) and the view.

Time for a reality check. Doesn't all this sound very typical of an Ajax application? There's probably been countless lines of JavaScript written to bind data to a form, catch a form submission, asynchronously send data back to the server, and then repaint the portion of the view that is displaying the data. This is all baked into an XForms implementation. You can accomplish a lot just inside XForms, but it's definitely not a walled-garden technology. It provides straightforward hooks into bread-and-butter client-side technologies: the HTML DOM and JavaScript.


XForms and JavaScript

With XForms, the data behind your application can be represented as a model and bound to various views. It's the kind of approach that you see all the time when developing server-side code, and it is becoming more and more common on the client side because of Ajax. XForms is a client-side technology, so it should come as no surprise that it is easily accessible using the native language of the browser: JavaScript.

The powerful world of XForms is completely accessible to JavaScript executing on the same page. In fact, all the XForms elements, both models and views, are part of the HTML DOM that is created. This is all per next-generation HTML specification. So you can access them just like you would access an HTML div, using the familiar getElementById() paradigm. Take a look at Listing 4 for an example of accessing an XForms model using JavaScript.


Listing 4. XForms model exposed in JavaScript
                
var model = document.getElementById("my-model");
var instance = model.getInstanceDocument("my-data");
var dataElement = instance.getElementsByTagName("Data")[0];
var itemElements = dataElement.getElementsByTagName("Item");
var cnt = itemElements.length;
var descripElement = itemElements[0].getElementsByTagName("Description")[0];
descripElement.childNodes[0].nodeValue = "";
var amtElement = itemElements[0].getElementsByTagName("Amount")[0];
amtElement.childNodes[0].nodeValue = "0";
model.rebuild();
model.recalculate();
model.refresh();

As you see in Listing 4, you can access an XForms model as part of the DOM. What you get is a first class JavaScript object. Notice it has specialized methods, like the getInstanceDocument(). This provides access to the XML instance data. This is a real XML DOM object, so you can navigate and modify it just like you would with any other XML DOM object.


GWT

GWT was introduced at JavaOne in 2006. Since then it has become very popular among Java technology developers. It lets Java technology developers rapidly produce Ajax-enabled Web applications using only their Java technology skills plus some basic knowledge of HTML and CSS. It's an obvious tool for rapid prototyping, but has proven its capabilities in production scenarios. For example, Google's own Mashup Editor, an online integrated development environment for scripting together Web applications and Web APIs, was built using GWT.

Much of the magic behind GWT comes from its ability to compile Java code into JavaScript. This lets Java technology developers use familiar event-driven programming tied directly into server-side models. Most Java developers are just happy to not have to write any JavaScript themselves. They get the benefits of a strongly typed language and are able to use standard debugging tools (like Eclipse) to debug their Ajax-enabled Web applications.

If you don't mind dealing with JavaScript, then GWT can open up even more possibilities. Most importantly, JavaScript is the key into and out of the GWT world. If you want things not written with GWT to interact with things written with GWT, or vice versa, then JavaScript is the way to go.

Fortunately, GWT was built to play nice with other technologies. It opens up its hidden JavaScript world by allowing developers to code in JavaScript directly from within a GWT class. That's right, you can write JavaScript side-by-side with your Java class by using GWT's JavaScript Native Interface (JSNI).


JSNI

If you read the GWT documentation (see Resources), it indicates several uses for JSNI. You can implement a client-side method completely using JSNI. You can use it to wrap existing JavaScript, which is very useful for migrating an existing application to GWT. You can access client-side Java code (which gets compiled to JavaScript anyway) using JSNI and vice versa. The key here is that anything you can do in JavaScript you can do using GWT using JSNI, without needing a Java representation. Let's take a look at some JSNI examples.

JSNI example

To examine what can be done with JSNI, let's start with one of the samples that ship with GWT. You'll take the KitchenSink sample. It's a showcase for the UI elements included with GWT. It's also useful for JSNI experimentation because it is all client-side, with no communication to the server.

You'll define a Java method that will be implemented in JavaScript. You'll start with the simplest thing you can do in JavaScript, alerting the classic "Hello world." Our JSNI version of Hello world is shown in Listing 5.


Listing 5. Hello World JSNI
                
private native void blastName() /*-{
	alert("Hello world");
}-*/;

To use your JSNI method, you'll add it to the KitchenSink class, and then'll have it execute the method at start-up by calling it from the Java method showInfo() as shown in Listing 6.


Listing 6. Calling JSNI from Java
                
private void showInfo() {
  show(list.find("Intro"), false);
  blastName(); // added JSNI method
}

Notice that GWT lets you treat your native method just like it was written in the Java platform. It's very clean and simple. Compile and run in hosted mode, and you should see the interface shown in Figure 1.


Figure 1. KitchenSink
KitchenSink

Simple enough. Now let's take the complexity up a level and share data between Java and JavaScript.

Accessing Java variables from JSNI

In order for JSNI to be useful, you need to be able to share data between code written in Java and native JavaScript code. This will let you take advantage of GWT while leveraging the power of JavaScript at the same time. Take a look at Listing 7 to see how an improved version of our JSNI "Hello world."


Listing 7. JSNI and Java variables
                
public class KitchenSink implements EntryPoint, HistoryListener {

  private static final Sink.Images images = (Sink.Images) GWT.create(Sink.Images.class);

  protected SinkList list = new SinkList(images);
  private SinkInfo curInfo;
  private Sink curSink;
  private HTML description = new HTML();
  private VerticalPanel panel = new VerticalPanel();
  // new variable to be accessed in JSNI
  private String myVar = "Hello variables"; 

You define the myVar variable in Java, but you'll be able to access it within your JSNI method, as shown in Listing 8.


Listing 8. Accessing the myVar variable within your JNSI method
                
private native void blastName() /*-{
  var str = 
   this.@com.google.gwt.sample.kitchensink.client.KitchenSink::myVar;
  alert(str);
}-*/;

Now compile the new KitchenSink, click on the button as before, and you should see the interface shown in Figure 2.


Figure 2. Hello variables
hello variables

Now you can easily pass data back and forth between Java and native JavaScript code. You have all the building blocks you need to glue together GWT and any other technology that is exposed through JavaScript, such as XForms.


Summary

XForms and GWT both provide powerful abstractions and tools for modern Ajax applications. They also both provide hooks into "low-level" JavaScript. This allows not only for JavaScript to be used to augment the rich functionality already offered by each technology, but also provides a common ground for combining the technologies with other technologies -- like each other. You now know the blueprint for integrating XForms and GWT. In Part 2 you'll follow the blueprint and start mixing XForms and GWT together.


Resources

Learn

Get products and technologies

Discuss

About the author

Michael Galpin has been developing Java software professionally since 1998. He currently works at Ludi Labs, a start-up in Mountain View, Calif. He holds a degree in mathematics from the California Institute of Technology.

Comments



Trademarks

static.content.url=/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Java technology
ArticleID=255601
ArticleTitle=Integrate XForms with the Google Web Toolkit, Part 1: Introducing GWT's JavaScript Native Interface
publish-date=09182007
author1-email=mike.sr@gmail.com
author1-email-cc=ruterbo@us.ibm.com