You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Christian Riedel <cr...@googlemail.com> on 2012/02/15 18:43:32 UTC

Howto render a block and put it into a JSON reply?

Hi there,

I'm trying to improve the tapestry5-jquery DataTable component, which is able to respond paged results in JSON. Unfortunately the component is a bit limited in terms of what can be returned. I want to add support for the Grid-style p:propertyCell block-parameter-notation. 
I'm looking for the most elegant way to do it. Currently I'm trying it with faked zone updates (ajaxResponseRenderer.addRender) and a filter (ajaxResponseRenderer.addFilter) that should modify the JSON reply object. It feels very clumsy and I thought if someone on the list could point me to a more elegant solution.

More Abstract:
We've got
- an Ajax callback: void onData() { ... }
- PropertyOverrides, having block parameters
- a working data source that is able to fetch data by the current page

We need
- loop over all rows of the current page and
- render each cell's content or its override into a row-json-array and
- put each row-json-array into a data json-array

Is there another way than using ajaxResponseRenderer.addRender / addFilter?

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


Re: Howto render a block and put it into a JSON reply?

Posted by Rural Hunter <ru...@gmail.com>.
Thanks. I tried this and it works. One limitation is that, all the 
content in the block must be enclosed in a single html element. If the 
block is like this:
<t:block id='renderme'>
<t:loop ...>
<tr>...</tr>
</t:loop
</t:block>

The result only renders one tr element. I have to enclose the loop in a 
div to get all the rows rendered. Don't know why though. Here is my 
code(a little different):

public String renderMarkup(Block block)
{
RenderCommand renderCommand=typeCoercer.coerce(block, RenderCommand.class);
MarkupWriter markupWriter = new MarkupWriterImpl();
environment.push(Heartbeat.class, new HeartbeatImpl());
RenderQueueImpl renderQueue = new RenderQueueImpl(logger);
renderQueue.push(renderCommand);
renderQueue.run(markupWriter);
environment.pop(Heartbeat.class);
System.out.println("markup="+markupWriter.toString());
return 
markupWriter.toString().replaceAll("^\\n+","").replaceAll("\\n+$", "");
}

于 2012/2/16 22:00, dh ning 写道:
> Hi,
>
> To render block as html markup, I did like this:
>
> public String renderMarkup(RenderCommand renderCommand) {
>          MarkupWriter markupWriter = new MarkupWriterImpl();
>
>          // validation track
>          ValidationDecorator decorator = new
> DefaultValidationDecorator(environment,
> assetSource.getExpandedAsset("${tapestry.spacer-image}"), markupWriter);
>          environment.push(ValidationDecorator.class, decorator);
>          RenderQueueImpl renderQueue = new RenderQueueImpl(logger);
>          renderQueue.push(renderCommand);
>          renderQueue.run(markupWriter);
>
>          environment.pop(ValidationDecorator.class);
>          return markupWriter.toString().replaceAll("^\\n+",
> "").replaceAll("\\n+$", "");
>      }
>
> and call renderMarkup((RenderCommand )block).
>
> Not sure whether it is better than yours, hope it helps.
>
> 2012/2/16 Christian Riedel <cr...@googlemail.com>
>
>> Hi there,
>>
>> I'm trying to improve the tapestry5-jquery DataTable component, which is
>> able to respond paged results in JSON. Unfortunately the component is a bit
>> limited in terms of what can be returned. I want to add support for the
>> Grid-style p:propertyCell block-parameter-notation.
>> I'm looking for the most elegant way to do it. Currently I'm trying it
>> with faked zone updates (ajaxResponseRenderer.addRender) and a filter
>> (ajaxResponseRenderer.addFilter) that should modify the JSON reply object.
>> It feels very clumsy and I thought if someone on the list could point me to
>> a more elegant solution.
>>
>> More Abstract:
>> We've got
>> - an Ajax callback: void onData() { ... }
>> - PropertyOverrides, having block parameters
>> - a working data source that is able to fetch data by the current page
>>
>> We need
>> - loop over all rows of the current page and
>> - render each cell's content or its override into a row-json-array and
>> - put each row-json-array into a data json-array
>>
>> Is there another way than using ajaxResponseRenderer.addRender / addFilter?
>>
>> Cheers
>> Christian
>> ---------------------------------------------------------------------
>> 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: Howto render a block and put it into a JSON reply?

