New Technologies for Ajax and Web Application Development: Project jMaki

   
By Jennifer Ball, November 2006  

Articles Index

Project jMaki gives you a simple way to include Ajax-enabled widgets in your web applications. ( Ajax is a technology that includes but is not limited to Asynchronous JavaScript and XML.) The jMaki technology does this by allowing you to wrap widgets in a JavaServer Pages (JSP) technology tag handler or a JavaServer Faces component. By wrapping a widget in this way, you can encapsulate it in a modular unit and also give it the benefits of any JSP tag handler or JavaServer Faces component.

The primary benefit is that you can easily include wrapped widgets into any JSP or JavaServer Faces technology-based application in the same way that you would include any other custom JSP tag or JavaServer Faces component tag. By wrapping the widget in a JavaServer Faces component, you can give the widget all the functionality of any other JavaServer Faces component, including access to data conversion and validation capabilities. What's more, jMaki does all the work of creating the custom tag handler or custom JavaServer Faces component for you. You won't need to write another tag handler, component class, or component renderer by hand.

What makes the technology so flexible is that jMaki does not limit you to any particular kind of widget from any particular vendor. You can grab one of the widgets from Dojo, Script.aculo.us, or wherever you like and create a jMaki wrapper for it with minimal effort. With so many cool widgets available out there, this is a huge benefit: You don't have to reinvent the wheel. Still, if you don't find a widget that meets your needs, you can create one using jMaki and wrap it in a JSP technology tag handler or a JavaServer Faces component, as you would with any other widget.

The following sections give you a short introduction to using jMaki. First, you'll see how easy it is to include a jMaki component in a page. After that, you'll find out what's included in a typical jMaki widget. Then you'll learn how to wrap the components of a prebuilt, third-party widget and use it in a page. Finally, you will see how to create your own jMaki widget from scratch and add it to your application.

Using a jMaki Widget

The modular nature of a jMaki widget makes life easier for page authors. You don't need to know any JavaScript technology to use the widgets, and you can reuse them in multiple pages with minimal effort.

Once you download and unpack the jMaki zip file, adding jMaki widgets to applications is quite easy. It just takes some simple steps:

  1. Find the jMaki.war file in your unpacked jMaki zip file.
  2. Copy the jmaki.js file from the resources directory of jMaki.war to your application's web directory.
  3. Copy the ajax-wrapper-comp.jar file from the WEB-INF/lib directory of jMaki.war to your application's web/WEB-INF/lib directory.
  4. Copy the widget's resources to your application's web/resources directory. For example, the Dojo inline edit widget is located in the resources/dojo/inlineedit directory of jMaki.war.
  5. Add any scripts supplied by the third party that produced the original widget to the web/resources/libs directory. For example, the Dojo scripts are located in the /resources/libs/dojo directory of the jMaki distribution.

For details on how to get started, see one of the two tutorials listed in the For More Information section.

Once you perform the preceding steps, you can decide whether to use a widget in a JSP technology tag handler or a JavaServer Faces component by adding one of the two tag libraries that come with Project jMaki:

<%@ taglib prefix="a" uri="#" %>
                  

<%@ taglib prefix="a" uri="#" %>
                
 

After adding one of these to the page, include the widget using the ajax custom tag:

<a:ajax name="dojo.inlineedit"/>
 

The name attribute refers to the widget's name. In this case, it specifies the inline edit widget, a jMaki widget wrapped from the Dojo toolkit's InlineEditBox widget. This is one of the widgets included in the jMaki distribution. The inline edit widget allows users to edit a text string by clicking on it, editing the text string, and clicking a button, as shown in Figure 1.

 

There are other attributes besides the name attribute on the ajax tag. Different widgets might require you to use different attributes. See Using jMaki Widgets for a description of the other attributes.

The next section describes what a typical jMaki widget includes. After that, you'll find out how the jMaki development team wrapped the inline edit widget using jMaki.

Components of a Widget Wrapped With jMaki

A jMaki widget is composed of the following simple pieces:

  • A component.js file: A JavaScript technology file that contains all the client-side logic that handles any user-initiated events and interacts with the Ajax mechanism.
  • A component.htm file: An HTML file that the rendering mechanism will use as a template to render the widgets to the client.
  • A component.css file: A CSS stylesheet that controls the appearance of the widget, such as the style of fonts it might use. This file is optional.

As described in the previous section, when you package the widget in your web application, you must also add the following files:

  • The jmaki.js file
  • The ajax-wrapper-comp.jar file
  • Any extra script libraries that the widget requires

Figure 2 shows where the basic resources of a Dojo jMaki widget are located in a web application.

 

A widget might also require a service component, which can be a servlet, a JSP technology page, or a managed bean. This component has access to the request parameters and can perform some extra processing when the widget is activated. For example, if you have a widget that allows you to add items to a list, the service performs the logic that initializes the List object and invokes its add method with the new item to add.

The next section describes how to wrap these components into a jMaki widget.

Wrapping a Widget With jMaki

