<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- We need a doctype to allow us to use special characters like
We use a "strict" DTD to make IE follow the alignment rules. -->
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<body class="container">
<h3>AJAX Periodic Update Mixin</h3>
<noscript class="js-required">
${message:javascript_required}
</noscript>
Here we have moved the "AJAX periodic update" functionality into a mixin that can be used with any Zone.
<div class="eg">
<t:zone t:id="timeZone" id="timeZone" t:mixins="ZonePeriodicUpdater"
ZonePeriodicUpdater.event="refreshTimeZone" ZonePeriodicUpdater.frequencySecs="3" ZonePeriodicUpdater.maxUpdates="4">
serverTime: ${serverTime}
</t:zone>
</div>
The ZonePeriodicUpdater mixin on this page has a maxUpdates parameter. If we didn't need that parameter then we could use Tapestry's
<a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/mixins/ZoneRefresh.html">ZoneRefresh</a> mixin instead.<br/><br/>
References:
<a href="http://tapestry.apache.org/ajax-and-zones.html">Ajax and Zones</a>,
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/Zone.html">Zone</a>,
<a href="http://tapestry.apache.org/component-mixins.html">Component Mixins</a>,
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/ComponentResources.html">ComponentResources</a>,
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>,
<a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ClientElement.html">ClientElement</a>,
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html">@Inject</a>,
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/annotations/InjectContainer.html">@InjectContainer</a>,
<a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/annotations/InjectComponent.html">@InjectComponent</a>,
<a href="http://www.w3schools.com/js/js_timing.asp">JavaScript Timing Events</a>,
<a href="http://tapestry.apache.org/5.4/coffeescript/zone.html">t5/core/zone</a>.<br/><br/>
<t:pagelink page="Index">Home</t:pagelink><br/><br/>
<t:tabgroup>
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/ajax/AjaxPeriodicUpdateMixin.tml"/>
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/ajax/AjaxPeriodicUpdateMixin.java"/>
<t:sourcecodetab src="/web/src/main/resources/META-INF/assets/css/examples/js.css"/>
<t:sourcecodetab src="/web/src/main/java/jumpstart/web/mixins/ZonePeriodicUpdater.java"/>
<t:sourcecodetab src="/web/src/main/resources/META-INF/modules/zone-periodic-updater.js"/>
</t:tabgroup>
</body>
</html>
package jumpstart.web.pages.examples.ajax;
import java.util.Date;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
@Import(stylesheet = "css/examples/js.css")
public class AjaxPeriodicUpdateMixin {
// Generally useful bits and pieces
@InjectComponent
private Zone timeZone;
@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
@Inject
private Request request;
// The code
void onRefreshTimeZone() {
if (request.isXHR()) {
ajaxResponseRenderer.addRender(timeZone);
}
}
public Date getServerTime() {
return new Date();
}
}
.eg {
margin: 20px 0;
padding: 14px;
color: #888;
border: 1px solid #ddd;
border-radius: 6px;
-webkit-border-radius: 6px;
-mox-border-radius: 6px;
}
.js-required {
color: red;
display: block;
margin-bottom: 14px;
}
.js-recommended {
color: red;
display: block;
margin-bottom: 14px;
}
/**
* A simple mixin for attaching javascript to a Zone that periodically issues an AJAX request to update the Zone.
* Loosely based on Tapestry's ZoneRefresh.
*/
package jumpstart.web.mixins;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.InjectContainer;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
public class ZonePeriodicUpdater {
// Parameters
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String event;
@Parameter
private Object[] context;
@Parameter(defaultPrefix = BindingConstants.LITERAL, required = true)
private int frequencySecs;
@Parameter(defaultPrefix = BindingConstants.LITERAL, required = true)
private int maxUpdates;
// Useful bits and pieces
@Inject
private ComponentResources componentResources;
@Inject
private JavaScriptSupport javaScriptSupport;
/**
* The element we attach ourselves to, which must be a Zone
*/
@InjectContainer
private Zone zone;
// The code
void afterRender() {
String eventURL = componentResources.createEventLink(event, context).toAbsoluteURI();
javaScriptSupport.require("zone-periodic-updater")
.with(zone.getClientId(), eventURL, frequencySecs, maxUpdates);
}
}
// For a zone (zoneElementId), periodically issues an AJAX request (eventURL) to update it.
define(["jquery", "t5/core/zone"], function($, zoneManager) {
return function(zoneElementId, eventURL, frequencySecs, maxUpdates) {
var frequencyMillis = frequencySecs * 1000;
var updatesCount = 0;
var interval = setInterval(updateZone, frequencyMillis);
function updateZone() {
if (updatesCount++ < maxUpdates) {
// Update the zone.
zoneManager.deferredZoneUpdate(zoneElementId, eventURL);
}
else {
// Stop updating.
clearInterval(interval);
}
}
}
});