Event to trigger zone refresh

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

Event to trigger zone refresh

Christopher
Hi all,

I had mistakenly thought that any event handler method could render a
response through return type, whereas seemingly this is unique to events
triggered by Tapestry's actionlink, eventlink and form components.

I developed a filter pane component for limiting the number and (date)
range of hibernate results displayed.  The idea was for this pane to
trigger a "filter" event - componentResources.triggerEvent("filter", null,
null) - causing the container to refresh the zone that contains the
results.  But invoking onFilter() produces the error: "This type of event
does not support return values from event handler methods."

What is the usual method for triggering events so that a handler method
renders a response based on return type (zone body in my case)?

I guess my handler method could rather respond to the "success" event that
bubbles up from the filter pane's internal form, as with beaneditform, but
this isn't an ideal or elegant approach in all situations.

Regards,

Chris.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away." - Antoine de Saint-Exupéry.
Reply | Threaded
Open this post in threaded view
|

Re: Event to trigger zone refresh

Ilya Obshadko-2
That's actually quite easy:

define(["jquery", "t5/core/utils", "t5/core/ajax", "t5/core/events"],
function($, utils, ajax, events) {
    return function(spec) {
        var $zoneElement = $('#' + spec.zoneElementId)
        $zoneElement.trigger(events.zone.refresh, { url: spec.zoneRefreshUrl })
    };
});

And you can construct and pass the actual zoneRefreshUrl using
ComponentResources.createEventLink method when using
JavaScriptSupport.require.
Event handler method, in this case, is supposed do something like
ajaxResponseRenderer.addRender(zoneElement), or simply return injected
block.


On Fri, Dec 14, 2018 at 3:04 AM Christopher Dodunski <
[hidden email]> wrote:

> Hi all,
>
> I had mistakenly thought that any event handler method could render a
> response through return type, whereas seemingly this is unique to events
> triggered by Tapestry's actionlink, eventlink and form components.
>
> I developed a filter pane component for limiting the number and (date)
> range of hibernate results displayed.  The idea was for this pane to
> trigger a "filter" event - componentResources.triggerEvent("filter", null,
> null) - causing the container to refresh the zone that contains the
> results.  But invoking onFilter() produces the error: "This type of event
> does not support return values from event handler methods."
>
> What is the usual method for triggering events so that a handler method
> renders a response based on return type (zone body in my case)?
>
> I guess my handler method could rather respond to the "success" event that
> bubbles up from the filter pane's internal form, as with beaneditform, but
> this isn't an ideal or elegant approach in all situations.
>
> Regards,
>
> Chris.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

--
Ilya Obshadko
Reply | Threaded
Open this post in threaded view
|

Re: Event to trigger zone refresh

Thiago H de Paula Figueiredo
In reply to this post by Christopher
On Thu, Dec 13, 2018 at 11:04 PM Christopher Dodunski <
[hidden email]> wrote:

> Hi all,
>

Hello!


> I had mistakenly thought that any event handler method could render a
> response through return type, whereas seemingly this is unique to events
> triggered by Tapestry's actionlink, eventlink and form components.
>

I'm afraid you're mistaken about being mistaken. :) There's absolutely no
difference between event handler methods from Tapestry components or your
own components. You just have limits on which return types are accepted for
AJAX requests (as determined by Request.isXHR()) and non-AJAX requests.


> I developed a filter pane component for limiting the number and (date)
> range of hibernate results displayed.  The idea was for this pane to
> trigger a "filter" event - componentResources.triggerEvent("filter", null,
> null) - causing the container to refresh the zone that contains the
> results.  But invoking onFilter() produces the error: "This type of event
> does not support return values from event handler methods."
>

This matches what I said before. What did you return on onFilter()?


> What is the usual method for triggering events so that a handler method
> renders a response based on return type (zone body in my case)?
>

In the end, it boils down to the registered ComponentEventResultProcessor
instances. You can contribute your own ones to
the ComponentEventResultProcessor service.

--
Thiago
Reply | Threaded
Open this post in threaded view
|

Re: Event to trigger zone refresh

Thiago H de Paula Figueiredo
In reply to this post by Ilya Obshadko-2
You can have it easier in Tapestry 5.4.2+, not having to pass the event URL
from Java to JavaScript. From the example at
tapestry.apache.org/ajax-and-zones.html#AjaxandZones-Invokingserver-sideeventhandlermethodsfromJavaScript,
supposing you want to trigger a server-side event when clicking the <p
id="result"> element:

@PublishEvent
[ReturnType] yourEventHandlerMethod() {


In the template of the component or page class above.


<p id="result">(no result yet)</p>


JavaScript:


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);
                        }
                });
        });
});


On Fri, Dec 14, 2018 at 2:08 PM Ilya Obshadko <[hidden email]>
wrote:

> That's actually quite easy:
>
> define(["jquery", "t5/core/utils", "t5/core/ajax", "t5/core/events"],
> function($, utils, ajax, events) {
>     return function(spec) {
>         var $zoneElement = $('#' + spec.zoneElementId)
>         $zoneElement.trigger(events.zone.refresh, { url:
> spec.zoneRefreshUrl })
>     };
> });
>
> And you can construct and pass the actual zoneRefreshUrl using
> ComponentResources.createEventLink method when using
> JavaScriptSupport.require.
> Event handler method, in this case, is supposed do something like
> ajaxResponseRenderer.addRender(zoneElement), or simply return injected
> block.
>
>
> On Fri, Dec 14, 2018 at 3:04 AM Christopher Dodunski <
> [hidden email]> wrote:
>
> > Hi all,
> >
> > I had mistakenly thought that any event handler method could render a
> > response through return type, whereas seemingly this is unique to events
> > triggered by Tapestry's actionlink, eventlink and form components.
> >
> > I developed a filter pane component for limiting the number and (date)
> > range of hibernate results displayed.  The idea was for this pane to
> > trigger a "filter" event - componentResources.triggerEvent("filter",
> null,
> > null) - causing the container to refresh the zone that contains the
> > results.  But invoking onFilter() produces the error: "This type of event
> > does not support return values from event handler methods."
> >
> > What is the usual method for triggering events so that a handler method
> > renders a response based on return type (zone body in my case)?
> >
> > I guess my handler method could rather respond to the "success" event
> that
> > bubbles up from the filter pane's internal form, as with beaneditform,
> but
> > this isn't an ideal or elegant approach in all situations.
> >
> > Regards,
> >
> > Chris.
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
> >
>
> --
> Ilya Obshadko
>


--
Thiago
Reply | Threaded
Open this post in threaded view
|

Re: Event to trigger zone refresh

Christopher
In reply to this post by Christopher
Hi all,

Thanks for the pointers.  In the end I switched to AjaxResponseRenderer
rather than returning the zone's body, and all seems to work well.  I'm
not sure why I didn't do it this way to begin with.  You can see the old
line of code now commented out.

    public void onFilter(){
        expand();  //Effectively re-query database

        //return request.isXHR() ? operationChildZone.getBody() : this;
        ajaxResponseRenderer.addRender(operationChildZone);
    }

Thanks & regards,

Chris.


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away." - Antoine de Saint-Exupéry.