Hi! This is something I've wanted for a really long time to implement in Tapestry, so I won't wait for it to be released or even the documentation to be updated in the site to post it here. Feedback welcome! Invoking server-side event handler methods from JavaScript
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 <http://tapestry.apache.org/current/coffeescript/ajax.html> function 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: 1. The element itself 2. The element's previous siblings, closest first (bottom-up) 3. The element's parents. 4. The page's <body> element. Here's one example: 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. <div id="component" xmlns:t=" http://tapestry.apache.org/schema/tapestry_5_0_0.xsd" <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: 1 2 3 4 5 6 7 8 9 10 11 12 13 require(["t5/core/ajax", "jquery"], function (ajax, $) { // Creating a callback to be invoked with <p id="result"> is clicked. $('#result').click(function() { ajax('answer', { element: $('#result'), // This doesn't need to be the same element as the one two lines above // Callback called when the request is finished. // response.json is the object returned by the event handler method success: function(response) { $('#result').text(response.json.origin); } }); }); }); If you're trying to invoke a page class event handler, you can change line 5 above to element: null. You do need to explicitly set the element property, otherwise the ajax function will treat the first parameter, url, as an URL and not as an event name. -- Thiago