Posted by dh ning <ni...@gmail.com>.
Hi,

To render block as html markup, I did like this:

public String renderMarkup(RenderCommand renderCommand) {
        MarkupWriter markupWriter = new MarkupWriterImpl();

        // validation track
        ValidationDecorator decorator = new
DefaultValidationDecorator(environment,
assetSource.getExpandedAsset("${tapestry.spacer-image}"), markupWriter);
        environment.push(ValidationDecorator.class, decorator);
        RenderQueueImpl renderQueue = new RenderQueueImpl(logger);
        renderQueue.push(renderCommand);
        renderQueue.run(markupWriter);

        environment.pop(ValidationDecorator.class);
        return markupWriter.toString().replaceAll("^\\n+",
"").replaceAll("\\n+$", "");
    }

and call renderMarkup((RenderCommand )block).

Not sure whether it is better than yours, hope it helps.

2012/2/16 Christian Riedel <cr...@googlemail.com>

> Hi there,
>
> I'm trying to improve the tapestry5-jquery DataTable component, which is
> able to respond paged results in JSON. Unfortunately the component is a bit
> limited in terms of what can be returned. I want to add support for the
> Grid-style p:propertyCell block-parameter-notation.
> I'm looking for the most elegant way to do it. Currently I'm trying it
> with faked zone updates (ajaxResponseRenderer.addRender) and a filter
> (ajaxResponseRenderer.addFilter) that should modify the JSON reply object.
> It feels very clumsy and I thought if someone on the list could point me to
> a more elegant solution.
>
> More Abstract:
> We've got
> - an Ajax callback: void onData() { ... }
> - PropertyOverrides, having block parameters
> - a working data source that is able to fetch data by the current page
>
> We need
> - loop over all rows of the current page and
> - render each cell's content or its override into a row-json-array and
> - put each row-json-array into a data json-array
>
> Is there another way than using ajaxResponseRenderer.addRender / addFilter?
>
> Cheers
> Christian
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: Howto render a block and put it into a JSON reply?

Posted by Rural Hunter <ru...@gmail.com>.
hmm...This is an event handler for ajax action. I access it via 
ajax('/somepage:event') at client side. I don't see any problem for 
Tapestry to handle the json return value. And it works if I skip the 
getMarkup for the block. The client receives the json string without 
problem.

于 2012/11/10 1:09, Lance Java 写道:
> Tapestry does NOT accept JSONObject as a return value from a component event.
> If you want to make a JSONObject available in your javascript, you should
> use AjaxResponseRenderer.
>
> http://tawus.wordpress.com/2011/10/01/tapestry-5-3-new-features-part-2/
>
>
>
> --
> View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5717885.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: Howto render a block and put it into a JSON reply?

Posted by Howard Lewis Ship <hl...@gmail.com>.
In an Ajax request, returning a JSONObject is completely appropriate return
value from a component event that expects a page navigation result.  This
will mix-and-match well with AjaxResponseRenderer (under 5.3 and 5.4); that
is, you can return a JSONObject and Tapestry will add to it the keys for
zone updates and page initializations related to rendering Blocks and Zones.

Under 5.4, it's a bit neater, with the partial page render response values
buried down a level under a "_tapestry" key.


On Fri, Nov 9, 2012 at 9:09 AM, Lance Java <la...@googlemail.com>wrote:

> Tapestry does NOT accept JSONObject as a return value from a component
> event.
> If you want to make a JSONObject available in your javascript, you should
> use AjaxResponseRenderer.
>
> http://tawus.wordpress.com/2011/10/01/tapestry-5-3-new-features-part-2/
>
>
>
> --
> View this message in context:
> http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5717885.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
>
>


-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

Re: Howto render a block and put it into a JSON reply?

Posted by Lance Java <la...@googlemail.com>.
Tapestry does NOT accept JSONObject as a return value from a component event.
If you want to make a JSONObject available in your javascript, you should
use AjaxResponseRenderer.

