a Dynamic Ajax table example using jMaki and Java Persistence APIs on Glassfish

This Sample Catalog app demonstrates the usage of the Java Persistence APIs to implement server side pagination (recommended for large sets of data), and  jMaki to get and display the results in a dynamic Ajax table.

Download the jMaki Sample Application Code

https://ajax.dev.java.net/jMaki is an Ajax framework that provides a lightweight model for creating JavaScript centric Ajax-enabled web applications. jMaki provides wrappedwidgets that can be used as JavaServer Pages tags, as JavaServer Faces components, within a Phobos application, or with PHP. This sample applicaton uses jMaki with JavaServer Pages.

Explanation of the usage of jMaki and the Java Persistence APIs in a sample Catalog Application

The image below shows the Customer Listing page, which allows the user to page through a list of customers.


jMaki dataTable widget

With  jMaki and JavaServer Pages, you can easily include wrapped widgets from ajax toolkits into a JavaServer Page as a custom JSP tag. With the Netbeans jMaki plugin you can drag  jMaki widgets from the Palette into a JSP. jMaki standardizes widget data and event models to simplify the programming model and to simplify interactions between widgets.

The sample application's index.jsp page uses a jMaki yahoo.dataTable widget to display a  list of customers in a dynamic table.

The jMaki table widgets (there is also a jMaki dojo table widget) are useful when you want to show a set of results in tabular data on a web page.  Table widgets provide sortable columns, row selection, and they can be updated using jMaki publish subscribe events.

In the List.jsp web page the dataTable is defined as shown below:   (Note:Redcolors are for jMaki tags or variables,  and Green for my code orvariables)

Code Sample from:  index.jsp

<a:widget name="yahoo.dataTable"

To determine the data format and events for the table you can refer to the  jMaki Table Data Model or look at the widget.json file for the table widget. This file is located in the resources/yahoo/dataTable directory.
The serviceattribute references the CatalogServiceservlet which returns the data to be included in the table.  The data for the table should be a JSON object containing an object of columns and an array of row arrays. The column names need a unique id which is then used in the data to associate it with a given row. An example for a table of companies is shown below:

Code Sample from:  widget.json
     {'label' :'Company', 'id' : 'name'},
     {'label':'City', 'id' : 'city'}
     {'name' : 'Sun Microsystems', 'city' : 'Santa Clara'},
     {'name' : 'IBM', 'city' : 'Raleigh'}

The publishsubscribeattributes specify a topic that publish and subscribe events will be sent to. Publish and subscribe events can be used to tie widgets together (more on this later).

The dataTable's service="CatalogService"  calls the CatalogServiceservlet which calls the getCustomersJSONmethod of the Catalogclass:

