Pages

Friday, April 16, 2010

Ajax Zone with Interval in Tapestry 5

I'm planning to create a zone that will keep requesting data from the server at certain interval. Seems simple enough to do in Tapestry 5 right ?

But because of my lack of understanding about Ajax and Javascript concept, I've venture to many place to make it. ZoneUpdate, Progressive Display is a few things that i look a bit deep. Trying to understand their inner work, just to find out in which part could I add this simple code.

After a day struggling, i found out that my original idea work just fine. Yeah when its about web, ajax and javascript, I SUCKS ! BIG TIME !

So here's the code to make it work, so no other newbie would get lost like I Do.


The Code

I'm using the sample code from Zone Component in Tapestry 5.
Here's the template page :

<body>
<h1> Crawl Ajax </h1>
<h2> Timer Zone </h2>
   
    <div style="margin-left: 50px">
        <t:zone t:id="time2zone">
            time2:  ${time2}
        </t:zone><br/>

        <a t:type="actionlink" t:id="refreshZone" href="#"
            t:zone="time2zone">Refresh time2 </a>
            <br/><br/>

    </div>
       
    <input type="button" onclick="startTimer()" value="Start Timer" /> <br/>   
    <input type="button" onclick="stopTimer()" value="Stop Timer" /> <br/>   

</body>

Here's the java class code :

    @InjectComponent
    private Zone _time2Zone;

    // The code
   
    void onActionFromRefreshPage() {
        // Nothing to do - the page will call getTime1() and getTime2() as it renders.
    }

    // Isn't called if the link is clicked before the DOM is fully loaded. See
    // https://issues.apache.org/jira/browse/TAP5-1 .
    Object onActionFromRefreshZone() {
        // Here we can do whatever updates we want, then return the content we want rendered.
        return _time2Zone.getBody();
    }

    public Date getTime2() {
        return new Date();
    }
   
    Object onChangeOfTimerZone() {
        return _time2Zone.getBody();
    }

And finally, Here's the Java Script code :

<script type="text/javascript">

var timerId;
var linkId='refreshZone';

function updateMyZone() {
    alert("Update Zone!" + linkId);
    var actionLink = $(linkId);
    Tapestry.findZoneManager( actionLink ).updateFromURL( actionLink.href );
}

function startTimer() {
    alert('yohoo');
    timerId = window.setInterval('updateMyZone()', 2000);
}

function stopTimer() {
    clearInterval (timerId);
}
</script>

As you can see i only add 2 input button to start and stop the timer. The button will invoke the javascript function that uses setInterval that will invoke updateMyZone every 2 second. The updateMyZone will emulate the actionLink behaviour to update the zone.

Bleah its 10+ line of code and it took me the whole day. *still angry and ashamed with my self*

~FD

2 comments:

Per-Erik Lindskog said...

Thanks a lot!

Saved me the day or days I would have needed to come up with this.

B said...

Hi Per-Erik, glad it could help :)