Parancoe AJAX Tutorial

The Parancoe Web module provides AJAX features through an integration of the DWR library.

This tutorial will show you how to use this integration for write the AJAX functionalities of your application.

Even if you can use the following features in your own, started from the ground, application, the tutorial base environment is and application created through the Parancoe Web Archetype. See Starting a Web Project with Parancoe.

Index

Add a method you can ajax-call

The DWR configuration isn’t in a separate file. You configure it in your applcation Spring configuration file: parancoe-servlet.xml.

For example, You need to populate your database, clicking on a link in a page. You don’t want to have a page reloading, so you need an AJAX call.

Put the code that populates the DB in a Java class:


public class PersonBo {

    public void populateArchive() {
      // doing DB population
    }

    // ...
}

Now You need to declare that method is callable through DWR. In your parancoe-servlet.xml:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:parancoe="http://www.parancoe.org/schema/parancoe" 
       xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       http://www.parancoe.org/schema/parancoe
       http://www.parancoe.org/schema/parancoe.xsd
       http://www.directwebremoting.org/schema/spring-dwr
       http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd" 
       default-lazy-init="false" >

    <!-- ... -->

    <bean id="personBO" class="com.mycompany.prova2.blo.PersonBo">
        <!-- anything you need in your object -->

        <dwr:remote javascript="personBO">
            <dwr:include method="populateArchive"/>
            <!-- more dwr:include -->
        </dwr:remote>
    </bean>

    <!-- ... -->
</beans>

This configuration automatically generate a JavaScript proxy containing that method, You can use in your pages:


<html>
    <head>
        <!-- inclusion from the parancoe web archetype --> 
        <%@ include file="head.jspf" %>
        <!-- inclusion of the personPO javascript proxy -->
        <script src="${cp}/dwr/interface/personBO.js" 
                type="text/javascript"></script>
    </head>
    <!-- DWR initialization on page loading -->
    <body onload="parancoe.util.initDWR()">

        <!-- ... -->

         <!-- note: this is an AJAX call to Java code on the server -->
        <a href="#" onclick="personBO.populateArchive()"; return false;">Populate</a>

        <!-- ... -->

    </body>
</html>

Write a method that returns simple data

If you need to return data to your page after an ajax call, simply define a method returning a value. DWR can generate proxies for all basic Java data types.


public class PersonBo {

    public String getFullName(Long personId) {
      // retrive the person with that id
      return p.getFirstName()+" "+p.getLastName();
    }

    // ...
}

Declare it in your DRW configuration in the parancoe-servlet.xml:


<bean id="personBO" class="com.mycompany.prova2.blo.PersonBo">
    <!-- anything you need in your object -->

    <dwr:remote javascript="personBO">
        <dwr:include method="getFullName"/>
        <!-- more dwr:include -->
    </dwr:remote>
</bean>

Now You can you it in you Javascript code in your pages:


<html>
    <head>
        <!-- inclusion from the parancoe web archetype --> 
        <%@ include file="head.jspf" %>
        <!-- inclusion of the personPO javascript proxy -->
        <script src="${cp}/dwr/interface/personBO.js" 
                type="text/javascript"></script>
    </head>
    <!-- DWR initialization on page loading -->
    <body onload="parancoe.util.initDWR()">

        <div>
            Person Id: <input type="text" id="personId"/>
            <input type="button" value="Search" 
                   onclick="updateFullNameDiv($('personId').value)"/>
        </div>

        <div id="fullNameDiv"></div>

        <script type="text/javascript"/>
           function updateFullNameDiv(personId) {
             // note: this is an AJAX call to Java code on the server
             personBO.getFullName(personId, function (data) {
                $('fullNameDiv').innerHTML = data;
             });
           }
         </script>

    </body>
</html>

Write a method that returns complex data

If You want to return a complex object to your page (or pass a complex object to a method), you need to declare the object type in your DWR configuration in your parancoe-servlet.xml:


<bean id="personBO" class="com.mycompany.prova2.blo.PersonBo">
    <!-- anything you need in your object -->

    <dwr:remote javascript="personBO">
        <dwr:include method="retrievePerson"/>
        <!-- more dwr:include -->
    </dwr:remote>
</bean>

<dwr:configuration>
    <dwr:convert type="bean" class="com.mycompany.prova2.po.Person" />
</dwr:configuration>

The method is something like:


public class PersonBo {

    public Person retrievePerson(Long personId) {
      // retrieve the person with that id
      return p;
    }

    // ...
}

Now in your page:


<html>
    <head>
        <!-- inclusion from the parancoe web archetype --> 
        <%@ include file="head.jspf" %>
        <!-- inclusion of the personPO javascript proxy -->
        <script src="${cp}/dwr/interface/personBO.js" 
                type="text/javascript"></script>
    </head>
    <!-- DWR initialization on page loading -->
    <body onload="parancoe.util.initDWR()">

        <div>
            Person Id: <input type="text" id="personId"/>
            <input type="button" value="Search" 
                   onclick="updateFullNameDiv($('personId').value)"/>
        </div>

        <div id="fullNameDiv"></div>

        <script type="text/javascript"/>
           function updateFullNameDiv(personId) {
             // note: this is an AJAX call to Java code on the server
             personBO.retrievePerson(personId, function (data) {
                $('fullNameDiv').innerHTML = data.firstName+' '+data.lastName;
             });
           }
         </script>

    </body>
</html>

Manipulate the page from the Java code

With DWR’s reverse AJAX features you can remove most of the JavaScript code from your page, manipulating the page content directly from the server-side Java code.

As always, declare your method in your parancoe-servlet.xml:


<bean id="personBO" class="com.mycompany.prova2.blo.PersonBo">
    <!-- anything you need in your object -->

    <dwr:remote javascript="personBO">
        <dwr:include method="updateFullName"/>
        <!-- more dwr:include -->
    </dwr:remote>
</bean>

In the method You can use the org.directwebremoting.proxy.dwr.Util class:


public class PersonBo {

    public void updateFullName(Long id) {
        WebContext wctx = WebContextFactory.get();        
        ScriptSession session = wctx.getScriptSession();
        Util util = new Util(session);
        // retrieve the person with that id
        util.setValue("fullNameDiv", p.getFirstName()+" "+p.getLastName());

        // You can also use scriptaculous effects
        Effect effect = new Effect(session);
        effect.highlight("fullNameDiv");
    }

    // ...
}

Note, You are writing Java code, not JavaScript code. If you need, you can even display scriptaculous effects.

Now in your page:


<html>
    <head>
        <!-- inclusion from the parancoe web archetype --> 
        <%@ include file="head.jspf" %>
        <!-- inclusion of the personPO javascript proxy -->
        <script src="${cp}/dwr/interface/personBO.js" 
                type="text/javascript"></script>
    </head>
    <!-- DWR initialization on page loading -->
    <body onload="parancoe.util.initDWR()">

        <div>
            Person Id: <input type="text" id="personId"/>
            <input type="button" value="Search" 
                   onclick="personBO.updateFullName($('personId').value)"/>
        </div>

        <div id="fullNameDiv"></div>

    </body>
</html>

Note again: mostly no JavaScript code, except the call to your method.

...to be continued.

Posted by Lucio Benfante on Wednesday, September 26, 2007