Code Sample from: Catalog.java
public class Catalog {
 public List<Customer> getCustomers()throws Exception {
   EntityManager em = getEntityManager();
   Query q = em.createQuery(
          "select object(o) from Customer as o");
   return q.getResultList();

 public JSONArraygetCustomersJSON()throws Exception {
   JSONArraycustomersJSON = new JSONArray();
   List<Customer> customers = getCustomers();
   for (Customer customerData : customers) {
       JSONObject customerJSON = customerData.toJSON();
   return customersJSON;

Java Persistence Query API

The Catalog getCustomersJSON() uses the Java Persistence API Queryobject to return a list of customers, a JSONArray  object is used to return the list in JSON format.  The Java Persistence Query APIs are used to create and execute queries that can return a list of results.  The JPA Query interface provides support for pagination via the setFirstResult() and setMaxResults() methods: query.setMaxResults(int maxResult) sets the maximum number of results to retrieve.query.setFirstResult(int startPosition) sets the position of the first result to retrieve.

In the code below, we show the Customerentity class which maps to the  CUSTOMER table that stores the customer instances. This is a typical Java Persistence entity object. There are two requirements for an entity:
  1. annotating the class with an @Entityannotation.
  2. annotating the primary key identifier with @Id
Because the fields name, description.... are basic mappings from the object fields to columns of the same name in the database table, they don't have to be annotated. 
For more information on Netbeans and JPA seehttp://www.apress.com/book/bookDisplay.html?bID=10093 basics of developing a web application using Java™ Persistence API.

Code Sample from: Customer.java


public class Customerimplements Serializable {

    private Integer customerId;

    private String name;
    private String addressline1;   
    private String city;  
    private String state; 
    private String zip;

Customer() { }
    public String getName() {
        return name;
    public void setName(String name) {
        this.name = name;

JSONObjecttoJSON() {
        JSONObject thisJSON=new JSONObject();
        thisJSON.put("name", this.getName());
        thisJSON.put("city", this.getCity());
        thisJSON.put("state", this.getState());
        thisJSON.put("zip", this.getZip());


I added thetoJSON() method to theCustomer to return a JSON representation of the Customer entity.

jMaki Publish Subscribe events 

jMaki publish subscribe events tie widgets actions together. The sample app uses two jMaki yahoo.buttonwidgets which publish to the /button/previous,/button/next topicswhen the respective button is clicked:

Code Sample from: List.jsp

<a:widget name="yahoo.button" value="{label : '<<',
                 action : {topic : '/button/previous'}}" />

<a:widget name="yahoo.button" value="{label : '>>',
                 action : {topic : '/button/next'}}" />

Events in jMaki are handled by jMaki Glue , whichhttps://ajax.dev.java.net/introGlue.html allows JavaScript components to talk to each other. You put function listeners which Subscribe to topics that your widgets Publish to in a file called glue.js (to read more about this see A practical guide to jMaki Events ).

Connecting the listener to the handler
The listener handler for the  /button/nexttopic is shown below. First you declare the topic to listen to and then the listener function which will handle the notification. The/button/nextlistener handler  increments the page number and then calls the getNextPagefuntion.

Code Sample from: glue.js
var page= 0;

jmaki.subscribe("/button/next", function(args) {
    page =page + 1;

jmaki.subscribe("/button/previous", function(args) {
    page =page - 1;
    if (page < 0) page = 0;

function getNextPage(page) {
    jmaki.doAjax({method: "POST",
        url: "CatalogService?page="+encodeURIComponent(page)+
           "&rowsonly=" + encodeURIComponent(rowsonly),
        callback :function(req) {
           customers = eval(req.responseText);
           jmaki.publish("/table/clear", { });
                   { value : customers} );

The getNextPagefunction uses  jmaki.doAjax, which provides an easy way to make an  XMLHttpRequest, to call the CatalogServiceservlet passing the page number as a URI parameter.  The callbackfunction uses  eval to convert the XMLHttpRequest response into a JSON object. Then  jmaki.publishis called to publish the returned customersJSON object to the /table/addRowstopic.

The yahoo.dataTable widget subscribes to thetabletopic.
Subscribe events allow you to manipulate a given instance of a widget. The event names are appended to the the subscribe topic name following a "/". For example  "/table/addRows" will call the yahoo.dataTableaddRowsfunction which will add the  payload value passed to the widget to the the table. This will cause the  returnedcustomersJSON object to be displayed in the table on the html page.

This CatalogServletprocessRequest  method is defined as shown below:

Code Sample from: CatalogBean.java

public class CatalogServletextends HttpServlet {

protected void processRequest(HttpServletRequest request,
       HttpServletResponse response)
       throws ServletException, IOException {

   Catalog catalog = new Catalog();
   PrintWriter out = response.getWriter();
   int page =
   int rowsonly =

   JSONArray array = catalog.getNextCustomersJSON(page);
   if (rowsonly == 1) {
   } else{
     out.println("{columns : [" +
        "{ label : 'Company', id : 'name'}," +
        "{ label :'City', id : 'city'}," +
        "{ label : 'State', id : 'state'}," +
        "{ label : 'Zip', id : 'zip'}" +
     out.println("rows: ");
     out.println(" }");

The CatalogServletsimply calls the Catalog class to get the next list of results from the database like we saw in the previous code. The CatalogServletthen returns the resulting JSONArray as a text string.

This concludes the sample application which demonstrates the usage of the Java Persistence APIs and jMaki in a dynamic Ajax table example.

Configuration of the Application for jMaki, JPA, Netbeans 6.1 and Glassfish V2

Open and Run the Sample code:

  1. Download the sample code and extract its contents. You should now see the newly extracted directory as<sample_install_dir>/JPAjmaki, where <sample_install_dir> is the directory where you installed the sample package. For example, if you extracted the contents to C:\ on a Windows machine, then your newly created directory should be atC:\JPAjmaki.

  2. Start the NetBeans IDE. Click Open Project in the File menu and select the JPAjmaki directory you just unzipped.

  3. Build the project as follows:

    • Right click the JPAjmaki node in the Projects window.
    • Select Clean and Build Project.

  4. Run the project as follows:

    • Right click the JPAjmaki node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display the opening page of the Sample Application (at http://localhost:8080/JPAjmaki/).

If you want to create your own jMaki application: