You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by "Thiago H. de Paula Figueiredo" <th...@gmail.com> on 2017/03/19 20:46:44 UTC

[Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

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

Re: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

Posted by abangkis <ab...@gmail.com>.
Yes. I've seen it. Pretty clean and good example.

Thank you.

On Thu, Apr 27, 2017 at 7:15 PM, Svein-Erik Løken <sv...@jacilla.no> wrote:

> See my working demo above in this thread:
> (https://github.com/sveine/tapestry-multi-module-demo/
> blob/master/module1-root/module1/src/main/resources/META-INF/modules/
> publisheventdemo.js)
>
> From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List
> Archives] [mailto:ml+s1045711n5733456h17@n5.nabble.com]
> Sent: 27. april 2017 14:11
> To: Svein-Erik Løken <sv...@jacilla.no>
> Subject: Re: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily
> call event handler methods from JavaScript
>
> On Thu, Apr 27, 2017 at 6:43 AM, abangkis <[hidden
> email]</user/SendEmail.jtp?type=node&node=5733456&i=0>> wrote:
>
> > Hi. Thanks for the awesome improvement. I want to adopt it immediately.
>
>
> Hi! Nice! :)
>
>
> > But I've stumbled to one problem. How do I pass a parameter to the event?
> >
>
> You don't pass it to the event, but to the t5/core/ajax() function. Check
> the data property of the options parameter in
> https://tapestry.apache.org/current/coffeescript/ajax.html. Basically, you
> pass an object with the key/value pairs you want passed as parameters:
>
> ajax('answer', {
>     element: $('#result'),
> /* Here it goes */
> data: {
> queryParameter1: valueParameter1,
> queryParameter2: valueParameter2
> }
> /* Here it ends */
>     success: function(response) {
>         $('#result').text(response.json.origin);
>     }
> });
>
>
> --
> Thiago
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/Announcement-New-feature-for-Tapestry-5-4-
> 2-and-5-5-easily-call-event-handler-methods-from-
> JavaScript-tp5733295p5733456.html
> To unsubscribe from users@tapestry.apache.org<mailto:
> users@tapestry.apache.org> Mailing List Archives, click here<
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=
> 2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4>.
> NAML<http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%
> 21nabble%3Aemail.naml&base=nabble.naml.namespaces.
> BasicNamespace-nabble.view.web.template.NabbleNamespace-
> nabble.view.web.template.NodeNamespace&breadcrumbs=
> notify_subscribers%21nabble%3Aemail.naml-instant_emails%
> 21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>



-- 
http://www.mreunionlabs.net/ <http://www.mreunion-labs.net/>
twitter : @mreunionlabs @abangkis
page : https://plus.google.com/104168782385184990771

RE: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

Posted by Svein-Erik Løken <sv...@jacilla.no>.
See my working demo above in this thread:
(https://github.com/sveine/tapestry-multi-module-demo/blob/master/module1-root/module1/src/main/resources/META-INF/modules/publisheventdemo.js)

From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List Archives] [mailto:ml+s1045711n5733456h17@n5.nabble.com]
Sent: 27. april 2017 14:11
To: Svein-Erik Løken <sv...@jacilla.no>
Subject: Re: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

On Thu, Apr 27, 2017 at 6:43 AM, abangkis <[hidden email]</user/SendEmail.jtp?type=node&node=5733456&i=0>> wrote:

> Hi. Thanks for the awesome improvement. I want to adopt it immediately.


Hi! Nice! :)


> But I've stumbled to one problem. How do I pass a parameter to the event?
>

You don't pass it to the event, but to the t5/core/ajax() function. Check
the data property of the options parameter in
https://tapestry.apache.org/current/coffeescript/ajax.html. Basically, you
pass an object with the key/value pairs you want passed as parameters:

ajax('answer', {
    element: $('#result'),
/* Here it goes */
data: {
queryParameter1: valueParameter1,
queryParameter2: valueParameter2
}
/* Here it ends */
    success: function(response) {
        $('#result').text(response.json.origin);
    }
});


--
Thiago

________________________________
If you reply to this email, your message will be added to the discussion below:
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Announcement-New-feature-for-Tapestry-5-4-2-and-5-5-easily-call-event-handler-methods-from-JavaScript-tp5733295p5733456.html
To unsubscribe from users@tapestry.apache.org<ma...@tapestry.apache.org> Mailing List Archives, click here<http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4>.
NAML<http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>

Re: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

Posted by abangkis <ab...@gmail.com>.
Thank you very much. I got it working. Now my code is going to be a whole
lot cleaner.

Good job Thiago.

On Thu, Apr 27, 2017 at 7:10 PM, Thiago H. de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> On Thu, Apr 27, 2017 at 6:43 AM, abangkis <ab...@gmail.com> wrote:
>
> > Hi. Thanks for the awesome improvement. I want to adopt it immediately.
>
>
> Hi! Nice! :)
>
>
> > But I've stumbled to one problem. How do I pass a parameter to the event?
> >
>
> You don't pass it to the event, but to the t5/core/ajax() function. Check
> the data property of the options parameter in
> https://tapestry.apache.org/current/coffeescript/ajax.html. Basically, you
> pass an object with the key/value pairs you want passed as parameters:
>
> ajax('answer', {
>     element: $('#result'),
> /* Here it goes */
> data: {
> queryParameter1: valueParameter1,
> queryParameter2: valueParameter2
> }
> /* Here it ends */
>     success: function(response) {
>         $('#result').text(response.json.origin);
>     }
> });
>
>
> --
> Thiago
>



-- 
http://www.mreunionlabs.net/ <http://www.mreunion-labs.net/>
twitter : @mreunionlabs @abangkis
page : https://plus.google.com/104168782385184990771