Before you get started learning how to wrap a prebuilt widget, you should know that you might not even need to do so. Project jMaki comes with many common widgets already wrapped, including several from the Dojo toolkit and Script.aculo.us. Just follow the simple instructions in the section Using a jMaki Widget to use those existing widgets.

To show you how easy it is to wrap a widget with jMaki, this article will now describe how the jMaki development team wrapped the Dojo InlineEditBox widget, included in the jMaki.war file as the inline editor jMaki widget. First, the jMaki development team downloaded the widget code from the Dojo toolkit web site.  The code for all the Dojo widgets is already available in the jMaki distribution.

To wrap the Dojo inline editor widget with jMaki, the jMaki development team followed these steps:

  1. Set up the widget's directory structure.
  2. Create three files:
    • component.js
    • component.htm
    • component.css

The first step is to create the inlineedit directory for the widget. What you name the directory is significant because this is how the jMaki wrapper and rendering mechanism will refer to the widget. You can find this directory in the resources/dojo directory of your jMaki.war file. Inside the inlineedit directory, add the three templating files: component.htm, component.js, and component.css.

The component.htm file is the HTML template file in which you can customize how the widget will be used on the page. In this case, the component.htm file includes the following information:

<h1 id="${uuid}" dojoType="inlineEditBox">
                  

  Edit me - I will trigger a custom onSave Handler</h1>
                
 

These lines tell the jMaki rendering mechanism to render a Dojo InlineEditBox widget with a heading 1 and give it a generated ID. Because you can put any number of these widgets on a page, jMaki will replace the parameterized ID ${uuid} with a generated ID, which it constructs with the name of the widget, concatenated with an integer representing the instance of the widget in the page.

 

The component.js file includes the JavaScript technology code that will import the code that came with the prebuilt widget and bootstrap it so that it works with your application:

dojo.require("dojo.widget.*");
dojo.require("dojo.widget.InlineEditBox");
dojo.require("dojo.event.*");

var w = dojo.widget.createWidget(widget.uuid);

w.getValue = function() {
    return w.textValue;
}

// Save the state.
if (typeof widget.valueCallback != 'undefined') {
    w.onSave = function(newValue, oldValue) {
        var url = widget.valueCallback;
        dojo.io.bind({
            url: url + "?cmd=update",
            method: "post",
            content: { "value" : newValue },
            load: function (type, data, evt) {
            }
        });
    }
}
w.saveState = w.onSave;
jmaki.attributes.put(widget.uuid, w);
 

As this code shows, you must import the appropriate Dojo packages and call the createWidget function to create the widget. Then you provide a function that gets the widget's current value, which is whatever the user entered into the text field.

The next several lines of code provide support for saving the state of the widget to a managed bean, for those who want to use a widget as a JavaServer Faces component. These lines will be essentially the same for any Dojo widget wrapped as a jMaki widget.

Finally, you add the widget ID to a special properties map using the jmaki.attributes.put function. This saves the widget for later use, in case you have components that need to interact with each other.

At this point, you have a jMaki widget. Now you can decide whether to wrap this widget in a JSP technology tag handler or a JavaServer Faces component by using one of the two tag libraries that come with Project jMaki, as shown in the section Using a jMaki Widget.

After adding one of these to the page, you can include the widget by using the ajax custom tag:

<a:ajax type="dojo" 
name="dojo.inlineedit"/>
 

The name attribute refers to the name of the directory in which you created the widget.

Creating a New jMaki Widget

Before you begin creating a new widget, browse through the widgets included with jMaki to see whether one of those fits your needs. If you don't find what you need there, check out Dojo and other widget repositories to see whether you can use one from there and wrap it with jMaki.

The process of creating a brand-new jMaki widget is almost the same as the process of wrapping an existing widget, except that you must provide the JavaScript technology code that implements the widget. Here are the steps:

  1. Create a new directory for the widget.
  2. Create the component.htm file.
  3. Create the component.css file.
  4. Create the component.js file.
  5. Create a separate service in the form of a JSP technology page or JavaServer Faces technology managed bean to perform any necessary logic other than that used to handle Ajax requests.
  6. Include the necessary jMaki bootstrap JavaScript technology file and tag libraries.
  7. Include the widget in a page.

The list widget, which is part of the jMaki distribution, was created from scratch -- that is, it is not just a wrapper around a pre-existing widget. This widget allows the user to add items to a list and display the list on the page. It also allows the user to click an item in the list to remove it. Figure 3 shows a screen capture of a page using the list widget.

 

Let's take a look at the different pieces of the list widget to get a sense of how you can create new jMaki widgets. First, go to the widgets/list directory of the jMaki distribution. In the src/resources directory, you'll find the component.js, component.htm, and component.css files.

The component.htm File

The component.htm file includes the following:

<div id="${uuid}" class="listContainer">
                  

<form onsubmit="jmaki.attributes.get('${uuid}').submitData();
                  

 return false;">
                  

 <input id="${uuid}_entryField" type="text" size="20"
                  

 value="Enter new Value">
                  

 <input type="button"
                  

 onclick="jmaki.attributes.get('${uuid}').submitData();
                  

             return false;" value="Add to List">
                  

</form>
                  

                   

<div id="${uuid}_list" class="listDiv"></div>
                  

