You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Markus Joschko <ma...@gmail.com> on 2010/09/20 22:24:14 UTC

Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

I have a "dialog" on a page which has some eventlinks that are
triggering serverside actions via ajax requests.
When some conditions are met, the server will decide to close the
dialog and update a zone in the page.
That requires to send the javascript close command and a zone update
to the browser as response to the event method.

Now I have problems to figure out the best way to do this.
Although there is the MultiZoneUpdate object I can't use it as the
RenderCommand that encapsulates the javascript does not work nicely
with it (leaving the zone name blank gives an error on the
clientside).
 I found another approach on the mailinglist that works but it
involves the PageRenderQueue, which is an internal service.
Is there a better way to achieve what I want?

Regards,
 Markus

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

Posted by Markus Joschko <ma...@gmail.com>.
I think I found away which is still a bit clumsy but allows to return
javascript and a MultiZoneUpdate as the response of an ajax event
without involving internal API:

@Inject
private TypeCoercer coercer;
@Inject
private JavaScriptSupport jsSupport;
@InjectComponent
private Zone updateZone;

public MultiZoneUpdate onEventX() {
 RenderCommand jsCommand = new RenderCommand() {
    void render(MarkupWriter writer, RenderQueue queue) {
       jsSupport.addScript("console.log('Test'));
    }
 }
 RenderCommand blockCommand = coercer.coerce(updateZone, RenderCommand.class);
 return new MultiZoneUpdate("zoneId", new
CombinedRenderCommand(jsCommand, blockCommand));
}

As I have translated that code back from scala and haven't run it
through a java compiler there might be typos or syntax errors but
you'll get the idea.


On Tue, Sep 21, 2010 at 5:01 PM, Markus Joschko
<ma...@gmail.com> wrote:
> OK, that's the dummy zone approach. It works but it is not very nifty.
> Maybe the easiest solution is to have MultiZoneUpdate accept
> Rendercommands without a zone name.
> The RenderCommands can then simply add javascript to the response.
>
>
>
> On Tue, Sep 21, 2010 at 4:43 PM, 9902468 <vi...@greenstreet.fi> wrote:
>>
>> This is interesting question, as the MultiZoneUpdate ideally would have
>> exactly the same js methods that the JavaScriptSupport service has and just
>> work.
>>
>> I always have circumvented this using jsdummy zone, which has no other
>> purpose but to drive my js that needs to be run in addition to the other
>> stuff returning back to client. This has slight overhead, but I already have
>> zones in the page, so it isn't much (one empty div + the penalty in client
>> side to run the zone.)
>>
>> For an example this can be fed to MultiZoneUpdate:
>> private Object getAmountRenderable(final String amount, final String text,
>> final String nhId) {
>>                return new RenderCommand() {
>>                        @Override
>>                        public void render(MarkupWriter writer, RenderQueue queue) {
>>                                writer.write(amount);
>>                                UUID id = UUID.randomUUID();
>>                                String ok = "a" + id.toString().replace("-", "_");
>>                                javaScriptSupport.addScript("var marker=$('"+nhId+"'); var marker_pos =
>> marker.cumulativeOffset(); "+ok+".setStyle({right: '200px', top:
>> (marker_pos[1] - 30)+'px'});");
>>                                javaScriptSupport.addScript(ok+".show();");
>>                                javaScriptSupport.addScript(ok+".fade({ duration: 4.0 });");
>>                                javaScriptSupport.addScript("resetSliders();");
>>                                javaScriptSupport.addScript("resetPrices('priceDisplay',
>> 'priceDiscountDisplay', ',', "+getPriceDivider()+");");
>>                        }
>>                };
>>        }
>>
>> like this:
>> if(request.isXHR()) {
>>        return new MultiZoneUpdate("cartDisplay", getAmountRenderable("2", "Product
>> " + languageManager.getName(product, locale) + " was added to cart.",
>> "marker")).add("otherZone", other.getBody());
>> }
>>
>> Hope that helps someone,
>>
>>  - Ville
>> --
>> View this message in context: http://tapestry.1045711.n5.nabble.com/Worthy-FAQ-What-is-the-best-way-to-return-a-zone-update-and-a-javascript-as-response-to-an-XHR-requet-tp2847175p2848163.html
>> Sent from the Tapestry - User mailing list archive at Nabble.com.
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

Posted by Markus Joschko <ma...@gmail.com>.
OK, that's the dummy zone approach. It works but it is not very nifty.
Maybe the easiest solution is to have MultiZoneUpdate accept
Rendercommands without a zone name.
The RenderCommands can then simply add javascript to the response.



On Tue, Sep 21, 2010 at 4:43 PM, 9902468 <vi...@greenstreet.fi> wrote:
>
> This is interesting question, as the MultiZoneUpdate ideally would have
> exactly the same js methods that the JavaScriptSupport service has and just
> work.
>
> I always have circumvented this using jsdummy zone, which has no other
> purpose but to drive my js that needs to be run in addition to the other
> stuff returning back to client. This has slight overhead, but I already have
> zones in the page, so it isn't much (one empty div + the penalty in client
> side to run the zone.)
>
> For an example this can be fed to MultiZoneUpdate:
> private Object getAmountRenderable(final String amount, final String text,
> final String nhId) {
>                return new RenderCommand() {
>                        @Override
>                        public void render(MarkupWriter writer, RenderQueue queue) {
>                                writer.write(amount);
>                                UUID id = UUID.randomUUID();
>                                String ok = "a" + id.toString().replace("-", "_");
>                                javaScriptSupport.addScript("var marker=$('"+nhId+"'); var marker_pos =
> marker.cumulativeOffset(); "+ok+".setStyle({right: '200px', top:
> (marker_pos[1] - 30)+'px'});");
>                                javaScriptSupport.addScript(ok+".show();");
>                                javaScriptSupport.addScript(ok+".fade({ duration: 4.0 });");
>                                javaScriptSupport.addScript("resetSliders();");
>                                javaScriptSupport.addScript("resetPrices('priceDisplay',
> 'priceDiscountDisplay', ',', "+getPriceDivider()+");");
>                        }
>                };
>        }
>
> like this:
> if(request.isXHR()) {
>        return new MultiZoneUpdate("cartDisplay", getAmountRenderable("2", "Product
> " + languageManager.getName(product, locale) + " was added to cart.",
> "marker")).add("otherZone", other.getBody());
> }
>
> Hope that helps someone,
>
>  - Ville
> --
> View this message in context: http://tapestry.1045711.n5.nabble.com/Worthy-FAQ-What-is-the-best-way-to-return-a-zone-update-and-a-javascript-as-response-to-an-XHR-requet-tp2847175p2848163.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

Posted by 9902468 <vi...@greenstreet.fi>.
This is interesting question, as the MultiZoneUpdate ideally would have
exactly the same js methods that the JavaScriptSupport service has and just
work.

I always have circumvented this using jsdummy zone, which has no other
purpose but to drive my js that needs to be run in addition to the other
stuff returning back to client. This has slight overhead, but I already have
zones in the page, so it isn't much (one empty div + the penalty in client
side to run the zone.)

