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

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Thiago H. de Paula Figueiredo
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
Reply | Threaded
Open this post in threaded view
|

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

Svein-Erik Løken
Reply | Threaded
Open this post in threaded view
|

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

Thiago H. de Paula Figueiredo
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 <[hidden email]> 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
Reply | Threaded
Open this post in threaded view
|

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

abangkis
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 <
[hidden email]> 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 <[hidden email]>
> 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
Reply | Threaded
Open this post in threaded view
|

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

Thiago H. de Paula Figueiredo
On Thu, Apr 27, 2017 at 6:43 AM, abangkis <[hidden email]> 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
Reply | Threaded
Open this post in threaded view
|

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

Svein-Erik Løken
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:[hidden email]]
Sent: 27. april 2017 14:11
To: Svein-Erik Løken <[hidden email]>
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 [hidden email]<mailto:[hidden email]> Mailing List Archives, click here<
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>
Reply | Threaded
Open this post in threaded view
|

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

abangkis
In reply to this post by Thiago H. de Paula Figueiredo
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 <
[hidden email]> wrote:

> On Thu, Apr 27, 2017 at 6:43 AM, abangkis <[hidden email]> 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
Reply | Threaded
Open this post in threaded view
|

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

abangkis
In reply to this post by Svein-Erik Løken
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 <[hidden email]> 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:[hidden email]]
> Sent: 27. april 2017 14:11
> To: Svein-Erik Løken <[hidden email]>
> 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 [hidden email]<mailto:
> [hidden email]> 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