</div>
                
 

Notice that there are two div tags, one inside the other. A JavaScript technology function looks for a tag in a page by using the unique IDs of div tags. The outer div tag wraps the form component, which includes the field in which you enter an item, the button to add the item to the list, and the inner div tag. The inner div tag identifies the component that displays the list on the page.

When the user clicks the button, jMaki gets the ID of the entire list widget and invokes the widget's submitData method, defined in the component.js file. After the application displays the list, the user can remove an item from the list by clicking on the item.

The component.css File

The component.css file defines a few simple styles that help give feedback to the user. For example, the application must indicate to the user that clicking on an item in the list will remove it. When the user passes the mouses over an item, the following style is applied to it:

.over {
                  

 color: white;
                  

 height:25;
                  

 font-size:18px;
                  

 font-weight: bold;
                  

 font-family: Arial;
                  

 background: blue;
                  

 cursor: pointer;
                  

}
                
 

As you can see, at the mouseover event, the background changes to blue, the text changes to white, and the cursor turns into a pointer, indicating that clicking on the item will have an effect. You'll see how this style is used in a later discussion about the service listService.jsp, which interacts with component.js file to manipulate the contents of the list.

The Interaction of the component.js File and the listService.jsp File

The component.js file contains the mostly boilerplate code you've seen before to implement the Ajax mechanism. It contains two functions: submitData and removeItem. These functions interact with the listService.jsp service. This service does the work of adding an item to the list or removing an item from the list using common java.awt.List operations. In this section, you will see how the component.js and listService.jsp files work together to manipulate the list's contents.

Here are the submitData and removeItem functions from the component.js file:

this.submitData = function() {
                  

        var list = document.getElementById(uuid + "_list");
                  

        var req = getXHR(service);
                  

        req.onreadystatechange = function() {
                  

            if (req.readyState == 4) {
                  

                if (req.status == 200) {
                  

                    list.innerHTML = req.responseText;
                  

                }
                  

            }
                  

        };
                  

        req.open("POST", service, true);
                  

        var entryField = document.getElementById(uuid + "_entryField");
                  

        req.setRequestHeader("Content-Type",
                  

             "application/x-www-form-urlencoded");
                  

        req.send("command=add&entry=" + entryField.value
                  

                + "&uuid=" + uuid);
                  

    }
                  

                   

this.removeItem = function(index) {
                  

        var list = document.getElementById(uuid + "_list");
                  

        var req = getXHR(service);
                  

        req.onreadystatechange = function() {
                  

            if (req.readyState == 4) {
                  

                if (req.status == 200) {
                  

                    list.innerHTML = req.responseText;
                  

                }
                  

            }
                  

        };
                  

        req.open("POST", service, true);
                  

        req.setRequestHeader("Content-Type",
                  

           "application/x-www-form-urlencoded");
                  

        req.send("command=remove&index=" + index  + "&uuid=" + uuid);
                  

}
                
 

This submitData function does the following:

  • Passes the listService.jsp service to the XMLHttpRequest object
  • Gets the list element and the entryField element from the HTML DOM
  • Gets the value that the user entered into the entryField
  • Passes to the service these three items:
  •     - The value
    - The list
    - The command to add the value to the list
removeItem
  • Passes the listService.jsp service to the XMLHttpRequest object
  • Gets the list widget from the HTML DOM
  • Passes to the service these three items:
  •     - The list
    - The index of the item to remove
    - The command to remove the item from the list
 

The listService.jsp service receives the ID of the list widget and the command -- add or remove -- from the request parameters. When the service renders the list, it renders the following div tag to the page for each item in the list:

<div class=\"plain\" onmouseover=\"this.className ='over';\"
                  

    onmouseout=\"this.className ='plain';\"
                  

    onclick=\"jmaki.attributes.get('" + uuid + "').
                  

            removeItem('" + counter++ + "')\">"
                  

             + it.next() + "</div>
                
 

This div tag contains some script that allows the user to select an item in the list to remove it. This action invokes the removeItem method in component.js, which in turn will send to the service the remove command, the widget ID, and the index of the item to be removed.

Notice that the service in this case is a JSP technology page. You can implement the service code in a different kind of component, such as a servlet or a JavaServer Faces technology managed bean.

Packaging and Using the List Widget

Now that you have created all the files you need, you must package them, along with some files that jMaki provides, as described in Using a jMaki Widget.

That's it. Now you can use the list widget as shown here:

<a:ajax name="list"
                  

        service="listService.jsp"  />
                
 
Conclusion

Project jMaki makes it easier to add Ajax to both pure JSP and JavaServer Faces technology-based applications. jMaki simplifies the page author's work because the widget is encapsulated in a modular, portable unit, thereby shielding the page author from JavaScript technology code and facilitating reuse of the widgets.

It's also easier for developers for many reasons. They can reuse most widgets they already created. And they get the benefit of a JSP technology tag handler or JavaServer Faces component without having to write the extra code that is associated with creating these modules.

For More Information

 



About the Author

Jennifer Ball is a staff writer at Sun. She writes about web application technologies that are part of the Java EE platform.

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.