http://tawus.wordpress.com/2011/10/01/tapestry-5-3-new-features-part-2/



--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5717885.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: Howto render a block and put it into a JSON reply?

Posted by Rural Hunter <ru...@gmail.com>.
Hi Lance,

I also tried this. But there is some problem. I had to handle the json 
in this getMarkup method. Otherwise the json returned in my event 
handler is not rendered.

Object onEventXXX()
{
JSONObject result=new JSONObject();
....
result.put("html",getMarkup(myblock) );
return result;
}

I can see the markup is generated correctly but the result received at 
client is just empty. If I put needed content in the reply json object 
in renderMarkup of the PartialMarkupRendererFilter, the client can 
receive the good response. My guess is that the response is terminated 
in getMarkup() so the returned json in the event handler is not rendered.

于 2012/6/11 17:38, Lance Java 写道:
> Try this out (untested). If it works, I'll add it to the wiki page
>
> public class AjaxRenderCommandMarkupRenderer {
>     private final PageRenderQueue pageRenderQueue;
>     private final AjaxFormUpdateController ajaxFormUpdateController;
>     private final AjaxPartialResponseRenderer partialRenderer;
>
>     // constructor
>
>     public String getMarkup(RenderCommand renderCommand) {
>        final StringBuilder builder = new StringBuiler();
>        pageRenderQueue.addPartialMarkupRendererFilter(new
> PartialMarkupRendererFilter() {
>           public void renderMarkup(MarkupWriter writer, JSONObject reply,
> PartialMarkupRenderer renderer)
>           {
>               Element root = writer.element("ajax-partial");
>               ajaxFormUpdateController.setupBeforePartialZoneRender(writer);
>               renderer.renderMarkup(writer, reply);
>               ajaxFormUpdateController.cleanupAfterPartialZoneRender();
>               writer.end();
>               builder.append(root.getChildMarkup().trim());
>               root.remove();
>           }
>        });
>        pageRenderQueue.addPartialRenderer(value);
>        partialRenderer.renderPartialPageMarkup();
>        return builder.toString();
>     }
> }
>
> --
> View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713760.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: Howto render a block and put it into a JSON reply?

Posted by Lance Java <la...@googlemail.com>.
Try this out (untested). If it works, I'll add it to the wiki page

public class AjaxRenderCommandMarkupRenderer {
   private final PageRenderQueue pageRenderQueue;
   private final AjaxFormUpdateController ajaxFormUpdateController;
   private final AjaxPartialResponseRenderer partialRenderer;

   // constructor

   public String getMarkup(RenderCommand renderCommand) {
      final StringBuilder builder = new StringBuiler();
      pageRenderQueue.addPartialMarkupRendererFilter(new
PartialMarkupRendererFilter() {
         public void renderMarkup(MarkupWriter writer, JSONObject reply,
PartialMarkupRenderer renderer)
         {
             Element root = writer.element("ajax-partial");
             ajaxFormUpdateController.setupBeforePartialZoneRender(writer);
             renderer.renderMarkup(writer, reply);
             ajaxFormUpdateController.cleanupAfterPartialZoneRender();
             writer.end();
             builder.append(root.getChildMarkup().trim());
             root.remove();
         }
      });
      pageRenderQueue.addPartialRenderer(value);
      partialRenderer.renderPartialPageMarkup();
      return builder.toString();
   }
}

--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713760.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: Howto render a block and put it into a JSON reply?

Posted by Nourredine <no...@atos.net>.
Just seen your last post. Will take a look.

--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713759.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: Howto render a block and put it into a JSON reply?

Posted by Lance Java <la...@googlemail.com>.
Sorry, I have just given you a solution that will only work for non-ajax
requests.

For ajax requests, take a look at how the
RenderCommandComponentEventResultProcessor generates markup using a similar
method.

http://tapestry.apache.org/5.3/apidocs/src-html/org/apache/tapestry5/internal/services/RenderCommandComponentEventResultProcessor.html

--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713757.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: Howto render a block and put it into a JSON reply?

Posted by Nourredine <no...@atos.net>.
Thank you Lance for your input. Very interesting. Unfortunately, I need to
render my block "outside" of a component rendering (can not use render
methods). I'm inside an ajax callback, constructing a JSON object "on the
fly". 
The implementation must be generic, as I don't know what exactly the blocks
contain (they are like Grid propertyOverrides blocks), and must work for
components that use Environment stuff (JavaScriptSupport,
ClientBehaviourSupport, ...)



--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713758.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: Howto render a block and put it into a JSON reply?

Posted by Lance Java <la...@googlemail.com>.
If you would like to avoid using internal API's (eg MarkupWriterImpl and
RenderQueueImpl) you can follow the method here:
http://wiki.apache.org/tapestry/Tapestry5HowToGetAnHTMLStringFromARenderCommandParameter

--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713755.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: Howto render a block and put it into a JSON reply?

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Mon, 11 Jun 2012 05:09:11 -0300, Nourredine  
<no...@atos.net> wrote:

> Just using a RenderCommand with the RenderQueue does not solve the issue
> when blocks contain advanced components.

There are no advanced components in Tapestry. Tapestry treats all  
components the same.

-- 
Thiago H. de Paula Figueiredo

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


Re: Howto render a block and put it into a JSON reply?

Posted by Nourredine <no...@atos.net>.
Christian,

I ended up following the source code of
"MultiZoneUpdateEventResultProcessor#processResultValue" method and
"SingleZonePartialRendererFilter" class (which is nearly what Lance had
suggested).

It concerns the "DataTableModel"'s default implementation [1] that can
easily be replaced.

I had also to add a javascript callback [2] to call the
"Tapestry.loadScriptsInReply" function for displaying zones with their
scripts.

1 -
https://github.com/got5/tapestry5-jquery/blob/master/src/main/java/org/got5/tapestry5/jquery/internal/DefaultDataTableModel.java

2 -
https://github.com/got5/tapestry5-jquery/blob/master/src/main/resources/org/got5/tapestry5/jquery/assets/components/datatables/dataTables.js

Some aspects need to be improved, but at the moment, it does the job.

Thank you all guys for your help :)

Nourredine.



--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5715387.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: Howto render a block and put it into a JSON reply?

Posted by Christian Riedel <cr...@googlemail.com>.
Hi Nourredine,

well we gave up on jQuery's datatable and built our own searchable datatable solution. It's based on MongoDB, Tapestry's Grid, a GridDataSource similar to JpaGridDataSource and mongo-jackson-mapper[1].
It works fine in our backoffice but I think it doesn't scale well, if you plan to integrate it on a frequently used page (we're persisting a field in the session for convenience). 

I'll check out Lance's approach, maybe I can use it to improve the code at Tapestry5-jQuery :-)

Best,
Christian


[1] https://github.com/vznet/mongo-jackson-mapper



Am 11.06.2012 um 10:09 schrieb Nourredine:

> Hi Christian,
> 
> I'm facing  the exact same issue with the jquery datatable plugin.
> 
> Just using a RenderCommand with the RenderQueue does not solve the issue
> when blocks contain advanced components.
> 
> So, I'm interested in your implementation which I will adapt to the Tapestry
> 5.2 version
> 
> Can you share the code you've developped to render a block using a
> AjaxResponseRenderer or give me more details please ?
> 
> Regards,
> 
> Nourredine.
> 
> --
> View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713754.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: Howto render a block and put it into a JSON reply?

Posted by Nourredine <no...@atos.net>.
Hi Christian,

I'm facing  the exact same issue with the jquery datatable plugin.

Just using a RenderCommand with the RenderQueue does not solve the issue
when blocks contain advanced components.

So, I'm interested in your implementation which I will adapt to the Tapestry
5.2 version

Can you share the code you've developped to render a block using a
AjaxResponseRenderer or give me more details please ?

Regards,

Nourredine.

--
View this message in context: http://tapestry.1045711.n5.nabble.com/Howto-render-a-block-and-put-it-into-a-JSON-reply-tp5486823p5713754.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