For an example this can be fed to MultiZoneUpdate:
private Object getAmountRenderable(final String amount, final String text,
final String nhId) {
		return new RenderCommand() {
			@Override
			public void render(MarkupWriter writer, RenderQueue queue) {
				writer.write(amount);
				UUID id = UUID.randomUUID();				
				String ok = "a" + id.toString().replace("-", "_");
				javaScriptSupport.addScript("var marker=$('"+nhId+"'); var marker_pos =
marker.cumulativeOffset(); "+ok+".setStyle({right: '200px', top:
(marker_pos[1] - 30)+'px'});");
				javaScriptSupport.addScript(ok+".show();");
				javaScriptSupport.addScript(ok+".fade({ duration: 4.0 });");
				javaScriptSupport.addScript("resetSliders();");
				javaScriptSupport.addScript("resetPrices('priceDisplay',
'priceDiscountDisplay', ',', "+getPriceDivider()+");");
			}
		};
	}

like this:
if(request.isXHR()) {
	return new MultiZoneUpdate("cartDisplay", getAmountRenderable("2", "Product
" + languageManager.getName(product, locale) + " was added to cart.",
"marker")).add("otherZone", other.getBody());
}

Hope that helps someone,

 - Ville
-- 
View this message in context: http://tapestry.1045711.n5.nabble.com/Worthy-FAQ-What-is-the-best-way-to-return-a-zone-update-and-a-javascript-as-response-to-an-XHR-requet-tp2847175p2848163.html
Sent from the Tapestry - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

Posted by Markus Joschko <ma...@gmail.com>.
Also only a workaround. The zone is not directly related to the
dialog. It makes no sense to wire a mixin to a component in that zone.
I could probably also return a dummy zone in the Multizoneupdate which
only contains a "dialog close component", but that also feels awkward.
But thanks for the input.

On Tue, Sep 21, 2010 at 12:42 PM, LLTYK <LL...@mailinator.com> wrote:
>
> Putting a mixin on a component in the zone executes the mixin javascript on
> zone update. So you'd stick in your dialog close logic in a mixin.
> --
> View this message in context: http://tapestry-users.832.n2.nabble.com/Worthy-FAQ-What-is-the-best-way-to-return-a-zone-update-and-a-javascript-as-response-to-an-XHR-requet-tp5552201p5554149.html
> Sent from the Tapestry Users mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

Posted by LLTYK <LL...@mailinator.com>.
Putting a mixin on a component in the zone executes the mixin javascript on
zone update. So you'd stick in your dialog close logic in a mixin.
-- 
View this message in context: http://tapestry-users.832.n2.nabble.com/Worthy-FAQ-What-is-the-best-way-to-return-a-zone-update-and-a-javascript-as-response-to-an-XHR-requet-tp5552201p5554149.html
Sent from the Tapestry Users mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

Posted by Markus Joschko <ma...@gmail.com>.
Yep, that's the "fallback" solution. But it requires two requests to
the server. First getting the javascript and then updating the zone.
I would prefer to return everything in one request. That is possible
using the internal services.

Thanks,
 Markus

On Mon, Sep 20, 2010 at 11:11 PM, Anna Vo <av...@widen.com> wrote:
> Markus-
>
> You can inject ComponentResources, pass the zoneId and eventlink to
> your javascript method with a JSONObject in your javascript
> initializer call , and then call the tapestry zone update via client
> side javascript.
>
> Example Java Code:
>
> @Inject
> private ComponentResources resources;
>
> @Environmental
> private JavaScriptSupport javascriptSupport;
>
> @InjectComponent
> private Zone yourZone;
>
> void afterRender()
> {
> Link url = resources.createEventLink("yourMethodName");
> JSONObject spec = new JSONObject();
> spec.put("zoneId", yourZone.getClientId());
> spec.put("url", url.toString());
> javascriptSupport.addInitializerCall(InitializationPriority.NORMAL,
> "yourJsFunction", spec);
> }
>
> Object onYourMethodName()
> {
> return yourZone.getBody();
> }
>
> Example Javascript Code:
>
> Tapestry.Initializer.yourJsFunction = function(spec)
> {
> ....
> var zone = Tapestry.findZoneManagerForZone(spec.zoneId);
> zone.updateFromURL(spec.url);
> ....
> };
>
>
> You can also observe the Tapestry.ZONE_UPDATED_EVENT in your
> javascript by doing this if you wanted to perform a zone update first
> and then do some javascript:
>
> $(spec.zoneId).observe(Tapestry.ZONE_UPDATED_EVENT, someJsFunction)
>
>
>
> On Mon, Sep 20, 2010 at 3:24 PM, Markus Joschko
> <ma...@gmail.com> wrote:
>> I have a "dialog" on a page which has some eventlinks that are
>> triggering serverside actions via ajax requests.
>> When some conditions are met, the server will decide to close the
>> dialog and update a zone in the page.
>> That requires to send the javascript close command and a zone update
>> to the browser as response to the event method.
>>
>> Now I have problems to figure out the best way to do this.
>> Although there is the MultiZoneUpdate object I can't use it as the
>> RenderCommand that encapsulates the javascript does not work nicely
>> with it (leaving the zone name blank gives an error on the
>> clientside).
>>  I found another approach on the mailinglist that works but it
>> involves the PageRenderQueue, which is an internal service.
>> Is there a better way to achieve what I want?
>>
>> Regards,
>>  Markus
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Worthy FAQ?: What is the best way to return a zone update and a javascript as response to an XHR request

Posted by Anna Vo <av...@widen.com>.
Markus-

You can inject ComponentResources, pass the zoneId and eventlink to
your javascript method with a JSONObject in your javascript
initializer call , and then call the tapestry zone update via client
side javascript.

Example Java Code:

@Inject
private ComponentResources resources;

@Environmental
private JavaScriptSupport javascriptSupport;

@InjectComponent
private Zone yourZone;

void afterRender()
{
Link url = resources.createEventLink("yourMethodName");
JSONObject spec = new JSONObject();
spec.put("zoneId", yourZone.getClientId());
spec.put("url", url.toString());
javascriptSupport.addInitializerCall(InitializationPriority.NORMAL,
"yourJsFunction", spec);
}

Object onYourMethodName()
{
return yourZone.getBody();
}

Example Javascript Code:

Tapestry.Initializer.yourJsFunction = function(spec)
{
....
var zone = Tapestry.findZoneManagerForZone(spec.zoneId);
zone.updateFromURL(spec.url);
....
};


You can also observe the Tapestry.ZONE_UPDATED_EVENT in your
javascript by doing this if you wanted to perform a zone update first
and then do some javascript:

$(spec.zoneId).observe(Tapestry.ZONE_UPDATED_EVENT, someJsFunction)



On Mon, Sep 20, 2010 at 3:24 PM, Markus Joschko
<ma...@gmail.com> wrote:
> I have a "dialog" on a page which has some eventlinks that are
> triggering serverside actions via ajax requests.
> When some conditions are met, the server will decide to close the
> dialog and update a zone in the page.
> That requires to send the javascript close command and a zone update
> to the browser as response to the event method.
>
> Now I have problems to figure out the best way to do this.
> Although there is the MultiZoneUpdate object I can't use it as the
> RenderCommand that encapsulates the javascript does not work nicely
> with it (leaving the zone name blank gives an error on the
> clientside).
>  I found another approach on the mailinglist that works but it
> involves the PageRenderQueue, which is an internal service.
> Is there a better way to achieve what I want?
>
> Regards,
>  Markus
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org