...
Tapestry 5.4.2 introduced has an API which makes it easy for server-side events to be invoked from JavaScript. In the server-side, you first need to annotate the event handler methods you want exposed with the new @PublishEvent
annotation. Then, in JavaScript, all you need to do is to call the existing t5/core/ajax
function with the server-side event name/type in the url
parameter and with an options
parameter containing an element
property, be it null or specifying an DOM element to be used as the starting point for finding the event information. Here's one example:
Code Block | ||
---|---|---|
| ||
public class PublishEventDemoComponent
{
@OnEvent("answer")
@PublishEvent
JSONObject answer() {
return new JSONObject("origin", "componentAction");
}
@PublishEvent
JSONObject onAction()
{
return new JSONObject("origin", "componentAnswer");
}
}
|
Notice that answer()
and onAction()
are ordinary event handlers, with nothing specific besides the @PublishEvent
annotation.
Code Block | ||
---|---|---|
| ||
<div id="component" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<p id="componentParagraph">I'm a <strong id="strong">component</strong></p>
</div> |
...
but with slightly different parameters.
t5/core/ajax
has two parameters: url
and options
. The first one was the difficult part to get when doing AJAX requests to event handler methods in Tapestry. You needed to inject ComponentResources
, call componentResources.createEventLink()
for each event handler method then pass all this information to JS through one of the JavaScriptSupport
methods. Since 5.4.2, your JavaScript code only needs to know the event name (also called event type) and optionally indicate a DOM element to be used as a starting point for finding the event URL.
All event data is stored in data-componenent-events
attributes. For page classes, it's put in the <body>
element. For components, it's put in the first element rendered created by rendering the component. Given an HTML element, the search is done until one in this order until information for the given event is first found:
- The element itself
- The element's previous siblings, closest first (bottom-up)
- The element's parents.
- The page's <
body>
element.
Here's one example:
Code Block | ||
---|---|---|
| ||
public class PublishEventDemoComponent
{
@OnEvent("answer")
@PublishEvent
JSONObject answer() {
return new JSONObject("origin", "componentAnswer");
}
@PublishEvent
JSONObject onAction()
{
return new JSONObject("origin", "componentAction");
}
}
|
Notice that answer()
and onAction()
are ordinary event handlers, with nothing specific besides the @PublishEvent
annotation.
Code Block | ||
---|---|---|
| ||
<div id="component" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<p id="componentParagraph">I'm a component</p>
<p id="result">(no result yet)</p>
</div> |
The template also has nothing special. When rendered, the component's events information is placed in the outer <div>
(id="component").
We want to update the text of <p id="result">
with the value of the origin
property of the returned JSON object when that element itself is clicked, so here's our JavaScript code, supposing we want to trigger the answer
event:
Code Block | ||||
---|---|---|---|---|
| ||||
require(["t5/core/ajax", "jquery"], function (ajax, $) {
$('#result').click(function() {
ajax('answer', {
element: $('#componentParagraph'),
success: function(response) {
$('#result').text(response.json.origin);
}
});
});
}); |