Re: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Thu, Apr 27, 2017 at 6:43 AM, abangkis <ab...@gmail.com> wrote:

> Hi. Thanks for the awesome improvement. I want to adopt it immediately.


Hi! Nice! :)


> But I've stumbled to one problem. How do I pass a parameter to the event?
>

You don't pass it to the event, but to the t5/core/ajax() function. Check
the data property of the options parameter in
https://tapestry.apache.org/current/coffeescript/ajax.html. Basically, you
pass an object with the key/value pairs you want passed as parameters:

ajax('answer', {
    element: $('#result'),
/* Here it goes */
data: {
queryParameter1: valueParameter1,
queryParameter2: valueParameter2
}
/* Here it ends */
    success: function(response) {
        $('#result').text(response.json.origin);
    }
});


-- 
Thiago

Re: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

Posted by abangkis <ab...@gmail.com>.
Hi. Thanks for the awesome improvement. I want to adopt it immediately. But
I've stumbled to one problem. How do I pass a parameter to the event?

Here's the onEvent method that will be invoked

@OnEvent("updateNodes")
void updateNodes(@RequestParameter(value = "param", allowBlank = false)
String param) {
    logger.debug("On update nodes {} ", param);
}

In the old way i could call it using

$('#saveChanges').click(function () {
    var my_param = {'example param'};

    routejs.jsClickCallback(tSpec.updateOrderEventLink, tSpec.zoneId,
JSON.stringify(my_param));
});

var jsClickCallback = function(listenerURI, zoneElementId, param) {
  var listenerURIWithValue = listenerURI;

  listenerURIWithValue = appendQueryStringParameter(listenerURIWithValue,
'param', param);

  zoneManager.deferredZoneUpdate(zoneElementId, listenerURIWithValue);
};

var appendQueryStringParameter = function(url, name, value) {
  if (url.indexOf('?') < 0) {
    url += '?'
  }
  else {
    url += '&';
  }
  value = escape(value);
  url += name + '=' + value;
  return url;
}

On Sun, Apr 23, 2017 at 6:04 AM, Thiago H. de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> Cool! It's nice to see a feature I've wanted for so long already being
> adopted by users. Thanks for the example!
>
> On Fri, Apr 21, 2017 at 11:18 AM, Svein-Erik Løken <sv...@jacilla.no>
> wrote:
>
> > The @PublishEvent was a big improvement 😊
> >
> >
> >
> > I am using it already. I have created a working demo. I really like that
> > it is so easy to stop hardcoding of event url.
> >
> >
> >
> >
> >
> > https://github.com/sveine/tapestry-multi-module-demo/
> > blob/master/module1-root/module1/src/main/java/com/demo/module1/pages/
> > PublishEventDemo.java
> >
> > https://github.com/sveine/tapestry-multi-module-demo/
> > blob/master/module1-root/module1/src/main/resources/
> > com/demo/module1/pages/PublishEventDemo.tml
> >
> > https://github.com/sveine/tapestry-multi-module-demo/
> > blob/master/module1-root/module1/src/main/resources/META-INF/modules/
> > publisheventdemo.js
> >
> > https://github.com/sveine/tapestry-multi-module-demo/
> > blob/master/core/src/main/resources/META-INF/modules/
> util/tapestryutil.js
> > (TapestryUtil.ajaxEvent)
> >
>
>
>
> --
> Thiago
>



-- 
http://www.mreunionlabs.net/ <http://www.mreunion-labs.net/>
twitter : @mreunionlabs @abangkis
page : https://plus.google.com/104168782385184990771

Re: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Cool! It's nice to see a feature I've wanted for so long already being
adopted by users. Thanks for the example!

On Fri, Apr 21, 2017 at 11:18 AM, Svein-Erik Løken <sv...@jacilla.no> wrote:

> The @PublishEvent was a big improvement 😊
>
>
>
> I am using it already. I have created a working demo. I really like that
> it is so easy to stop hardcoding of event url.
>
>
>
>
>
> https://github.com/sveine/tapestry-multi-module-demo/
> blob/master/module1-root/module1/src/main/java/com/demo/module1/pages/
> PublishEventDemo.java
>
> https://github.com/sveine/tapestry-multi-module-demo/
> blob/master/module1-root/module1/src/main/resources/
> com/demo/module1/pages/PublishEventDemo.tml
>
> https://github.com/sveine/tapestry-multi-module-demo/
> blob/master/module1-root/module1/src/main/resources/META-INF/modules/
> publisheventdemo.js
>
> https://github.com/sveine/tapestry-multi-module-demo/
> blob/master/core/src/main/resources/META-INF/modules/util/tapestryutil.js
> (TapestryUtil.ajaxEvent)
>



-- 
Thiago

RE: [Announcement] New feature for Tapestry 5.4.2 and 5.5: easily call event handler methods from JavaScript

Posted by Svein-Erik Løken <sv...@jacilla.no>.
The @PublishEvent was a big improvement 😊



I am using it already. I have created a working demo. I really like that it is so easy to stop hardcoding of event url.





https://github.com/sveine/tapestry-multi-module-demo/blob/master/module1-root/module1/src/main/java/com/demo/module1/pages/PublishEventDemo.java

https://github.com/sveine/tapestry-multi-module-demo/blob/master/module1-root/module1/src/main/resources/com/demo/module1/pages/PublishEventDemo.tml

https://github.com/sveine/tapestry-multi-module-demo/blob/master/module1-root/module1/src/main/resources/META-INF/modules/publisheventdemo.js

https://github.com/sveine/tapestry-multi-module-demo/blob/master/core/src/main/resources/META-INF/modules/util/tapestryutil.js (TapestryUtil.ajaxEvent)